Skip to content

Commit

Permalink
Merge pull request #224 from dream11/release-20240401
Browse files Browse the repository at this point in the history
Release 20240401
  • Loading branch information
yash-saxena-d11 authored Apr 1, 2024
2 parents f20528a + 4e3188d commit 4d89b5e
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 39 deletions.
36 changes: 36 additions & 0 deletions api/environment/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,39 @@ type Status struct {
type DetailResponse struct {
Response Env `yaml:"resp,omitempty" json:"resp,omitempty"`
}

type Operation struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Data interface{} `yaml:"data,omitempty" json:"data,omitempty"`
}

type OperationRequest struct {
Operations []Operation `yaml:"operations,omitempty" json:"operations,omitempty"`
}

type OperationConsent struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
IsFeedbackRequired bool `yaml:"is_feedback_required,omitempty" json:"is_feedback_required,omitempty"`
Message string `yaml:"message,omitempty" json:"message,omitempty"`
}

type OperationValidationResponseBody struct {
Operations []OperationConsent `yaml:"operations,omitempty" json:"operations,omitempty"`
}

type OperationValidationResponse struct {
Response OperationValidationResponseBody `yaml:"resp,omitempty" json:"resp,omitempty"`
}

type OperationOutput struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Message string `yaml:"message,omitempty" json:"message,omitempty"`
}

type OperationResponseBody struct {
Operations []OperationOutput `yaml:"operations,omitempty" json:"operations,omitempty"`
}

type OperationResponse struct {
Response OperationResponseBody `yaml:"resp,omitempty" json:"resp,omitempty"`
}
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ type application struct {
// App (Application) interface
var App application = application{
Name: "odin",
Version: "1.3.4",
Version: "1.4.0",
}
24 changes: 24 additions & 0 deletions internal/backend/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,27 @@ func (e *Env) EnvTypes() (envResp.EnvTypesResponse, error) {

return envResponse, err
}

func (e *Env) ValidateOperation(envName string, data envResp.OperationRequest) (envResp.OperationValidationResponse, error) {
client := newApiClient()

response := client.actionWithRetry(path.Join(envEntity, envName)+"/operate/validate/", "GET", data)
response.Process(true)

var validateOperationResponse envResp.OperationValidationResponse
err := json.Unmarshal(response.Body, &validateOperationResponse)

return validateOperationResponse, err
}

func (e *Env) OperateEnv(envName string, data envResp.OperationRequest) (envResp.OperationResponse, error) {
client := newApiClient()

response := client.actionWithRetry(path.Join(envEntity, envName)+"/operate/", "PUT", data)
response.Process(true)

var operationResponse envResp.OperationResponse
err := json.Unmarshal(response.Body, &operationResponse)

return operationResponse, err
}
9 changes: 9 additions & 0 deletions internal/backend/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ func (o *Operation) ListServiceOperations() ([]operationapi.Operation, error) {
err := json.Unmarshal(response.Body, &listResponse)
return listResponse.Response, err
}

func (o *Operation) ListEnvOperations() ([]operationapi.Operation, error) {
client := newApiClient()
response := client.actionWithRetry(path.Join("envs", "operations", "all"), "GET", nil)
response.Process(true) // process response and exit if error
var listResponse operationapi.ListOperation
err := json.Unmarshal(response.Body, &listResponse)
return listResponse.Response, err
}
3 changes: 3 additions & 0 deletions internal/command/command_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ func CommandsCatalog() map[string]cli.CommandFactory {
"set env": func() (cli.Command, error) {
return &commands.Env{Set: true}, nil
},
"operate env": func() (cli.Command, error) {
return &commands.Env{Operate: true}, nil
},
"list env-type": func() (cli.Command, error) {
return &commands.EnvType{List: true}, nil
},
Expand Down
106 changes: 105 additions & 1 deletion internal/command/commands/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ func (e *Env) Run(args []string) int {
component := flagSet.String("component", "", "component name to filter out describe environment")
providerAccount := flagSet.String("account", "", "account name to provision the environment in")
id := flagSet.Int("id", 0, "unique id of a changelog of an env")
filePath := flagSet.String("file", "", "file to update env")
filePath := flagSet.String("file", "", "file to update env or provide options for environment operations")
data := flagSet.String("data", "", "data for updating the env")
displayAll := flagSet.Bool("all", false, "whether to display all environments")
operation := flagSet.String("operation", "", "name of the operation to performed on the environment")
options := flagSet.String("options", "", "options for environment operations")

err := flagSet.Parse(args)
if err != nil {
Expand Down Expand Up @@ -380,6 +382,93 @@ func (e *Env) Run(args []string) int {
return 0
}

if e.Operate {
if *name == "" {
*name = utils.FetchKey(ENV_NAME_KEY)
}

isNamePresent := len(*name) > 0
isOptionsPresent := len(*options) > 0
isFilePresent := len(*filePath) > 0
isOperationPresnt := len(*operation) > 0

if !isNamePresent {
e.Logger.Error("--name cannot be blank")
return 1
}
if !isOperationPresnt {
e.Logger.Error("--operation cannot be blank")
return 1
}
if isOptionsPresent && isFilePresent {
e.Logger.Error("You can provide either --options or --file but not both")
return 1
}

var optionsData map[string]interface{}

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

data := environment.OperationRequest{
Operations: []environment.Operation{
{
Name: *operation,
Data: optionsData,
},
},
}

e.Logger.Info("Validating the operation: " + *operation + " on the environment: " + *name)

validateOperateResponse, err := envClient.ValidateOperation(*name, data)
if err != nil {
e.Logger.Error(err.Error())
return 1
}

for _, operation := range validateOperateResponse.Response.Operations {
if operation.IsFeedbackRequired {
consentMessage := fmt.Sprintf("\n%s", operation.Message)
allowedInputs := map[string]struct{}{"Y": {}, "n": {}}
val, err := e.Input.AskWithConstraints(consentMessage, allowedInputs)
if err != nil {
e.Logger.Error(err.Error())
return 1
}
if val != "Y" {
e.Logger.Info("Aborting the operation")
return 1
}
} else {
e.Logger.Info("Validations succeeded. Proceeding...")
}
}

operateResponse, err := envClient.OperateEnv(*name, data)
if err != nil {
e.Logger.Error(err.Error())
return 1
}

for _, operation := range operateResponse.Response.Operations {
e.Logger.Output(operation.Message)
}
return 0
}

e.Logger.Error("Not a valid command")
return 127
}
Expand Down Expand Up @@ -464,6 +553,15 @@ func (e *Env) Help() string {
})
}

if e.Operate {
return commandHelper("operate", "environment", "", []Options{
{Flag: "--name", Description: "name of environment"},
{Flag: "--operation", Description: "name of the operation to be performed on the environment"},
{Flag: "--options", Description: "options for 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 Expand Up @@ -496,9 +594,15 @@ func (e *Env) Synopsis() string {
if e.Set {
return "Set a default env"
}

if e.Update {
return "update an env"
}

if e.Operate {
return "operate an environment"
}

return defaultHelper()
}

Expand Down
Loading

0 comments on commit 4d89b5e

Please sign in to comment.