Skip to content

Commit

Permalink
Merge pull request #79 from dream11/development
Browse files Browse the repository at this point in the history
Synchronous logging & exposed config
  • Loading branch information
brownhash authored May 5, 2022
2 parents d846a04 + 229ebc7 commit 34e7e17
Show file tree
Hide file tree
Showing 16 changed files with 296 additions and 967 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/go-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ jobs:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
uses: golangci/golangci-lint-action@v3
with:
version: v1.43.0
args: -E gofmt -E gci
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
repos:
- repo: git://github.com/golangci/golangci-lint
- repo: https://github.com/golangci/golangci-lint
rev: v1.43.0
hooks:
- id: golangci-lint
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# <img src="./docs/odin-logo.jpg" alt="Odin" title="Odin: Internal framework CLI for CRUD operations on environments." width="30%" height="30%">

Internal framework CLI for CRUD operations on environments.
Interface for service definitions & deployments into self-managed environments.

## Installation

```shell
export HOMEBREW_GITHUB_API_TOKEN=<your github access token>
brew install dream11/tools/odin
```

> Supporting Darwin(AMD64 & ARM64) and Linux AMD64
## Development Setup

1. [Download](https://golang.org/dl/go1.17.1.darwin-amd64.pkg) and run the Go installer.
Expand Down
19 changes: 16 additions & 3 deletions api/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,27 @@ type Type struct {
DeploymentPlatformMapping interface{} `yaml:"behaviour,omitempty" json:"behaviour,omitempty"`
}

// Exposed Config interface
type ExposedConfig struct {
Config string `yaml:"config,omitempty" json:"config,omitempty"`
Mandatory bool `yaml:"mandatory,omitempty" json:"mandatory,omitempty"`
DataType string `yaml:"data_type,omitempty" json:"data_type,omitempty"`
}

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

// ListTypeResponse interface
type DetailComponentTypeResponse struct {
Response Type `yaml:"resp,omitempty" json:"resp,omitempty"`
// DetailComponentTypeResponse interface
type ComponentDetailsResponse struct {
Response ComponentDetails `yaml:"resp,omitempty" json:"resp,omitempty"`
}

// ComponentDetails interface
type ComponentDetails struct {
Details Type `yaml:"details,omitempty" json:"details,omitempty"`
ExposedConfigs []ExposedConfig `yaml:"exposed_config,omitempty" json:"exposed_config,omitempty"`
}

// ListTypeResponse interface
Expand Down
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.0.1-alpha",
Version: "1.1.0-alpha",
}
12 changes: 10 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ module github.com/dream11/odin
go 1.17

require (
github.com/mitchellh/cli v1.1.2
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
Expand All @@ -18,10 +16,20 @@ require (
github.com/imdario/mergo v0.3.12 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/cli v1.1.2
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)

require (
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
)
928 changes: 11 additions & 917 deletions go.sum

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions internal/backend/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package backend
import (
"github.com/dream11/odin/internal/config"
"github.com/dream11/odin/pkg/request"
"github.com/dream11/odin/pkg/sse"
)

// initiation of an HTTP client for backend interactions
Expand Down Expand Up @@ -49,3 +50,42 @@ func newApiClient() clientProperties {

return apiClient
}

// initiation of an SSE client for backend stream interactions
type streamingClientProperties clientProperties

// perform streaming on initiated client
func (sc *streamingClientProperties) stream(entity, requestType string, body interface{}) sse.StreamResponse {
req := sse.StreamRequest{
Method: requestType,
URL: sc.address + entity,
Header: sc.Headers,
Query: sc.QueryParams,
Body: body,
}

response := req.Stream()
return response
}

func newStreamingClient() streamingClientProperties {
var appConfig = config.Get()

return streamingClientProperties{
address: appConfig.BackendAddr + "/",
Headers: map[string]string{
"Content-Type": "application/json",
},
QueryParams: map[string]string{},
}
}

func newStreamingApiClient() streamingClientProperties {
var appConfig = config.Get()

streamClient := newStreamingClient()
streamClient.address += "api/integration/cli/stream/v2/"
streamClient.Headers["Authorization"] = "Bearer " + appConfig.AccessToken

return streamClient
}
8 changes: 4 additions & 4 deletions internal/backend/componentType.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ func (c *ComponentType) ListComponentTypes(componentTypeName, version string) ([
}

// DescribeComponentTypes : describe a component type
func (c *ComponentType) DescribeComponentType(componentTypeName, version string) (component.Type, error) {
func (c *ComponentType) DescribeComponentType(componentTypeName, version string) (component.ComponentDetails, error) {
client := newApiClient()
client.QueryParams["version"] = version
response := client.action(path.Join("componenttypes", componentTypeName), "GET", nil)
response.Process(true) // process response and exit if error

var componentTypeResponse component.DetailComponentTypeResponse
err := json.Unmarshal(response.Body, &componentTypeResponse)
var componentDetailsResponse component.ComponentDetailsResponse
err := json.Unmarshal(response.Body, &componentDetailsResponse)

return componentTypeResponse.Response, err
return componentDetailsResponse.Response, err
}
14 changes: 14 additions & 0 deletions internal/backend/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ func (e *Env) CreateEnv(envDetails interface{}) (envResp.Env, error) {
return envResponse.Response, err
}

// CreateEnvStream : create an empty Env and stream creation events
func (e *Env) CreateEnvStream(envDetails interface{}) {
client := newStreamingApiClient()
response := client.stream(envEntity+"/", "POST", envDetails)
response.Process(true)
}

// DescribeEnv : describe an Env
func (e *Env) DescribeEnv(env, service, component string) (envResp.Env, error) {
client := newApiClient()
Expand Down Expand Up @@ -64,6 +71,13 @@ func (e *Env) DeleteEnv(env string) {
response.Process(true) // process response and exit if error
}

// DeleteEnvStream : delete a created environment and stream deletion events
func (e *Env) DeleteEnvStream(env string) {
client := newStreamingApiClient()
response := client.stream(path.Join(envEntity, env)+"/", "DELETE", nil)
response.Process(true)
}

// UpdateEnv : update a created environment
func (e *Env) UpdateEnv(env string, config interface{}) {
client := newApiClient()
Expand Down
28 changes: 24 additions & 4 deletions internal/backend/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (s *Service) CreateService(service interface{}) {
response.Process(true) // process response and exit if error
}

// Rebuild Service : rebuild a service
// RebuildService : rebuild a service
func (s *Service) RebuildService(service, version string) {
client := newApiClient()

Expand Down Expand Up @@ -64,14 +64,22 @@ func (s *Service) ListServices(team, version, serviceName string, maturity bool)
return serviceResponse.Response, err
}

// UndeployService: To remove a service from a given env
func (s *Service) UndeployService(serviceName, env_name string) {
// UndeployService : To remove a service from a given env
func (s *Service) UndeployService(serviceName, envName string) {
client := newApiClient()
client.QueryParams["env_name"] = env_name
client.QueryParams["env_name"] = envName

response := client.action(path.Join(serviceEntity, "undeploy", serviceName)+"/", "DELETE", nil)
response.Process(true)
}

// UnDeployServiceStream : un-deploy a service in an Env and stream creation events
func (s *Service) UnDeployServiceStream(serviceName, envName string) {
client := newStreamingApiClient()
client.QueryParams["env_name"] = envName

response := client.stream(path.Join(serviceEntity, "undeploy", serviceName)+"/", "DELETE", nil)
response.Process(true)
}

// DeleteService : delete a service version
Expand Down Expand Up @@ -102,6 +110,18 @@ func (s *Service) DeployService(service, version, env, platform string, force, r
response.Process(true)
}

// DeployServiceStream : deploy a service in an Env and stream creation events
func (s *Service) DeployServiceStream(service, version, env, platform string, force, rebuild bool) {
client := newStreamingApiClient()
client.QueryParams["env_name"] = env
client.QueryParams["force"] = fmt.Sprintf("%v", force)
client.QueryParams["rebuild"] = fmt.Sprintf("%v", rebuild)
client.QueryParams["platform"] = platform

response := client.stream(path.Join(serviceEntity, "deploy", service, "versions", version)+"/", "POST", nil)
response.Process(true)
}

// StatusService : get status of a service
func (s *Service) StatusService(serviceName, version string) ([]service.Status, error) {
client := newApiClient()
Expand Down
24 changes: 21 additions & 3 deletions internal/command/commands/componentType.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,38 @@ func (c *ComponentType) Run(args []string) int {
emptyParameters := emptyParameters(map[string]string{"--name": *componentTypeName})
if len(emptyParameters) == 0 {
c.Logger.Info("Describing component type: " + *componentTypeName + "@" + *componentTypeVersion)
componentTypeResp, err := componentTypeClient.DescribeComponentType(*componentTypeName, *componentTypeVersion)
componentDetailsResponse, err := componentTypeClient.DescribeComponentType(*componentTypeName, *componentTypeVersion)
if err != nil {
c.Logger.Error(err.Error())
return 1
}

details, err := yaml.Marshal(componentTypeResp)
details, err := yaml.Marshal(componentDetailsResponse.Details)
if err != nil {
c.Logger.Error(err.Error())
return 1
}

c.Logger.Output(fmt.Sprintf("\n%s", details))
var tableHeaders []string
var tableData [][]interface{}
if len(componentDetailsResponse.ExposedConfigs) > 0 {
tableHeaders = []string{"Config", "Mandatory", "Data Type"}
for _, exposed_config := range componentDetailsResponse.ExposedConfigs {
tableData = append(tableData, []interface{}{
exposed_config.Config,
exposed_config.Mandatory,
exposed_config.DataType,
})
}
}

c.Logger.Output(fmt.Sprintf("\n%s", details))
c.Logger.ItalicEmphasize("List of exposed configs :\n")
err = table.Write(tableHeaders, tableData)
if err != nil {
c.Logger.Error(err.Error())
return 1
}
return 0
}

Expand Down
32 changes: 22 additions & 10 deletions internal/command/commands/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func (e *Env) Run(args []string) int {
providerAccount := flagSet.String("account", "", "account name to provision the environment in")
filePath := flagSet.String("file", "environment.yaml", "file to read environment config")
id := flagSet.Int("id", 0, "unique id of a changelog of an env")
tail := flagSet.Bool("tail", false, "enable synchronous logging of creation events")

err := flagSet.Parse(args)
if err != nil {
Expand All @@ -45,21 +46,25 @@ func (e *Env) Run(args []string) int {
if e.Create {
emptyParameters := emptyParameters(map[string]string{"--env-type": *env})
if len(emptyParameters) == 0 {
e.Logger.Info("Creating environment for team: " + *team)
e.Logger.Info("Initiating environment creation for team: " + *team)
envConfig := environment.Env{
Team: *team,
Purpose: *purpose,
EnvType: *env,
Account: *providerAccount,
}

response, err := envClient.CreateEnv(envConfig)
if err != nil {
e.Logger.Error(err.Error())
return 1
}
if *tail {
envClient.CreateEnvStream(envConfig)
} else {
response, err := envClient.CreateEnv(envConfig)
if err != nil {
e.Logger.Error(err.Error())
return 1
}

e.Logger.Success("Env: " + response.Name + " created!")
e.Logger.Success("Env: " + response.Name + " created!")
}

return 0
}
Expand Down Expand Up @@ -245,9 +250,14 @@ func (e *Env) Run(args []string) int {
if e.Delete {
emptyParameters := emptyParameters(map[string]string{"--name": *name})
if len(emptyParameters) == 0 {
e.Logger.Info("Deleting environment: " + *name)
envClient.DeleteEnv(*name)
e.Logger.Success(fmt.Sprintf("Deletion started: %s", *name))
if *tail {
envClient.DeleteEnvStream(*name)
} else {
e.Logger.Info("Initiating environment deletion: " + *name)
envClient.DeleteEnv(*name)
e.Logger.Success(fmt.Sprintf("Deletion started: %s", *name))
}

return 0
}

Expand Down Expand Up @@ -340,6 +350,7 @@ func (e *Env) Help() string {
"--purpose=reason to create environment",
"--env-type=type of environment",
"--account=account name to provision the environment in (optional)",
"--tail enable synchronous logging of creation events",
})
}

Expand Down Expand Up @@ -370,6 +381,7 @@ func (e *Env) Help() string {
if e.Delete {
return commandHelper("delete", "environment", []string{
"--name=name of environment to delete",
"--tail enable synchronous logging of deletion events",
})
}

Expand Down
Loading

0 comments on commit 34e7e17

Please sign in to comment.