Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
36a0e2a
added application add command to create applications
vipul-rawat Dec 11, 2024
7bc24e2
fix linters
vipul-rawat Dec 11, 2024
650e5e0
fix tests for application
vipul-rawat Dec 12, 2024
c91263e
Merge branch 'main' of github.com:zopdev/zop-cli into add-application
vipul-rawat Dec 12, 2024
6b4f023
add application lister command to display all applications and enviro…
vipul-rawat Dec 12, 2024
dbd42c3
modify the application list output
vipul-rawat Dec 12, 2024
59e1868
modify the application list output
vipul-rawat Dec 12, 2024
e1bbd86
add environment creation
vipul-rawat Dec 12, 2024
3b195d1
fix linter errors
vipul-rawat Dec 16, 2024
cacd5d7
list all environments for an application
vipul-rawat Dec 16, 2024
f340f10
fix linter errors
vipul-rawat Dec 16, 2024
f96bba3
Merge branch 'main' of github.com:zopdev/zop-cli into list-application
vipul-rawat Dec 16, 2024
27f51a5
rename methods according to the convention
vipul-rawat Dec 16, 2024
40ffbb7
add test for list function
vipul-rawat Dec 16, 2024
5259853
Merge branch 'list-application' of github.com:zopdev/zop-cli into add…
vipul-rawat Dec 16, 2024
dec59de
refactor application lister interface
vipul-rawat Dec 16, 2024
9819d9d
Merge branch 'add-environment' of github.com:zopdev/zop-cli into list…
vipul-rawat Dec 16, 2024
f65bf72
add godoc for environment implementation
vipul-rawat Dec 16, 2024
ffee13c
Merge branch 'main' of github.com:zopdev/zop-cli into add-environment
vipul-rawat Dec 16, 2024
03d74fd
add table printing for the envs
vipul-rawat Dec 17, 2024
3e3ed00
inital commit
vipul-rawat Dec 17, 2024
63705c5
refactor list generation for recurring use
vipul-rawat Dec 17, 2024
3bc5719
Merge branch 'add-environment' of github.com:zopdev/zop-cli into list…
vipul-rawat Dec 17, 2024
94c51df
change list styles to match zopdev theme
vipul-rawat Dec 17, 2024
1a45ac2
Merge branch 'list-environments' of github.com:zopdev/zop-cli into ad…
vipul-rawat Dec 17, 2024
2d4803c
add selection of cloud acc, application and deploy options
vipul-rawat Dec 17, 2024
ed5a56c
Merge branch 'main' of github.com:zopdev/zop-cli into list-environments
vipul-rawat Dec 17, 2024
bed8ede
Display selected application
vipul-rawat Dec 17, 2024
d0c9905
Add logic to display different option list for deployment space
vipul-rawat Dec 17, 2024
4e7ccdf
Merge branch 'list-environments' of github.com:zopdev/zop-cli into ad…
vipul-rawat Dec 17, 2024
6441061
refactor service and add godoc
vipul-rawat Dec 18, 2024
20e70f6
Merge branch 'main' of github.com:zopdev/zop-cli into add-deployment-…
vipul-rawat Dec 18, 2024
705750d
add utils godoc
vipul-rawat Dec 18, 2024
883caae
fix deployment Option models and infinite for loop
vipul-rawat Dec 18, 2024
e157e9f
add error check for POST deploymentSpace and option metadata in table
vipul-rawat Dec 18, 2024
424a9c5
add spinners to improve the TUI
vipul-rawat Dec 18, 2024
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
2 changes: 1 addition & 1 deletion application/service/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type Environment struct {

// Application represents an application with its associated environments.
type Application struct {
ID int `json:"id"` // Unique identifier of the application
ID int64 `json:"id"` // Unique identifier of the application
Name string `json:"name"` // Name of the application
Envs []Environment `json:"environments,omitempty"` // List of associated environments
}
41 changes: 41 additions & 0 deletions deploymentspace/handler/deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Package handler is used to import data from external sources
// this package has an Add(ctx *gofr.Context) method that is used to configure deployment space
// for the environments of applications.
package handler

import "gofr.dev/pkg/gofr"

// Handler is responsible for handling requests related to deployment operations.
type Handler struct {
deployService DeploymentService
}

// New initializes a new Handler instance.
//
// Parameters:
// - depSvc: An instance of DeploymentService used to manage deployment-related operations.
//
// Returns:
// - A pointer to the Handler instance.
func New(depSvc DeploymentService) *Handler {
return &Handler{
deployService: depSvc,
}
}

// Add processes a deployment creation request.
//
// Parameters:
// - ctx: The context object containing request and session details.
//
// Returns:
// - A success message if the deployment is created successfully.
// - An error if the deployment creation fails.
func (h *Handler) Add(ctx *gofr.Context) (any, error) {
err := h.deployService.Add(ctx)
if err != nil {
return nil, err
}

return "Deployment Created", nil
}
17 changes: 17 additions & 0 deletions deploymentspace/handler/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package handler

import "gofr.dev/pkg/gofr"

// DeploymentService defines the interface for deployment-related operations.
//
// It contains methods that allow adding and managing deployments.
type DeploymentService interface {
// Add creates a new deployment.
//
// Parameters:
// - ctx: The context object containing request and session details.
//
// Returns:
// - An error if the deployment creation fails.
Add(ctx *gofr.Context) error
}
219 changes: 219 additions & 0 deletions deploymentspace/service/deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
// Package service provides structures and interfaces for managing deployment options and related operations.
package service

import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"

"gofr.dev/pkg/gofr"
"gofr.dev/pkg/gofr/cmd/terminal"

"zop.dev/cli/zop/utils"
)

