Skip to content

Commit

Permalink
cli: Add enforce single mesh functionality to osm install (openservic…
Browse files Browse the repository at this point in the history
  • Loading branch information
ksubrmnn authored Oct 19, 2020
1 parent fde0ef6 commit 8e22bef
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 1 deletion.
2 changes: 1 addition & 1 deletion charts/osm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ A Helm chart to install the OSM control plane on Kubernetes
| OpenServiceMesh.vault.protocol | string | `"http"` | |
| OpenServiceMesh.vault.role | string | `"openservicemesh"` | |
| OpenServiceMesh.vault.token | string | `nil` | |

| OpenServiceMesh.enforceSingleMesh | bool | `"false"` | |
1 change: 1 addition & 0 deletions charts/osm/templates/osm-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ metadata:
labels:
app: osm-controller
meshName: {{ .Values.OpenServiceMesh.meshName }}
{{ if .Values.OpenServiceMesh.enforceSingleMesh }}enforceSingleMesh: "true"{{ end }}
spec:
replicas: {{ .Values.OpenServiceMesh.replicaCount }}
selector:
Expand Down
1 change: 1 addition & 0 deletions charts/osm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ OpenServiceMesh:
meshName: osm
useHTTPSIngress: false
envoyLogLevel: error
enforceSingleMesh: false

# Set deployJaeger to true to deploy a Jaeger cluster in the
# namespace where OSM resides.
Expand Down
26 changes: 26 additions & 0 deletions cmd/cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ type installCmd struct {

// Toggle this to enable/disable the automatic deployment of Jaeger
deployJaeger bool

// Toggle this to enforce only one mesh in this cluster
enforceSingleMesh bool
}

func newInstallCmd(config *helm.Configuration, out io.Writer) *cobra.Command {
Expand Down Expand Up @@ -152,6 +155,7 @@ func newInstallCmd(config *helm.Configuration, out io.Writer) *cobra.Command {
f.StringVar(&inst.meshName, "mesh-name", defaultMeshName, "name for the new control plane instance")
f.BoolVar(&inst.deployJaeger, "deploy-jaeger", true, "Deploy Jaeger in the namespace of the OSM controller")
f.StringVar(&inst.envoyLogLevel, "envoy-log-level", "error", "Envoy log level is used to specify the level of logs collected from envoy and needs to be one of these (trace, debug, info, warning, warn, error, critical, off)")
f.BoolVar(&inst.enforceSingleMesh, "enforce-single-mesh", false, "Enforce only deploying one mesh in the cluster")

return cmd
}
Expand Down Expand Up @@ -218,6 +222,7 @@ func (i *installCmd) resolveValues() (map[string]interface{}, error) {
fmt.Sprintf("OpenServiceMesh.enableEgress=%t", i.enableEgress),
fmt.Sprintf("OpenServiceMesh.deployJaeger=%t", i.deployJaeger),
fmt.Sprintf("OpenServiceMesh.envoyLogLevel=%s", strings.ToLower(i.envoyLogLevel)),
fmt.Sprintf("OpenServiceMesh.enforceSingleMesh=%t", i.enforceSingleMesh),
}

if i.containerRegistrySecret != "" {
Expand Down Expand Up @@ -293,6 +298,27 @@ func (i *installCmd) validateOptions() error {
return err
}

list, err = getControllerDeployments(i.clientSet)
if err != nil {
return err
}

// Check if single mesh cluster is already specified
for _, deployment := range list.Items {
singleMeshEnforced := deployment.ObjectMeta.Labels["enforceSingleMesh"] == "true"
name := deployment.ObjectMeta.Labels["meshName"]
if singleMeshEnforced {
return errors.Errorf("Cannot install mesh [%s]. Existing mesh [%s] enforces single mesh cluster.", i.meshName, name)
}
}

// Enforce single mesh cluster if needed
if i.enforceSingleMesh {
if len(list.Items) != 0 {
return errors.Errorf("Meshes already exist in cluster. Cannot enforce single mesh cluster. ")
}
}

return nil
}

Expand Down
159 changes: 159 additions & 0 deletions cmd/cli/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import (
"bytes"
"context"
"io/ioutil"
"strings"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/assert"
helm "helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chartutil"
kubefake "helm.sh/helm/v3/pkg/kube/fake"
Expand Down Expand Up @@ -143,6 +146,7 @@ var _ = Describe("Running the install command", func() {
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})

Expand Down Expand Up @@ -260,6 +264,7 @@ var _ = Describe("Running the install command", func() {
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})

Expand Down Expand Up @@ -385,6 +390,7 @@ var _ = Describe("Running the install command", func() {
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})

Expand Down Expand Up @@ -551,6 +557,7 @@ var _ = Describe("Running the install command", func() {
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})

Expand Down Expand Up @@ -819,6 +826,7 @@ var _ = Describe("Resolving values for install command with vault parameters", f
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})
})
Expand Down Expand Up @@ -899,6 +907,7 @@ var _ = Describe("Ensure that grafana is disabled when flag is set to false", fu
"enableGrafana": false,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})

Expand Down Expand Up @@ -980,6 +989,7 @@ var _ = Describe("Ensure that grafana is enabled when flag is set to true", func
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})

Expand Down Expand Up @@ -1061,6 +1071,7 @@ var _ = Describe("Ensure that prometheus is disabled when flag is set to false",
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})
})
Expand Down Expand Up @@ -1141,6 +1152,7 @@ var _ = Describe("Resolving values for install command with cert-manager paramet
"enableGrafana": true,
"deployJaeger": false,
"envoyLogLevel": testEnvoyLogLevel,
"enforceSingleMesh": false,
}}))
})
})
Expand Down Expand Up @@ -1262,6 +1274,153 @@ var _ = Describe("Resolving values for service cert validity duration", func() {
})
})

func TestEnforceSingleMesh(t *testing.T) {
assert := assert.New(t)

out := new(bytes.Buffer)
store := storage.Init(driver.NewMemory())
if mem, ok := store.Driver.(*driver.Memory); ok {
mem.SetNamespace(settings.Namespace())
}

config := &helm.Configuration{
Releases: store,
KubeClient: &kubefake.PrintingKubeClient{
Out: ioutil.Discard,
},
Capabilities: chartutil.DefaultCapabilities,
Log: func(format string, v ...interface{}) {},
}

fakeClientSet := fake.NewSimpleClientset()

install := &installCmd{
out: out,
chartPath: "testdata/test-chart",
containerRegistry: testRegistry,
osmImageTag: testOsmImageTag,
osmImagePullPolicy: defaultOsmImagePullPolicy,
certificateManager: "tresor",
serviceCertValidityDuration: "24h",
prometheusRetentionTime: testRetentionTime,
meshName: defaultMeshName,
enableEgress: true,
enablePrometheus: true,
enableGrafana: true,
clientSet: fakeClientSet,
envoyLogLevel: testEnvoyLogLevel,
enforceSingleMesh: true,
}

err := install.run(config)
assert.Nil(err)
assert.Equal(out.String(), "OSM installed successfully in namespace [osm-system] with mesh name [osm]\n")
}

func TestEnforceSingleMeshRejectsNewMesh(t *testing.T) {
assert := assert.New(t)

out := new(bytes.Buffer)
store := storage.Init(driver.NewMemory())
if mem, ok := store.Driver.(*driver.Memory); ok {
mem.SetNamespace(settings.Namespace())
}

config := &helm.Configuration{
Releases: store,
KubeClient: &kubefake.PrintingKubeClient{
Out: ioutil.Discard,
},
Capabilities: chartutil.DefaultCapabilities,
Log: func(format string, v ...interface{}) {},
}

fakeClientSet := fake.NewSimpleClientset()

labelMap := make(map[string]string)
labelMap["meshName"] = defaultMeshName
labelMap["app"] = constants.OSMControllerName
labelMap["enforceSingleMesh"] = "true"

deploymentSpec := &v1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: constants.OSMControllerName,
Namespace: settings.Namespace() + "-existing",
Labels: labelMap,
},
}
_, err := fakeClientSet.AppsV1().Deployments(settings.Namespace()+"-existing").Create(context.TODO(), deploymentSpec, metav1.CreateOptions{})
assert.Nil(err)

install := &installCmd{
out: out,
chartPath: "testdata/test-chart",
containerRegistry: testRegistry,
osmImageTag: testOsmImageTag,
osmImagePullPolicy: defaultOsmImagePullPolicy,
certificateManager: "tresor",
serviceCertValidityDuration: "24h",
prometheusRetentionTime: testRetentionTime,
meshName: defaultMeshName + "-2",
enableEgress: true,
enablePrometheus: true,
enableGrafana: true,
clientSet: fakeClientSet,
envoyLogLevel: testEnvoyLogLevel,
}

err = install.run(config)
assert.NotNil(err)
assert.True(strings.Contains(err.Error(), "Cannot install mesh [osm-2]. Existing mesh [osm] enforces single mesh cluster"))
}

func TestEnforceSingleMeshWithExistingMesh(t *testing.T) {
assert := assert.New(t)

out := new(bytes.Buffer)
store := storage.Init(driver.NewMemory())
if mem, ok := store.Driver.(*driver.Memory); ok {
mem.SetNamespace(settings.Namespace())
}

config := &helm.Configuration{
Releases: store,
KubeClient: &kubefake.PrintingKubeClient{
Out: ioutil.Discard,
},
Capabilities: chartutil.DefaultCapabilities,
Log: func(format string, v ...interface{}) {},
}

fakeClientSet := fake.NewSimpleClientset()

deploymentSpec := createDeploymentSpec(settings.Namespace()+"-existing", defaultMeshName)
_, err := fakeClientSet.AppsV1().Deployments(settings.Namespace()+"-existing").Create(context.TODO(), deploymentSpec, metav1.CreateOptions{})
assert.Nil(err)

install := &installCmd{
out: out,
chartPath: "testdata/test-chart",
containerRegistry: testRegistry,
osmImageTag: testOsmImageTag,
osmImagePullPolicy: defaultOsmImagePullPolicy,
certificateManager: "tresor",
serviceCertValidityDuration: "24h",
prometheusRetentionTime: testRetentionTime,
meshName: defaultMeshName + "-2",
enableEgress: true,
enablePrometheus: true,
enableGrafana: true,
clientSet: fakeClientSet,
envoyLogLevel: testEnvoyLogLevel,
enforceSingleMesh: true,
}

err = install.run(config)
assert.NotNil(err)
assert.True(strings.Contains(err.Error(), "Meshes already exist in cluster. Cannot enforce single mesh cluster"))
}

func createDeploymentSpec(namespace, meshName string) *v1.Deployment {
labelMap := make(map[string]string)
if meshName != "" {
Expand Down

0 comments on commit 8e22bef

Please sign in to comment.