Skip to content

Commit

Permalink
improve lock and override mechanisms
Browse files Browse the repository at this point in the history
  • Loading branch information
maorfr committed Oct 17, 2018
1 parent 9e2e765 commit 9958369
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 10 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ push chart Push Helm chart to chart repository
get env Get list of Helm releases in an environment (Kubernetes namespace)
deploy env Deploy a list of Helm charts to an environment (Kubernetes namespace)
delete env Delete an environment (Kubernetes namespace) along with all Helm releases in it
lock env Lock an environment (Kubernetes namespace)
unlock env Unlock an environment (Kubernetes namespace)
create resource Create or update a resource via REST API
get resource Get a resource via REST API
Expand Down Expand Up @@ -304,6 +306,30 @@ Flags:

`helm-tls-store` - path to directory containing `<kube-context>.cert.pem` and `<kube-context>.key.pem` files

### Lock env
```
Lock an environment (Kubernetes namespace)
Usage:
orca lock env [flags]
Flags:
--kube-context string name of the kubeconfig context to use. Overrides $ORCA_KUBE_CONTEXT
-n, --name string name of environment (namespace) to delete. Overrides $ORCA_NAME
```

### Unlock env
```
Unlock an environment (Kubernetes namespace)
Usage:
orca unlock env [flags]
Flags:
--kube-context string name of the kubeconfig context to use. Overrides $ORCA_KUBE_CONTEXT
-n, --name string name of environment (namespace) to delete. Overrides $ORCA_NAME
```