var (

// ErrConnectingZopAPI is returned when there is an error connecting to the Zop API.
ErrConnectingZopAPI = errors.New("unable to connect to Zop API")

// ErrGettingDeploymentOptions is returned when there is an error adding an environment.
ErrGettingDeploymentOptions = errors.New("unable to get deployment options")

// ErrorFetchingEnvironments is returned when there is an error fetching environments for a given application.
ErrorFetchingEnvironments = errors.New("unable to fetch environments")

// ErrUnknown is returned when an unknown error occurs while processing the request.
ErrUnknown = errors.New("unknown error occurred while processing the request")
)

// Service represents the core service that handles cloud account and environment-related operations.
type Service struct {
cloudGet CloudAccountService
envGet EnvironmentService
}

// New initializes a new Service instance.
//
// Parameters:
// - cloudGet: A CloudAccountService instance for retrieving cloud accounts.
// - envGet: An EnvironmentService instance for retrieving environments.
//
// Returns:
// - A pointer to the Service instance.
func New(cloudGet CloudAccountService, envGet EnvironmentService) *Service {
return &Service{
cloudGet: cloudGet,
envGet: envGet,
}
}

// Add handles the addition of a deployment configuration.
//
// This function selects a cloud account and environment, retrieves deployment options,
// processes the options, and submits the deployment request.
//
// Parameters:
// - ctx: The context object containing request and session details.
//
// Returns:
// - An error if any step in the process fails.
func (s *Service) Add(ctx *gofr.Context) error {
var request = make(map[string]any)

cloudAcc, err := s.getSelectedCloudAccount(ctx)
if err != nil {
return err
}

request["cloudAccount"] = cloudAcc

ctx.Out.Println("Selected cloud account: ", cloudAcc.Name)

env, err := s.getSelectedEnvironment(ctx)
if err != nil {
return err
}

ctx.Out.Println("Selected environment"+
":", env.Name)

options, err := getDeploymentSpaceOptions(ctx, cloudAcc.ID)
if err != nil {
return err
}

request[options.Type] = options

if er := processOptions(ctx, request, options.Path); er != nil {
return er
}

return submitDeployment(ctx, env.ID, request)
}

