Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/autoscaling confirmation #185

Open
wants to merge 5 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ type OperationRequest struct {
type OperationValidationResponse struct {
Response OperationValidationResponseBody `yaml:"resp,omitempty" json:"resp,omitempty"`
}

type ScalingConsentResponse struct {
Response []string `yaml:"resp,omitempty" json:"resp,omitempty"`
}
12 changes: 12 additions & 0 deletions internal/backend/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,15 @@ func (s *Service) OperateService(serviceName string, data service.OperationReque
response := client.streamWithRetry(path.Join(serviceEntity, serviceName)+"/operate/", "PUT", data)
response.Process(true)
}

func (s *Service) ScalingServiceConsent(serviceName string, data interface{}) (service.ScalingConsentResponse, error) {
client := newApiClient()

response := client.actionWithRetry(path.Join(serviceEntity, serviceName)+"/reactivescaledscalercomponents", "POST", data)
response.Process(true)

var scalingConsentResponse service.ScalingConsentResponse
err := json.Unmarshal(response.Body, &scalingConsentResponse)

return scalingConsentResponse, err
}
64 changes: 58 additions & 6 deletions internal/command/commands/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func (c *Component) Run(args []string) int {
envName := flagSet.String("env", "", "name of the environment in which the service is deployed")
operation := flagSet.String("operation", "", "name of the operation to performed on the component")
options := flagSet.String("options", "", "options of the operation in JSON format")
filePath := flagSet.String("file", "", "file to provide options for component operations")

err := flagSet.Parse(args)
if err != nil {
Expand All @@ -33,15 +34,38 @@ func (c *Component) Run(args []string) int {
if *envName == "" {
*envName = utils.FetchKey(ENV_NAME_KEY)
}
emptyParameters := emptyParameters(map[string]string{"--name": *name, "--service": *serviceName, "--env": *envName, "--operation": *operation, "--options": *options})
emptyParameters := emptyParameters(map[string]string{"--name": *name, "--service": *serviceName, "--env": *envName, "--operation": *operation})
if len(emptyParameters) == 0 {
var optionsJson interface{}
err = json.Unmarshal([]byte(*options), &optionsJson)
if err != nil {
c.Logger.Error("Unable to parse options JSON " + err.Error())
isOptionsPresent := len(*options) > 0
isFilePresent := len(*filePath) > 0

if isOptionsPresent && isFilePresent {
c.Logger.Error("You can provide either --options or --file but not both")
return 1
}

if !isOptionsPresent && !isFilePresent {
c.Logger.Error("You should provide either --options or --file")
return 1
}

var optionsData map[string]interface{}

if isFilePresent {
parsedConfig, err := parseFile(*filePath)
if err != nil {
c.Logger.Error("Error while parsing file " + *filePath + " : " + err.Error())
return 1
}
optionsData = parsedConfig.(map[string]interface{})
} else if isOptionsPresent {
err = json.Unmarshal([]byte(*options), &optionsData)
if err != nil {
c.Logger.Error("Unable to parse JSON data " + err.Error())
return 1
}
}

envTypeResp, err := envTypeClient.GetEnvType(*envName)
if err != nil {
c.Logger.Error(err.Error())
Expand All @@ -62,14 +86,41 @@ func (c *Component) Run(args []string) int {
}
}

dataForScalingConsent := map[string]interface{}{
"env_name": *envName,
"component_name": *name,
"action": *operation,
"config": optionsData,
}
componentListResponse, err := serviceClient.ScalingServiceConsent(*serviceName, dataForScalingConsent)
if err != nil {
c.Logger.Error(err.Error())
return 1
}
for _, component := range componentListResponse.Response {
consentMessage := fmt.Sprintf("\nYou have enabled reactive scaling for %s, this means %s will no longer be scaled using Scaler post this operation. Do you wish to continue? [Y/n]:", component, component)
allowedInputs := map[string]struct{}{"Y": {}, "n": {}}
val, err := c.Input.AskWithConstraints(consentMessage, allowedInputs)

if err != nil {
c.Logger.Error(err.Error())
return 1
}

if val != "Y" {
c.Logger.Info("\nAborting...")
return 1
}
}

data := component.OperateComponentRequest{
Data: component.Data{
EnvName: *envName,
ServiceName: *serviceName,
Operations: []component.Operation{
{
Name: *operation,
Values: optionsJson,
Values: optionsData,
},
},
},
Expand All @@ -96,6 +147,7 @@ func (c *Component) Help() string {
{Flag: "--env", Description: "name of the environment in which the service is deployed"},
{Flag: "--operation", Description: "name of the operation to performed on the component"},
{Flag: "--options", Description: "options of the operation in JSON format"},
{Flag: "--file", Description: "path of the file which contains the options for the operation in JSON format"},
})
}
return defaultHelper()
Expand Down
61 changes: 58 additions & 3 deletions internal/command/commands/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ func (s *Service) Run(args []string) int {
}

if !isOperationPresnt {
s.Logger.Error("--opertion cannot be blank")
s.Logger.Error("--operation cannot be blank")
return 1
}

Expand Down Expand Up @@ -399,6 +399,16 @@ func (s *Service) Run(args []string) int {
return 1
}

dataForScalingConsent := map[string]interface{}{
"env_name": *envName,
"action": *operation,
"config": optionsData,
}
scalingConsent := s.askForScalingConsent(serviceName, envName, dataForScalingConsent)
if scalingConsent == 1 {
return 1
}

data := service.OperationRequest{
EnvName: *envName,
Operations: []service.Operation{
Expand Down Expand Up @@ -471,6 +481,30 @@ func (s *Service) askForConsent(envName *string) int {
return 0
}

func (s *Service) askForScalingConsent(serviceName *string, envName *string, data map[string]interface{}) int {
componentListResponse, err := serviceClient.ScalingServiceConsent(*serviceName, data)
if err != nil {
s.Logger.Error(err.Error())
return 1
}
for _, component := range componentListResponse.Response {
consentMessage := fmt.Sprintf("\nYou have enabled reactive scaling for %s, this means %s will no longer be scaled using Scaler post this operation. Do you wish to continue? [Y/n]:", component, component)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message is used twice, move this to constants

allowedInputs := map[string]struct{}{"Y": {}, "n": {}}
val, err := s.Input.AskWithConstraints(consentMessage, allowedInputs)

if err != nil {
s.Logger.Error(err.Error())
return 1
}

if val != "Y" {
s.Logger.Info("\nAborting...")
return 1
}
}
return 0
}

func (s *Service) deployUnreleasedService(envName *string, serviceDefinition map[string]interface{}, provisioningConfigFile *string, configStoreNamespace *string) int {

if serviceDefinition["name"] == nil || len(serviceDefinition["name"].(string)) == 0 {
Expand All @@ -485,7 +519,19 @@ func (s *Service) deployUnreleasedService(envName *string, serviceDefinition map
if done {
return i
}

config := map[string]interface{}{
"service_definition": serviceDefinition,
"provisioning_config": parsedProvisioningConfig,
}
dataForScalingConsent := map[string]interface{}{
"env_name": *envName,
"action": "unreleased_service_deploy",
"config": config,
}
scalingConsent := s.askForScalingConsent(&serviceName, envName, dataForScalingConsent)
if scalingConsent == 1 {
return 1
}
s.Logger.Debug(fmt.Sprintf("%s: %s : %s: %s:", serviceName, serviceVersion, *envName, *configStoreNamespace))
s.Logger.Info("Initiating service deployment: " + serviceName + "@" + serviceVersion + " in " + *envName)
serviceClient.DeployUnreleasedServiceStream(serviceDefinition, parsedProvisioningConfig, *envName, *configStoreNamespace)
Expand All @@ -500,7 +546,16 @@ func (s *Service) deployReleasedService(envName *string, serviceName *string, se
if done {
return i
}

dataForScalingConsent := map[string]interface{}{
"env_name": *envName,
"service_version": *serviceVersion,
"action": "released_service_deploy",
"config": parsedProvisioningConfig,
}
scalingConsent := s.askForScalingConsent(serviceName, envName, dataForScalingConsent)
if scalingConsent == 1 {
return 1
}
s.Logger.Debug(fmt.Sprintf("%s: %s : %s: %s:", *serviceName, *serviceVersion, *envName, *configStoreNamespace))
s.Logger.Info("Initiating service deployment: " + *serviceName + "@" + *serviceVersion + " in " + *envName)
serviceClient.DeployReleasedServiceStream(*serviceName, *serviceVersion, *envName, *configStoreNamespace, parsedProvisioningConfig)
Expand Down