Add environments to project configuration

This commit is contained in:
Pieter Noordhuis 2022-09-16 13:50:47 +02:00
parent 7cad8bda81
commit 22e0fc9286
No known key found for this signature in database
GPG Key ID: 87E4AC7F130E09B5
6 changed files with 119 additions and 12 deletions

View File

@ -50,6 +50,12 @@ type Config struct {
// created by administrator users or admin-level automation, like Terraform // created by administrator users or admin-level automation, like Terraform
// and/or SCIM provisioning. // and/or SCIM provisioning.
Assertions *Assertions `json:"assertions,omitempty"` Assertions *Assertions `json:"assertions,omitempty"`
// Environments contain this project's defined environments.
// They can be used to differentiate settings and resources between
// development, staging, production, etc.
// The project assumes an environment named "development" is always defined.
Environments map[string]Environment `json:"environments"`
} }
func (c Config) IsDevClusterDefined() bool { func (c Config) IsDevClusterDefined() bool {

41
project/environment.go Normal file
View File

@ -0,0 +1,41 @@
package project
import (
"os"
"github.com/spf13/cobra"
)
const bricksEnv = "BRICKS_ENV"
const defaultEnvironment = "development"
// Workspace defines configurables at the workspace level.
type Workspace struct {
Profile string `json:"profile,omitempty"`
}
// Environment defines all configurables for a single environment.
type Environment struct {
Workspace Workspace `json:"workspace"`
}
// getEnvironment returns the name of the environment to operate in.
func getEnvironment(cmd *cobra.Command) (value string) {
// The command line flag takes precedence.
flag := cmd.Flag("environment")
if flag != nil {
value = flag.Value.String()
if value != "" {
return
}
}
// If it's not set, use the environment variable.
value = os.Getenv(bricksEnv)
if value != "" {
return
}
return defaultEnvironment
}

View File

@ -0,0 +1,38 @@
package project
import (
"testing"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)
func TestEnvironmentFromCommand(t *testing.T) {
var cmd cobra.Command
cmd.Flags().String("environment", "", "specify environment")
cmd.Flags().Set("environment", "env-from-arg")
t.Setenv(bricksEnv, "")
value := getEnvironment(&cmd)
assert.Equal(t, "env-from-arg", value)
}
func TestEnvironmentFromEnvironment(t *testing.T) {
var cmd cobra.Command
cmd.Flags().String("environment", "", "specify environment")
cmd.Flags().Set("environment", "")
t.Setenv(bricksEnv, "env-from-env")
value := getEnvironment(&cmd)
assert.Equal(t, "env-from-env", value)
}
func TestEnvironmentDefault(t *testing.T) {
var cmd cobra.Command
cmd.Flags().String("environment", "", "specify environment")
cmd.Flags().Set("environment", "")
t.Setenv(bricksEnv, "")
value := getEnvironment(&cmd)
assert.Equal(t, defaultEnvironment, value)
}

View File

@ -17,10 +17,12 @@ type project struct {
mu sync.Mutex mu sync.Mutex
root string root string
env string
config *Config config *Config
wsc *workspaces.WorkspacesClient environment *Environment
me *scim.User wsc *workspaces.WorkspacesClient
me *scim.User
} }
// Configure is used as a PreRunE function for all commands that // Configure is used as a PreRunE function for all commands that
@ -32,7 +34,7 @@ func Configure(cmd *cobra.Command, args []string) error {
return err return err
} }
ctx, err := Initialize(cmd.Context(), root) ctx, err := Initialize(cmd.Context(), root, getEnvironment(cmd))
if err != nil { if err != nil {
return err return err
} }
@ -44,21 +46,30 @@ func Configure(cmd *cobra.Command, args []string) error {
// Placeholder to use as unique key in context.Context. // Placeholder to use as unique key in context.Context.
var projectKey int var projectKey int
// Initialize loads a project configuration given a root. // Initialize loads a project configuration given a root and environment.
// It stores the project on a new context. // It stores the project on a new context.
// The project is available through the `Get()` function. // The project is available through the `Get()` function.
func Initialize(ctx context.Context, root string) (context.Context, error) { func Initialize(ctx context.Context, root, env string) (context.Context, error) {
config, err := loadProjectConf(root) config, err := loadProjectConf(root)
if err != nil { if err != nil {
return nil, err return nil, err
} }
p := project{ // Confirm that the specified environment is valid.
root: root, environment, ok := config.Environments[env]
config: &config, if !ok {
return nil, fmt.Errorf("environment [%s] not defined", env)
} }
p.wsc = workspaces.New(&databricks.Config{Profile: config.Profile}) p := project{
root: root,
env: env,
config: &config,
environment: &environment,
}
p.wsc = workspaces.New(&databricks.Config{Profile: environment.Workspace.Profile})
return context.WithValue(ctx, &projectKey, &p), nil return context.WithValue(ctx, &projectKey, &p), nil
} }
@ -81,6 +92,14 @@ func (p *project) Root() string {
return p.root return p.root
} }
func (p *project) Config() Config {
return *p.config
}
func (p *project) Environment() Environment {
return *p.environment
}
func (p *project) Me() (*scim.User, error) { func (p *project) Me() (*scim.User, error) {
p.mu.Lock() p.mu.Lock()
defer p.mu.Unlock() defer p.mu.Unlock()

View File

@ -9,7 +9,7 @@ import (
) )
func TestProjectInitialize(t *testing.T) { func TestProjectInitialize(t *testing.T) {
ctx, err := Initialize(context.Background(), "./testdata") ctx, err := Initialize(context.Background(), "./testdata", defaultEnvironment)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, Get(ctx).config.Name, "dev") assert.Equal(t, Get(ctx).config.Name, "dev")
} }

View File

@ -1,4 +1,7 @@
name: dev name: dev
profile: demo profile: demo
dev_cluster: dev_cluster:
cluster_name: Shared Autoscaling cluster_name: Shared Autoscaling
environments:
development: