Skip to content

Commit

Permalink
Adjusted CLI commands to work with new version of the Nullstone engin…
Browse files Browse the repository at this point in the history
…e. (#195)
  • Loading branch information
BSick7 authored Jul 11, 2024
1 parent b85520a commit 6f24626
Show file tree
Hide file tree
Showing 27 changed files with 398 additions and 181 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 0.0.121 (Jul 11, 2024)
* Updated CLI commands (`launch`, `deploy`, `plan`, `apply`, `up`, `envs up`, `envs down`) to interop with workflows.

# 0.0.120 (Apr 09, 2024)
* Added `ingress` as an option for category when generating a new module.

Expand Down
20 changes: 20 additions & 0 deletions app_urls/base_url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package app_urls

import (
"gopkg.in/nullstone-io/go-api-client.v0"
"net/url"
"strings"
)

func GetBaseUrl(cfg api.Config) *url.URL {
u, err := url.Parse(cfg.BaseAddress)
if err != nil {
u = &url.URL{Scheme: "https", Host: "app.nullstone.io"}
}
u.Host = strings.Replace(u.Host, "api", "app", 1)
if u.Host == "localhost:8443" {
u.Scheme = "http"
u.Host = "localhost:8090"
}
return u
}
14 changes: 14 additions & 0 deletions app_urls/intent_workflow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package app_urls

import (
"fmt"
"gopkg.in/nullstone-io/go-api-client.v0"
"gopkg.in/nullstone-io/go-api-client.v0/types"
)

func GetIntentWorkflow(cfg api.Config, iw types.IntentWorkflow) string {
u := GetBaseUrl(cfg)
u.Path = fmt.Sprintf("orgs/%s/stacks/%d/envs/%d/activity/workflows/%d",
iw.OrgName, iw.StackId, iw.EnvId, iw.Id)
return u.String()
}
14 changes: 14 additions & 0 deletions app_urls/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package app_urls

import (
"fmt"
"gopkg.in/nullstone-io/go-api-client.v0"
"gopkg.in/nullstone-io/go-api-client.v0/types"
)

func GetRun(cfg api.Config, workspace types.Workspace, run types.Run) string {
u := GetBaseUrl(cfg)
u.Path = fmt.Sprintf("orgs/%s/stacks/%d/envs/%d/blocks/%d/activity/runs/%s",
workspace.OrgName, workspace.StackId, workspace.EnvId, workspace.BlockId, run.Uid)
return u.String()
}
18 changes: 18 additions & 0 deletions app_urls/workspace_workflow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package app_urls

import (
"fmt"
"gopkg.in/nullstone-io/go-api-client.v0"
"gopkg.in/nullstone-io/go-api-client.v0/types"
)

func GetWorkspaceWorkflow(cfg api.Config, ww types.WorkspaceWorkflow, isApp bool) string {
u := GetBaseUrl(cfg)
blockType := "blocks"
if isApp {
blockType = "apps"
}
u.Path = fmt.Sprintf("orgs/%s/stacks/%d/envs/%d/%s/%d/activity/workflows/%d",
ww.OrgName, ww.StackId, ww.EnvId, blockType, ww.BlockId, ww.Id)
return u.String()
}
2 changes: 1 addition & 1 deletion aws/beanstalk/remoter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func NewRemoter(ctx context.Context, osWriters logging.OsWriters, source outputs.RetrieverSource, appDetails app.Details) (admin.Remoter, error) {
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace)
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace, appDetails.WorkspaceConfig)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion aws/ec2/remoter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func NewRemoter(ctx context.Context, osWriters logging.OsWriters, source outputs.RetrieverSource, appDetails app.Details) (admin.Remoter, error) {
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace)
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace, appDetails.WorkspaceConfig)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion aws/ecs/remoter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func NewRemoter(ctx context.Context, osWriters logging.OsWriters, source outputs.RetrieverSource, appDetails app.Details) (admin.Remoter, error) {
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace)
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace, appDetails.WorkspaceConfig)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion aws/ecs/statuser.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func NewStatuser(ctx context.Context, osWriters logging.OsWriters, source outputs.RetrieverSource, appDetails app.Details) (admin.Statuser, error) {
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace)
outs, err := outputs.Retrieve[Outputs](ctx, source, appDetails.Workspace, appDetails.WorkspaceConfig)
if err != nil {
return nil, err
}
Expand Down
22 changes: 8 additions & 14 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package cmd

import (
"context"
"fmt"
"github.com/urfave/cli/v2"
"gopkg.in/nullstone-io/go-api-client.v0"
"gopkg.in/nullstone-io/go-api-client.v0/types"
"gopkg.in/nullstone-io/nullstone.v0/runs"
"os"
)

var Apply = func() *cli.Command {
Expand Down Expand Up @@ -66,19 +64,15 @@ var Apply = func() *cli.Command {
return err
}

newRun, err := runs.Create(ctx, cfg, workspace, autoApprove, false)
if err != nil {
return fmt.Errorf("error creating run: %w", err)
} else if newRun == nil {
return fmt.Errorf("unable to create run")
}
fmt.Fprintf(os.Stdout, "created apply run %q\n", newRun.Uid)
fmt.Fprintln(os.Stdout, runs.GetBrowserUrl(cfg, workspace, *newRun))

if c.IsSet("wait") {
return runs.StreamLogs(ctx, cfg, workspace, newRun)
input := PerformRunInput{
Workspace: workspace,
CommitSha: "",
IsApproved: autoApprove,
IsDestroy: false,
BlockType: types.BlockType(block.Type),
StreamLogs: c.IsSet("wait"),
}
return nil
return PerformRun(ctx, cfg, input)
})
},
}
Expand Down
9 changes: 4 additions & 5 deletions cmd/create_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@ import (
"fmt"
"github.com/nullstone-io/deployment-sdk/app"
"gopkg.in/nullstone-io/go-api-client.v0"
"gopkg.in/nullstone-io/go-api-client.v0/types"
)

func CreateDeploy(nsConfig api.Config, appDetails app.Details, commitSha, version string) (*types.Deploy, error) {
func CreateDeploy(nsConfig api.Config, appDetails app.Details, commitSha, version string) (*api.DeployCreateResult, error) {
ctx := context.TODO()
client := api.Client{Config: nsConfig}
payload := api.DeployCreatePayload{
FromSource: false,
Version: version,
CommitSha: commitSha,
}
newDeploy, err := client.Deploys().Create(ctx, appDetails.App.StackId, appDetails.App.Id, appDetails.Env.Id, payload)
result, err := client.Deploys().Create(ctx, appDetails.App.StackId, appDetails.App.Id, appDetails.Env.Id, payload)
if err != nil {
return nil, fmt.Errorf("error creating deploy: %w", err)
} else if newDeploy == nil {
} else if result == nil {
return nil, fmt.Errorf("unable to create deploy")
}
return newDeploy, nil
return result, nil
}
53 changes: 47 additions & 6 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,18 @@ var Deploy = func(providers app.Providers) *cli.Command {
}

fmt.Fprintln(osWriters.Stderr(), "Creating deploy...")
deploy, err := CreateDeploy(cfg, appDetails, commitSha, version)
result, err := CreateDeploy(cfg, appDetails, commitSha, version)
if err != nil {
return err
}

fmt.Fprintln(osWriters.Stderr())
return streamDeployLogs(ctx, osWriters, cfg, *deploy, wait)

if result.Deploy != nil {
return streamDeployLogs(ctx, osWriters, cfg, *result.Deploy, wait)
} else if result.IntentWorkflow != nil {
return streamDeployIntentLogs(ctx, osWriters, cfg, appDetails, *result.IntentWorkflow, wait)
}
return nil
})
},
}
Expand Down Expand Up @@ -93,8 +98,10 @@ func getCurrentVersion(ctx context.Context, pusher app.Pusher) (string, string,
}

