Skip to content

Commit

Permalink
Merge pull request #184 from dream11/development
Browse files Browse the repository at this point in the history
Development to main
  • Loading branch information
akshaypatidar1999 authored Mar 18, 2023
2 parents 595bebc + afeec36 commit 79e25b8
Show file tree
Hide file tree
Showing 10 changed files with 344 additions and 50 deletions.
14 changes: 14 additions & 0 deletions api/envtype/envtype.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
package envtype

type EnvType struct {
Id int64 `yaml:"id,omitempty" json:"id,omitempty"`
CreatedBy string `yaml:"createdBy,omitempty" json:"createdBy,omitempty"`
UpdatedBy string `yaml:"updatedBy,omitempty" json:"updatedBy,omitempty"`
CreatedAt string `yaml:"createdAt,omitempty" json:"createdAt,omitempty"`
UpdatedAt string `yaml:"updatedAt,omitempty" json:"updatedAt,omitempty"`
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Strict bool `yaml:"strict,omitempty" json:"strict,omitempty"`
}

// ListResponse interface
type ListTypeResponse struct {
Response []string `yaml:"resp,omitempty" json:"resp,omitempty"`
}

type GetEnvTypeResponse struct {
Response EnvType `yaml:"resp,omitempty" json:"resp,omitempty"`
}
24 changes: 24 additions & 0 deletions api/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,31 @@ type MergedService struct {
ProvisioningConfig map[string]interface{}
}

type Operation struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Data interface{} `yaml:"data,omitempty" json:"data,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"`
}

// CompareResponse
type CompareResponse struct {
Response interface{} `yaml:"resp,omitempty" json:"resp,omitempty"`
}

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