### Create resource
```
Create or update a resource via REST API
Expand Down
28 changes: 28 additions & 0 deletions cmd/orca.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Instead of writing scripts on top of scripts, Orca holds all the logic.
cmd.AddCommand(NewPushCmd(out))
cmd.AddCommand(NewCreateCmd(out))
cmd.AddCommand(NewVersionCmd(out))
cmd.AddCommand(NewLockCmd(out))
cmd.AddCommand(NewUnlockCmd(out))

return cmd
}
Expand Down Expand Up @@ -96,6 +98,32 @@ func NewGetCmd(out io.Writer) *cobra.Command {
return cmd
}

// NewLockCmd represents the lock command
func NewLockCmd(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "lock",
Short: "Lock functions",
Long: ``,
}

cmd.AddCommand(orca.NewLockEnvCmd(out))

return cmd
}

// NewUnlockCmd represents the unlock command
func NewUnlockCmd(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "unlock",
Short: "Unlock functions",
Long: ``,
}

cmd.AddCommand(orca.NewUnlockEnvCmd(out))

return cmd
}

// NewPushCmd represents the get command
func NewPushCmd(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Expand Down
77 changes: 72 additions & 5 deletions pkg/orca/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,25 +108,26 @@ func NewDeployEnvCmd(out io.Writer) *cobra.Command {
},
Run: func(cmd *cobra.Command, args []string) {
print := false

utils.AddRepository(e.repo, print)
utils.UpdateRepositories(print)

nsPreExists := true
if !utils.NamespaceExists(e.name, e.kubeContext) {
nsPreExists = false
utils.CreateNamespace(e.name, e.kubeContext, print)
log.Printf("created environment \"%s\"", e.name)
}

utils.AddRepository(e.repo, print)
utils.UpdateRepositories(print)
lockEnvironment(e.name, e.kubeContext, print)

var desiredReleases []utils.ReleaseSpec
if nsPreExists && e.deployOnlyOverrideIfEnvExists {
desiredReleases = utils.InitReleases(e.name, e.override)
} else {
desiredReleases = utils.InitReleasesFromChartsFile(e.chartsFile, e.name)
desiredReleases = utils.OverrideReleases(desiredReleases, e.override)
desiredReleases = utils.OverrideReleases(desiredReleases, e.override, e.name)
}

lockEnvironment(e.name, e.kubeContext, print)
includeFailed := false
installedReleases := utils.GetInstalledReleases(e.kubeContext, e.name, includeFailed)
releasesToInstall := utils.GetReleasesDelta(desiredReleases, installedReleases)
Expand Down Expand Up @@ -204,6 +205,72 @@ func NewDeleteEnvCmd(out io.Writer) *cobra.Command {
return cmd
}

// NewLockEnvCmd represents the lock env command
func NewLockEnvCmd(out io.Writer) *cobra.Command {
e := &envCmd{out: out}

cmd := &cobra.Command{
Use: "env",
Short: "Lock an environment (Kubernetes namespace)",
Long: ``,
Args: func(cmd *cobra.Command, args []string) error {
if e.name == "" {
return errors.New("name can not be empty")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
if !utils.NamespaceExists(e.name, e.kubeContext) {
log.Printf("environment \"%s\" not found", e.name)
return
}
print := false
lockEnvironment(e.name, e.kubeContext, print)
log.Printf("locked environment \"%s\"", e.name)
},
}

f := cmd.Flags()

f.StringVarP(&e.name, "name", "n", os.Getenv("ORCA_NAME"), "name of environment (namespace) to delete. Overrides $ORCA_NAME")
f.StringVar(&e.kubeContext, "kube-context", os.Getenv("ORCA_KUBE_CONTEXT"), "name of the kubeconfig context to use. Overrides $ORCA_KUBE_CONTEXT")

return cmd
}

// NewUnlockEnvCmd represents the unlock env command
func NewUnlockEnvCmd(out io.Writer) *cobra.Command {
e := &envCmd{out: out}

cmd := &cobra.Command{
Use: "env",
Short: "Unlock an environment (Kubernetes namespace)",
Long: ``,
Args: func(cmd *cobra.Command, args []string) error {
if e.name == "" {
return errors.New("name can not be empty")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
if !utils.NamespaceExists(e.name, e.kubeContext) {
log.Printf("environment \"%s\" not found", e.name)
return
}
print := false
unlockEnvironment(e.name, e.kubeContext, print)
log.Printf("unlocked environment \"%s\"", e.name)
},
}

f := cmd.Flags()

f.StringVarP(&e.name, "name", "n", os.Getenv("ORCA_NAME"), "name of environment (namespace) to delete. Overrides $ORCA_NAME")
f.StringVar(&e.kubeContext, "kube-context", os.Getenv("ORCA_KUBE_CONTEXT"), "name of the kubeconfig context to use. Overrides $ORCA_KUBE_CONTEXT")

return cmd
}

const (
annotationPrefix string = "orca.nuvocares.com"
stateAnnotation string = annotationPrefix + "/state"
Expand Down
25 changes: 22 additions & 3 deletions pkg/utils/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,21 +121,40 @@ func CheckCircularDependencies(releases []ReleaseSpec) bool {
return false
}

func OverrideReleases(releases []ReleaseSpec, overrides []string) []ReleaseSpec {
func OverrideReleases(releases []ReleaseSpec, overrides []string, env string) []ReleaseSpec {
if len(overrides) == 0 {
return releases
}

var outReleases []ReleaseSpec
var overrideFound = make([]bool, len(overrides))

for _, r := range releases {
for _, override := range overrides {
oChartName, oChartVersion := SplitInTwo(override, "=")
for i := 0; i < len(overrides); i++ {
oChartName, oChartVersion := SplitInTwo(overrides[i], "=")

if r.ChartName == oChartName && r.ChartVersion != oChartVersion {
overrideFound[i] = true
r.ChartName = oChartName
r.ChartVersion = oChartVersion
}
}
outReleases = append(outReleases, r)
}

for i := 0; i < len(overrides); i++ {
if overrideFound[i] {
continue
}
oChartName, oChartVersion := SplitInTwo(overrides[i], "=")
r := ReleaseSpec{
ReleaseName: env + "-" + oChartName,
ChartName: oChartName,
ChartVersion: oChartVersion,
}
outReleases = append(outReleases, r)
}

return outReleases
}

Expand Down
1 change: 1 addition & 0 deletions pkg/utils/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func Exec(cmd string) string {

output, err := exec.Command(binary, args[1:]...).CombinedOutput()
if err != nil {
log.Println("Error: command execution failed:", cmd)
log.Fatal(string(output))
}
return string(output)
Expand Down
20 changes: 18 additions & 2 deletions test/chart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,36 @@ func TestOverrideReleases_WithOverride(t *testing.T) {

releases := []utils.ReleaseSpec{rel0, rel1, rel2}

overrideReleases := utils.OverrideReleases(releases, []string{"kaa=7.1.0"})
overrideReleases := utils.OverrideReleases(releases, []string{"kaa=7.1.0"}, "test")

if !overrideReleases[2].Equals(rel2override) {
t.Errorf("Expected: true, Actual: false")
}
}

func TestOverrideReleases_WithNewOverride(t *testing.T) {
rel0 := utils.ReleaseSpec{ChartName: "cassandra", ChartVersion: "0.4.0", ReleaseName: "test-cassandra"}
rel1 := utils.ReleaseSpec{ChartName: "mariadb", ChartVersion: "0.5.4", ReleaseName: "test-mariadb"}
rel2 := utils.ReleaseSpec{ChartName: "kaa", ChartVersion: "0.1.7", ReleaseName: "test-kaa"}
rel2override := utils.ReleaseSpec{ChartName: "example", ChartVersion: "3.3.3", ReleaseName: "test-example"}

releases := []utils.ReleaseSpec{rel0, rel1, rel2}

overrideReleases := utils.OverrideReleases(releases, []string{"example=3.3.3"}, "test")

if !overrideReleases[3].Equals(rel2override) {
t.Errorf("Expected: true, Actual: false")
}
}

func TestOverrideReleases_WithoutOverride(t *testing.T) {
rel0 := utils.ReleaseSpec{ChartName: "cassandra", ChartVersion: "0.4.0", ReleaseName: "test-cassandra"}
rel1 := utils.ReleaseSpec{ChartName: "mariadb", ChartVersion: "0.5.4", ReleaseName: "test-mariadb"}
rel2 := utils.ReleaseSpec{ChartName: "kaa", ChartVersion: "0.1.7", ReleaseName: "test-kaa"}

releases := []utils.ReleaseSpec{rel0, rel1, rel2}

overrideReleases := utils.OverrideReleases(releases, []string{})
overrideReleases := utils.OverrideReleases(releases, []string{}, "test")

if !overrideReleases[0].Equals(rel0) {
t.Errorf("Expected: true, Actual: false")
Expand Down

0 comments on commit 9958369

Please sign in to comment.