func streamDeployLogs(ctx context.Context, osWriters logging.OsWriters, cfg api.Config, deploy types.Deploy, wait bool) error {
fmt.Fprintln(osWriters.Stderr(), "Waiting for deploy logs...")
stdout, stderr := osWriters.Stdout(), osWriters.Stderr()
client := api.Client{Config: cfg}

fmt.Fprintln(stderr, "Waiting for deploy logs...")
msgs, err := client.DeployLogs().Watch(ctx, deploy.StackId, deploy.Id, ws.RetryInfinite(2*time.Second))
if err != nil {
return fmt.Errorf("error connecting to deploy logs: %w", err)
Expand All @@ -107,14 +114,14 @@ func streamDeployLogs(ctx context.Context, osWriters logging.OsWriters, cfg api.
// Stop streaming logs if we receive a log message from wait-healthy and no --wait
break
}
fmt.Fprint(osWriters.Stderr(), msg.Content)
fmt.Fprint(stderr, msg.Content)
}

updated, err := client.Deploys().Get(ctx, deploy.StackId, deploy.AppId, deploy.EnvId, deploy.Id)
if err != nil {
return fmt.Errorf("error retrieving deploy status: %w", err)
}
fmt.Fprintln(osWriters.Stdout(), updated.Reference)
fmt.Fprintln(stdout, updated.Reference)
switch updated.Status {
case types.DeployStatusCancelled:
return fmt.Errorf("Deploy was cancelled.")
Expand All @@ -123,3 +130,37 @@ func streamDeployLogs(ctx context.Context, osWriters logging.OsWriters, cfg api.
}
return nil
}

func streamDeployIntentLogs(ctx context.Context, osWriters logging.OsWriters, cfg api.Config, appDetails app.Details, iw types.IntentWorkflow, wait bool) error {
_, stderr := osWriters.Stdout(), osWriters.Stderr()
client := api.Client{Config: cfg}

fmt.Fprintln(stderr, "Starting deployment...")
var err error
if iw, err = waitForRunningIntentWorkflow(ctx, cfg, iw); err != nil {
return err
} else if iw.Status == types.IntentWorkflowStatusCompleted {
fmt.Fprintln(stderr, "Deployment completed.")
return nil
}

var wflow types.WorkspaceWorkflow
for _, ww := range iw.WorkspaceWorkflows {
if ww.BlockId == appDetails.App.Id && ww.EnvId == appDetails.Env.Id && ww.StackId == appDetails.App.StackId {
wflow = ww
break
}
}
if wflow.Id == 0 {
return fmt.Errorf("deployment workflow is missing")
}

activities, err := client.WorkspaceWorkflows().GetActivities(ctx, wflow.StackId, wflow.BlockId, wflow.EnvId, wflow.Id)
if err != nil {
return fmt.Errorf("unable to find deployment: %w", err)
} else if activities == nil || activities.Deploy == nil {
return fmt.Errorf("deployment is missing")
}

return streamDeployLogs(ctx, osWriters, cfg, *activities.Deploy, wait)
}
63 changes: 6 additions & 57 deletions cmd/envs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"gopkg.in/nullstone-io/go-api-client.v0"
"gopkg.in/nullstone-io/go-api-client.v0/find"
"gopkg.in/nullstone-io/go-api-client.v0/types"
"gopkg.in/nullstone-io/nullstone.v0/runs"
"math"
"os"
"regexp"
Expand Down Expand Up @@ -372,11 +371,6 @@ func createEnvRun(c *cli.Context, cfg api.Config, isDestroy bool) error {
stackName := c.String("stack")
envName := c.String("env")

action := "launch"
if isDestroy {
action = "destroy"
}

stack, err := client.StacksByName().Get(ctx, stackName)
if err != nil {
return fmt.Errorf("error looking for stack %q: %w", stackName, err)
Expand All @@ -391,56 +385,11 @@ func createEnvRun(c *cli.Context, cfg api.Config, isDestroy bool) error {
return fmt.Errorf("environment %q does not exist in stack %d", envName, stack.Id)
}

body := types.CreateEnvRunInput{IsDestroy: isDestroy}
newRuns, err := client.EnvRuns().Create(ctx, stack.Id, env.Id, body)
if err != nil {
return fmt.Errorf("error creating run: %w", err)
}

if len(newRuns) <= 0 {
fmt.Fprintf(os.Stdout, "no runs created to %s the %q environment\n", action, envName)
return nil
}

workspaces, err := client.Workspaces().List(ctx, stack.Id)
if err != nil {
return fmt.Errorf("error retrieving list of workspaces: %w", err)
}
blocks, err := client.Blocks().List(ctx, stack.Id)
if err != nil {
return fmt.Errorf("error retrieving list of blocks: %w", err)
input := PerformEnvRunInput{
CommitSha: "",
Stack: *stack,
Env: *env,
IsDestroy: isDestroy,
}

findWorkspace := func(run types.Run) *types.Workspace {
for _, workspace := range workspaces {
if workspace.Uid == run.WorkspaceUid {
return &workspace
}
}
return nil
}
findBlock := func(workspace *types.Workspace) *types.Block {
if workspace == nil {
return nil
}
for _, block := range blocks {
if workspace.BlockId == block.Id {
return &block
}
}
return nil
}
for _, run := range newRuns {
blockName := "(unknown)"
workspace := findWorkspace(run)
if block := findBlock(workspace); block != nil {
blockName = block.Name
}
browserUrl := ""
if workspace != nil {
browserUrl = fmt.Sprintf(" Logs: %s", runs.GetBrowserUrl(cfg, *workspace, run))
}
fmt.Fprintf(os.Stdout, "created run to %s %s and dependencies in %q environment.%s\n", action, blockName, envName, browserUrl)
}
return nil
return PerformEnvRun(ctx, cfg, input)
}
Loading

0 comments on commit 6f24626

Please sign in to comment.