type OperationValidationResponse struct {
Response OperationValidationResponseBody `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.0-beta",
Version: "1.3.1-beta",
}
12 changes: 12 additions & 0 deletions internal/backend/envtype.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package backend

import (
"encoding/json"
"path"

"github.com/dream11/odin/api/envtype"
)
Expand All @@ -23,3 +24,14 @@ func (e *EnvType) ListEnvType() ([]string, error) {

return envTypeResponse.Response, err
}

func (e *EnvType) GetEnvType(envName string) (envtype.EnvType, error) {
client := newApiClient()
response := client.actionWithRetry(path.Join(envEntityType, envName)+"/", "GET", nil)
response.Process(true) // process response and exit if error

var envTypeResponse envtype.GetEnvTypeResponse
err := json.Unmarshal(response.Body, &envTypeResponse)

return envTypeResponse.Response, err
}
11 changes: 10 additions & 1 deletion internal/backend/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,20 @@ import (

type Operation struct{}

func (o *Operation) ListOperations(componentTypeName string) ([]operationapi.Operation, error) {
func (o *Operation) ListComponentTypeOperations(componentTypeName string) ([]operationapi.Operation, error) {
client := newApiClient()
response := client.actionWithRetry(path.Join("component", componentTypeName, "operate"), "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
}

func (o *Operation) ListServiceOperations() ([]operationapi.Operation, error) {
client := newApiClient()
response := client.actionWithRetry(path.Join("services", "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
}
19 changes: 19 additions & 0 deletions internal/backend/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,22 @@ func (s *Service) StatusService(serviceName, version string) ([]service.Status,

return serviceResponse.Response, err
}

func (s *Service) ValidateOperation(serviceName string, data service.OperationRequest) (service.OperationValidationResponse, error) {
client := newApiClient()

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

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

return validateOperationResponse, err
}

func (s *Service) OperateService(serviceName string, data service.OperationRequest) {
client := newStreamingApiClient()
client.Headers["Command-Verb"] = "operate"
response := client.streamWithRetry(path.Join(serviceEntity, serviceName)+"/operate/", "PUT", data)
response.Process(true)
}
3 changes: 3 additions & 0 deletions internal/command/command_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ func CommandsCatalog() map[string]cli.CommandFactory {
"status service": func() (cli.Command, error) {
return &commands.Service{Status: true}, nil
},
"operate service": func() (cli.Command, error) {
return &commands.Service{Operate: true}, nil
},
// Verbs for `service-set` resource
"create service-set": func() (cli.Command, error) {
return &commands.ServiceSet{Create: true}, nil
Expand Down
20 changes: 20 additions & 0 deletions internal/command/commands/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ func (c *Component) Run(args []string) int {
return 1
}

envTypeResp, err := envTypeClient.GetEnvType(*envName)
if err != nil {
c.Logger.Error(err.Error())
return 1
}
if envTypeResp.Strict {
consentMessage := fmt.Sprintf("\nYou are executing the above command on a restricted environment. Are you sure? Enter \033[1m%s\033[0m to continue:", *envName)
val, err := c.Input.Ask(consentMessage)

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

if val != *envName {
c.Logger.Info("Aborting the operation")
return 1
}
}

data := component.OperateComponentRequest{
Data: component.Data{
EnvName: *envName,
Expand Down
131 changes: 84 additions & 47 deletions internal/command/commands/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"flag"
"fmt"

operationapi "github.com/dream11/odin/api/operation"
"github.com/dream11/odin/internal/backend"
"github.com/dream11/odin/pkg/table"
)
Expand All @@ -26,69 +27,105 @@ func (o *Operation) Run(args []string) int {
}

if o.List {
emptyParameters := emptyParameters(map[string]string{"--component-type": *componentType})
if len(emptyParameters) == 0 {
operationList, err := operationClient.ListOperations(*componentType)
if err != nil {
o.Logger.Error(err.Error())
return 1
}
isComponentTypePresent := len(*componentType) > 0

o.Logger.Info("Listing all operation(s)")
tableHeaders := []string{"Name", "Descrption"}
var tableData [][]interface{}
var operationList []operationapi.Operation
var err error

for _, operation := range operationList {
tableData = append(tableData, []interface{}{
operation.Name,
operation.Description,
})
}
table.Write(tableHeaders, tableData)
if isComponentTypePresent {
operationList, err = operationClient.ListComponentTypeOperations(*componentType)
} else {
operationList, err = operationClient.ListServiceOperations()
}

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

o.Logger.Error(fmt.Sprintf("%s cannot be blank", emptyParameters))
return 1
if isComponentTypePresent {
o.Logger.Info("Listing all operation(s)" + " on component " + *componentType)
} else {
o.Logger.Info("Listing all service operations")
}

tableHeaders := []string{"Name", "Descrption"}
var tableData [][]interface{}

for _, operation := range operationList {
tableData = append(tableData, []interface{}{
operation.Name,
operation.Description,
})
}
table.Write(tableHeaders, tableData)

if isComponentTypePresent {
o.Logger.Output("\nCommand to describe component operation(s)")
o.Logger.ItalicEmphasize("odin describe operation --name <operationName> --component-type <componentTypeName>")
} else {
o.Logger.Output("\nCommand to describe service operations")
o.Logger.ItalicEmphasize("odin describe operation --name <operationName>")
}

return 0
}

if o.Describe {
emptyParameters := emptyParameters(map[string]string{"--name": *name, "--component-type": *componentType})
if len(emptyParameters) == 0 {
operationList, err := operationClient.ListOperations(*componentType)
if err != nil {
o.Logger.Error(err.Error())
return 1
}
isNamePresent := len(*name) > 0
isComponentTypePresent := len(*componentType) > 0

o.Logger.Info("Describing operation: " + *name + " on component " + *componentType)
var operationKeys interface{}
if !isNamePresent {
o.Logger.Error("--name cannot be blank")
return 1
}

for i := range operationList {
if operationList[i].Name == *name {
operationKeys = operationList[i].InputSchema
break
}
var operationList []operationapi.Operation
var err error

if isComponentTypePresent {
operationList, err = operationClient.ListComponentTypeOperations(*componentType)
} else {
operationList, err = operationClient.ListServiceOperations()
}

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

var operationKeys interface{}

for i := range operationList {
if operationList[i].Name == *name {
operationKeys = operationList[i].InputSchema
break
}
}

if operationKeys == nil {
if operationKeys == nil {
if isComponentTypePresent {
o.Logger.Error(fmt.Sprintf("operation: %s does not exist for the component: %s", *name, *componentType))
return 1
} else {
o.Logger.Error(fmt.Sprintf("operation: %s is not a valid service operation", *name))
}
return 1
}

operationKeysJson, err := json.MarshalIndent(operationKeys, "", " ")
if err != nil {
o.Logger.Error(err.Error())
return 1
}
operationKeysJson, err := json.MarshalIndent(operationKeys, "", " ")
if err != nil {
o.Logger.Error(err.Error())
return 1
}

o.Logger.Output(fmt.Sprintf("\n%s", operationKeysJson))
return 0
if isComponentTypePresent {
o.Logger.Info("Describing operation: " + *name + " on component " + *componentType)
} else {
o.Logger.Info("Describing the service operation: " + *name)
}

o.Logger.Error(fmt.Sprintf("%s cannot be blank", emptyParameters))
return 1
o.Logger.Output(fmt.Sprintf("\n%s", operationKeysJson))
return 0
}
o.Logger.Error("Not a valid command")
return 127
Expand All @@ -113,10 +150,10 @@ func (o *Operation) Help() string {
// Synopsis : returns a brief helper text for the command's verbs
func (o *Operation) Synopsis() string {
if o.List {
return "list all operations on a component-type"
return "list all operations on service or a component-type"
}
if o.Describe {
return "describe operation on a component-type"
return "describe a operation on service or a component-type"
}
return defaultHelper()
}
Loading

0 comments on commit 79e25b8

Please sign in to comment.