Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjusted CLI commands to work with new version of the Nullstone engine. #195

Merged
merged 6 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
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()
}
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)
}
19 changes: 13 additions & 6 deletions cmd/launch.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var Launch = func(providers app.Providers) *cli.Command {
Action: func(c *cli.Context) error {
return AppWorkspaceAction(c, func(ctx context.Context, cfg api.Config, appDetails app.Details) error {
osWriters := CliOsWriters{Context: c}
stderr := osWriters.Stderr()
source, version := c.String("source"), c.String("version")

pusher, err := getPusher(providers, cfg, appDetails)
Expand All @@ -35,27 +36,33 @@ var Launch = func(providers app.Providers) *cli.Command {

commitSha := ""
if version == "" {
fmt.Fprintf(osWriters.Stderr(), "No version specified. Defaulting version based on current git commit sha...\n")
fmt.Fprintf(stderr, "No version specified. Defaulting version based on current git commit sha...\n")
commitSha, version, err = calcNewVersion(ctx, pusher)
if err != nil {
return err
}
fmt.Fprintf(osWriters.Stderr(), "Version defaulted to: %s\n", version)
fmt.Fprintf(stderr, "Version defaulted to: %s\n", version)
}

err = push(ctx, osWriters, pusher, source, version)
if err != nil {
return err
}

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

fmt.Fprintln(osWriters.Stderr())
return streamDeployLogs(ctx, osWriters, cfg, *deploy, true)
fmt.Fprintln(stderr)
if result.Deploy != nil {
return streamDeployLogs(ctx, osWriters, cfg, *result.Deploy, true)
} else if result.IntentWorkflow != nil {
return streamDeployIntentLogs(ctx, osWriters, cfg, appDetails, *result.IntentWorkflow, true)
}
fmt.Fprintln(stderr, "Unable to stream deployment logs")
return nil
})
},
}
Expand Down
Loading