Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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)+"/scalingconsent", "GET", 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.askForScalingConset(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) askForScalingConset(serviceName *string, envName *string, data map[string]interface{}) int {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

spelling mistake

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
Copy Markdown
Contributor

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.askForScalingConset(&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.askForScalingConset(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