func processOptions(ctx *gofr.Context, request map[string]any, path string) error {
var (
optionName string
sp = terminal.NewDotSpinner(ctx.Out)
api = ctx.GetHTTPService("api-service")
)

sp.Spin(ctx)

resp, err := api.Get(ctx, path[1:], nil)
if err != nil {
ctx.Logger.Errorf("error connecting to zop api! %v", err)
return ErrConnectingZopAPI
}

var option apiResponse
if er := utils.GetResponse(resp, &option); er != nil {
ctx.Logger.Errorf("error fetching deployment options! %v", er)

return ErrGettingDeploymentOptions
}

resp.Body.Close()
sp.Stop()

for {
optionName = "option"

if option.Data.Metadata != nil {
optionName = option.Data.Metadata.Name
}

opt, er := getSelectedOption(ctx, option.Data.Option, optionName)
if er != nil {
return er
}

sp.Spin(ctx)

updateRequestWithOption(request, opt)

if option.Data.Next == nil {
break
}

params := getParameters(opt, &option)

resp, er = api.Get(ctx, option.Data.Next.Path[1:]+params, nil)
if er != nil {
ctx.Logger.Errorf("error connecting to zop api! %v", er)
return ErrConnectingZopAPI
}

option.Data = nil

er = utils.GetResponse(resp, &option)
if er != nil {
ctx.Logger.Errorf("error fetching deployment options! %v", er)
return ErrGettingDeploymentOptions
}

resp.Body.Close()
sp.Stop()
}

return nil
}

func updateRequestWithOption(request, opt map[string]any) {
keys := strings.Split(opt["type"].(string), ".")
current := request

for i, key := range keys {
if i == len(keys)-1 {
current[key] = opt
break
}

if _, exists := current[key]; !exists {
current[key] = make(map[string]any)
}

current = current[key].(map[string]any)
}
}

func submitDeployment(ctx *gofr.Context, envID int64, request map[string]any) error {
b, err := json.Marshal(request)
if err != nil {
return err
}

resp, err := ctx.GetHTTPService("api-service").
PostWithHeaders(ctx, fmt.Sprintf("environments/%d/deploymentspace", envID), nil, b, map[string]string{
"Content-Type": "application/json",
})
if err != nil {
return ErrConnectingZopAPI
}

if resp.StatusCode != http.StatusCreated {
var er ErrorResponse

err = utils.GetResponse(resp, &er)
if err != nil {
return ErrUnknown
}

return &er
}

return resp.Body.Close()
}

func getParameters(opt map[string]any, options *apiResponse) string {
params := "?"

for _, v := range options.Data.Next.Params {
params += fmt.Sprintf("&%s=%s", v, opt[v])
}

return params
}
28 changes: 28 additions & 0 deletions deploymentspace/service/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package service

import "fmt"

// ErrNoItemSelected represents an error that occurs when no item of a specific type is selected.
type ErrNoItemSelected struct {
Type string
}

// Error returns the error message for ErrNoItemSelected.
//
// This method satisfies the error interface.
//
// Returns:
// - A formatted error message indicating the type of the unselected item.
func (e *ErrNoItemSelected) Error() string {
return fmt.Sprintf("no %s selected", e.Type)
}

type ErrorResponse struct {
Er struct {
Message string `json:"message"`
} `json:"error"`
}

func (e *ErrorResponse) Error() string {
return e.Er.Message
}
36 changes: 36 additions & 0 deletions deploymentspace/service/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package service

import (
"gofr.dev/pkg/gofr"

cloudSvc "zop.dev/cli/zop/cloud/service/list"
envSvc "zop.dev/cli/zop/environment/service"
)

// CloudAccountService defines the interface for managing cloud accounts.
// It provides methods to retrieve cloud accounts available to the user.
type CloudAccountService interface {
// GetAccounts retrieves a list of cloud accounts.
//
// Parameters:
// - ctx: The context object containing request and session details.
//
// Returns:
// - A slice of pointers to CloudAccountResponse objects.
// - An error if the retrieval fails.
GetAccounts(ctx *gofr.Context) ([]*cloudSvc.CloudAccountResponse, error)
}

// EnvironmentService defines the interface for managing environments.
// It provides methods to list the environments associated with a user.
type EnvironmentService interface {
// List retrieves a list of environments.
//
// Parameters:
// - ctx: The context object containing request and session details.
//
// Returns:
// - A slice of Environment objects.
// - An error if the retrieval fails.
List(ctx *gofr.Context) ([]envSvc.Environment, error)
}
Loading
Loading