2021-06-30 06:03:02 +01:00
|
|
|
package stacks
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/auto"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
|
|
|
2021-07-03 15:32:09 +01:00
|
|
|
"gitlab.com/dananglin/helix/internal/config"
|
2021-06-30 06:03:02 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
dockerNetworkStackName string = "docker_network"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Previewer interface {
|
|
|
|
Preview(ctx context.Context) error
|
|
|
|
}
|
|
|
|
|
|
|
|
type Updater interface {
|
|
|
|
Update(ctx context.Context) error
|
|
|
|
}
|
|
|
|
|
|
|
|
type Destroyer interface {
|
|
|
|
Destroy(ctx context.Context) error
|
|
|
|
}
|
|
|
|
|
|
|
|
func createOrSelectStack(ctx context.Context, projectName, stackName string, deployFunc pulumi.RunFunc) (auto.Stack, error) {
|
|
|
|
var s auto.Stack
|
|
|
|
|
|
|
|
opts, err := workspaceOptions(projectName, stackName)
|
|
|
|
if err != nil {
|
|
|
|
return s, fmt.Errorf("unable to create the workspace options...\n%w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("Creating/selecting stack (%s)...\n", stackName)
|
|
|
|
s, err = auto.UpsertStackInlineSource(ctx, stackName, projectName, deployFunc, opts...)
|
|
|
|
if err != nil {
|
|
|
|
return s, fmt.Errorf("unable to create/select the stack...\n%w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("Refreshing stack (%s)...\n", stackName)
|
|
|
|
_, err = s.Refresh(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return s, fmt.Errorf("unable to refresh the stack...\n%w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func workspaceOptions(projectName, stackName string) ([]auto.LocalWorkspaceOption, error) {
|
|
|
|
pulumiHome := auto.PulumiHome(filepath.Join(os.Getenv("HOME"), ".pulumi"))
|
|
|
|
|
|
|
|
wd := filepath.Join(os.Getenv("HOME"), "Pulumi", "projects", projectName, "workspaces", stackName)
|
|
|
|
|
|
|
|
fmt.Printf("Ensuring that %s exists...\n", wd)
|
|
|
|
if err := os.MkdirAll(wd, 0750); err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to ensure that the directory exists...\n%w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
workDir := auto.WorkDir(wd)
|
|
|
|
|
|
|
|
secretsProvider := auto.SecretsProvider("passphrase")
|
|
|
|
|
|
|
|
backend := filepath.Join(os.Getenv("HOME"), "Pulumi", "projects", projectName, "stacks")
|
|
|
|
if err := os.MkdirAll(backend, 0750); err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to create the backend directory...\n%w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
project := auto.Project(workspace.Project{
|
|
|
|
Name: tokens.PackageName(projectName),
|
|
|
|
Runtime: workspace.NewProjectRuntimeInfo("go", nil),
|
|
|
|
Backend: &workspace.ProjectBackend{
|
|
|
|
URL: fmt.Sprintf("file://%s", backend),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
opts := []auto.LocalWorkspaceOption{pulumiHome, secretsProvider, project, workDir}
|
|
|
|
|
|
|
|
return opts, nil
|
|
|
|
}
|
|
|
|
|
2021-07-03 08:39:45 +01:00
|
|
|
func NewPreviewer(ctx context.Context, stack string, c config.Config) (Previewer, error) {
|
2021-06-30 06:03:02 +01:00
|
|
|
var p Previewer
|
|
|
|
var err error
|
|
|
|
|
|
|
|
switch stack {
|
|
|
|
case dockerNetworkStackName:
|
2021-07-03 08:39:45 +01:00
|
|
|
p, err = newDockerNetworkStack(ctx, c.ProjectName, stack, c.Docker.Network)
|
2021-06-30 06:03:02 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%v", stack, err)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unknown stack name '%s'", stack)
|
|
|
|
}
|
|
|
|
|
|
|
|
return p, nil
|
|
|
|
}
|
2021-07-03 08:39:45 +01:00
|
|
|
|
|
|
|
func NewUpdater(ctx context.Context, stack string, c config.Config) (Updater, error) {
|
|
|
|
var u Updater
|
|
|
|
var err error
|
|
|
|
|
|
|
|
switch stack {
|
|
|
|
case dockerNetworkStackName:
|
|
|
|
u, err = newDockerNetworkStack(ctx, c.ProjectName, stack, c.Docker.Network)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%v", stack, err)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unknown stack name '%s'", stack)
|
|
|
|
}
|
|
|
|
|
|
|
|
return u, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewDestroyer(ctx context.Context, stack string, c config.Config) (Destroyer, error) {
|
|
|
|
var d Destroyer
|
|
|
|
var err error
|
|
|
|
|
|
|
|
switch stack {
|
|
|
|
case dockerNetworkStackName:
|
|
|
|
d, err = newDockerNetworkStack(ctx, c.ProjectName, stack, c.Docker.Network)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%v", stack, err)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unknown stack name '%s'", stack)
|
|
|
|
}
|
|
|
|
|
|
|
|
return d, nil
|
|
|
|
}
|