Skip to content
This repository was archived by the owner on Jul 11, 2023. It is now read-only.

Commit aa1abf1

Browse files
authored
ref: use binary flag to enable use of MeshRootCertificate (#4871)
Uses a binary flag to enable the use of MeshRootCertificate. Updates the MRC id to be the MRC name. Passes vault token secret reference options to the controller, injector, and bootstrap. Signed-off-by: jaellio <[email protected]>
1 parent b7c8f61 commit aa1abf1

20 files changed

+605
-211
lines changed

charts/osm/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ The following table lists the configurable parameters of the osm chart and their
9797
| osm.featureFlags.enableEgressPolicy | bool | `true` | Enable OSM's Egress policy API. When enabled, fine grained control over Egress (external) traffic is enforced |
9898
| osm.featureFlags.enableEnvoyActiveHealthChecks | bool | `false` | Enable Envoy active health checks |
9999
| osm.featureFlags.enableIngressBackendPolicy | bool | `true` | Enables OSM's IngressBackend policy API. When enabled, OSM will use the IngressBackend API allow ingress traffic to mesh backends |
100+
| osm.featureFlags.enableMeshRootCertificate | bool | `false` | Enable the MeshRootCertificate to configure the OSM certificate provider |
100101
| osm.featureFlags.enableRetryPolicy | bool | `false` | Enable Retry Policy for automatic request retries |
101102
| osm.featureFlags.enableSnapshotCacheMode | bool | `false` | Enables SnapshotCache feature for Envoy xDS server. |
102103
| osm.featureFlags.enableWASMStats | bool | `true` | Enable extra Envoy statistics generated by a custom WASM extension |
@@ -270,7 +271,7 @@ The following table lists the configurable parameters of the osm chart and their
270271
| osm.vault.port | int | `8200` | port to use to connect to Vault |
271272
| osm.vault.protocol | string | `"http"` | protocol to use to connect to Vault |
272273
| osm.vault.role | string | `"openservicemesh"` | Vault role to be used by Open Service Mesh |
273-
| osm.vault.secret | object | `{"key":"","name":""}` | The Kubernetes secret storing the Vault token used in OSM |
274+
| osm.vault.secret | object | `{"key":"","name":""}` | The Kubernetes secret storing the Vault token used in OSM. The secret must be located in the namespace of the OSM installation |
274275
| osm.vault.secret.key | string | `""` | The Kubernetes secret key with the value bring the Vault token |
275276
| osm.vault.secret.name | string | `""` | The Kubernetes secret name storing the Vault token used in OSM |
276277
| osm.vault.token | string | `""` | token that should be used to connect to Vault |

charts/osm/templates/osm-bootstrap-deployment.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,14 @@ spec:
6161
"--osm-version", "{{ .Chart.AppVersion }}",
6262
"--ca-bundle-secret-name", "{{.Values.osm.caBundleSecretName}}",
6363
"--certificate-manager", "{{.Values.osm.certificateProvider.kind}}",
64+
"--enable-mesh-root-certificate={{.Values.osm.featureFlags.enableMeshRootCertificate}}",
6465
{{ if eq .Values.osm.certificateProvider.kind "vault" }}
6566
"--vault-host", "{{.Values.osm.vault.host}}",
6667
"--vault-port", "{{.Values.osm.vault.port}}",
6768
"--vault-protocol", "{{.Values.osm.vault.protocol}}",
6869
"--vault-token", "{{.Values.osm.vault.token}}",
70+
"--vault-token-secret-name", "{{ .Values.osm.vault.secret.name }}",
71+
"--vault-token-secret-key", "{{ .Values.osm.vault.secret.key }}",
6972
{{- end }}
7073
"--cert-manager-issuer-name", "{{.Values.osm.certmanager.issuerName}}",
7174
"--cert-manager-issuer-kind", "{{.Values.osm.certmanager.issuerKind}}",

charts/osm/templates/osm-deployment.yaml

+8-1
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,18 @@ spec:
6161
"--validator-webhook-config", "{{ include "osm.validatorWebhookConfigName" . }}",
6262
"--ca-bundle-secret-name", "{{.Values.osm.caBundleSecretName}}",
6363
"--certificate-manager", "{{.Values.osm.certificateProvider.kind}}",
64+
"--enable-mesh-root-certificate={{.Values.osm.featureFlags.enableMeshRootCertificate}}",
6465
{{ if eq .Values.osm.certificateProvider.kind "vault" }}
6566
"--vault-host", "{{ required "osm.vault.host is required when osm.certificateProvider.kind==vault" .Values.osm.vault.host }}",
6667
"--vault-port", "{{.Values.osm.vault.port}}",
6768
"--vault-protocol", "{{.Values.osm.vault.protocol}}",
68-
"--vault-token", "{{ required "osm.vault.token is required when osm.certificateProvider.kind==vault" .Values.osm.vault.token }}",
69+
{{ if and (empty .Values.osm.vault.secret.name) (empty .Values.osm.vault.secret.key) }}
70+
"--vault-token", "{{ required "osm.vault.token is required when osm.certificateProvider.kind==vault and osm.vault.secret.name and osm.vault.secret.key are empty" .Values.osm.vault.token }}",
71+
{{- end }}
72+
{{ if empty .Values.osm.vault.token }}
73+
"--vault-token-secret-name", "{{ required "osm.vault.secret.name is required when osm.certificateProvider.kind==vault and osm.vault.token is empty" .Values.osm.vault.secret.name }}",
74+
"--vault-token-secret-key", "{{ required "osm.vault.secret.key is required when osm.certificateProvider.kind==vault and osm.vault.token is empty" .Values.osm.vault.secret.key }}",
75+
{{- end }}
6976
{{- end }}
7077
"--cert-manager-issuer-name", "{{.Values.osm.certmanager.issuerName}}",
7178
"--cert-manager-issuer-kind", "{{.Values.osm.certmanager.issuerKind}}",

charts/osm/templates/osm-injector-deployment.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ spec:
5858
"--webhook-timeout", "{{.Values.osm.injector.webhookTimeoutSeconds}}",
5959
"--ca-bundle-secret-name", "{{.Values.osm.caBundleSecretName}}",
6060
"--certificate-manager", "{{.Values.osm.certificateProvider.kind}}",
61+
"--enable-mesh-root-certificate={{.Values.osm.featureFlags.enableMeshRootCertificate}}",
6162
{{ if eq .Values.osm.certificateProvider.kind "vault" }}
6263
"--vault-host", "{{.Values.osm.vault.host}}",
6364
"--vault-port", "{{.Values.osm.vault.port}}",
6465
"--vault-protocol", "{{.Values.osm.vault.protocol}}",
6566
"--vault-token", "{{.Values.osm.vault.token}}",
67+
"--vault-token-secret-name", "{{ .Values.osm.vault.secret.name }}",
68+
"--vault-token-secret-key", "{{ .Values.osm.vault.secret.key }}",
6669
{{- end }}
6770
"--cert-manager-issuer-name", "{{.Values.osm.certmanager.issuerName}}",
6871
"--cert-manager-issuer-kind", "{{.Values.osm.certmanager.issuerKind}}",

charts/osm/templates/preset-mesh-root-certificate.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{- if .Values.osm.featureFlags.enableMeshRootCertificate }}
12
apiVersion: v1
23
kind: ConfigMap
34
metadata:
@@ -42,3 +43,4 @@ data:
4243
{{- end}}
4344
}
4445
}
46+
{{- end}}

charts/osm/values.schema.json

+11-1
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,8 @@
983983
"enableIngressBackendPolicy",
984984
"enableEnvoyActiveHealthChecks",
985985
"enableSnapshotCacheMode",
986-
"enableRetryPolicy"
986+
"enableRetryPolicy",
987+
"enableMeshRootCertificate"
987988
],
988989
"properties": {
989990
"enableWASMStats": {
@@ -1048,6 +1049,15 @@
10481049
"examples": [
10491050
true
10501051
]
1052+
},
1053+
"enableMeshRootCertificate": {
1054+
"$id": "#/properties/osm/properties/featureFlags/properties/enableMeshRootCertificate",
1055+
"type": "boolean",
1056+
"title": "Enable the MeshRootCertificate",
1057+
"description": "Enable the MeshRootCertificate to configure the OSM certificate provider.",
1058+
"examples": [
1059+
false
1060+
]
10511061
}
10521062
},
10531063
"additionalProperties": false

charts/osm/values.yaml

+5-3
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ osm:
191191
token: ""
192192
# -- Vault role to be used by Open Service Mesh
193193
role: openservicemesh
194-
# -- The Kubernetes secret storing the Vault token used in OSM
194+
# -- The Kubernetes secret storing the Vault token used in OSM. The secret must be located in the namespace of the OSM installation
195195
secret:
196196
# -- The Kubernetes secret name storing the Vault token used in OSM
197197
name: ""
@@ -482,6 +482,8 @@ osm:
482482
enableSnapshotCacheMode: false
483483
# -- Enable Retry Policy for automatic request retries
484484
enableRetryPolicy: false
485+
# -- Enable the MeshRootCertificate to configure the OSM certificate provider
486+
enableMeshRootCertificate: false
485487

486488
# -- Node tolerations applied to control plane pods.
487489
# The specified tolerations allow pods to schedule onto nodes with matching taints.
@@ -547,7 +549,7 @@ osm:
547549

548550
#
549551
# -- OSM's preinstall hook parameters
550-
552+
551553
preinstall:
552554
## Affinity settings for pod assignment
553555
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
@@ -580,7 +582,7 @@ osm:
580582

581583
## Affinity settings for pod assignment
582584
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
583-
affinity:
585+
affinity:
584586
nodeAffinity:
585587
requiredDuringSchedulingIgnoredDuringExecution:
586588
nodeSelectorTerms:

cmd/cli/install_test.go

+113-9
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ import (
2828
)
2929

3030
const (
31-
testRegistrySecret = "test-registry-secret"
32-
testVaultHost = "vault.osm.svc.cluster.local"
33-
testVaultToken = "token"
34-
testChartPath = "testdata/test-chart"
35-
kubeVersionMajor = 1
36-
kubeVersionMinor = 22
37-
kubeVersionPatch = 9
31+
testRegistrySecret = "test-registry-secret"
32+
testVaultHost = "vault.osm.svc.cluster.local"
33+
testVaultToken = "token"
34+
testVaultSecretName = "secret"
35+
testVaultSecretKey = "key"
36+
testChartPath = "testdata/test-chart"
37+
kubeVersionMajor = 1
38+
kubeVersionMinor = 22
39+
kubeVersionPatch = 9
3840
)
3941

4042
func helmCapabilities() *chartutil.Capabilities {
@@ -181,7 +183,7 @@ var _ = Describe("Running the install command", func() {
181183
})
182184
})
183185

184-
Describe("with the vault cert manager", func() {
186+
Describe("with the vault cert manager using vault token", func() {
185187
var (
186188
out *bytes.Buffer
187189
store *storage.Storage
@@ -258,6 +260,87 @@ var _ = Describe("Running the install command", func() {
258260
})
259261
})
260262

263+
Describe("with the vault cert manager using token secret ref", func() {
264+
var (
265+
out *bytes.Buffer
266+
store *storage.Storage
267+
config *helm.Configuration
268+
err error
269+
)
270+
271+
BeforeEach(func() {
272+
out = new(bytes.Buffer)
273+
store = storage.Init(driver.NewMemory())
274+
if mem, ok := store.Driver.(*driver.Memory); ok {
275+
mem.SetNamespace(settings.Namespace())
276+
}
277+
278+
config = &helm.Configuration{
279+
Releases: store,
280+
KubeClient: &kubefake.PrintingKubeClient{
281+
Out: ioutil.Discard},
282+
Capabilities: helmCapabilities(),
283+
Log: func(format string, v ...interface{}) {},
284+
}
285+
286+
installCmd := getDefaultInstallCmd(out)
287+
288+
installCmd.setOptions = []string{
289+
"osm.certificateProvider.kind=vault",
290+
fmt.Sprintf("osm.vault.host=%s", testVaultHost),
291+
"osm.vault.token=",
292+
fmt.Sprintf("osm.vault.secret.name=%s", testVaultSecretName),
293+
fmt.Sprintf("osm.vault.secret.key=%s", testVaultSecretKey),
294+
}
295+
err = installCmd.run(config)
296+
})
297+
298+
It("should not error", func() {
299+
Expect(err).NotTo(HaveOccurred())
300+
})
301+
302+
It("should give a message confirming the successful install", func() {
303+
Expect(out.String()).To(Equal("OSM installed successfully in namespace [osm-system] with mesh name [osm]\n"))
304+
})
305+
306+
Context("the Helm release", func() {
307+
var (
308+
rel *release.Release
309+
err error
310+
)
311+
312+
BeforeEach(func() {
313+
rel, err = config.Releases.Get(defaultMeshName, 1)
314+
})
315+
316+
It("should not error when retrieved", func() {
317+
Expect(err).NotTo(HaveOccurred())
318+
})
319+
320+
It("should have the correct values", func() {
321+
expectedValues := getDefaultValues()
322+
valuesConfig := []string{
323+
fmt.Sprintf("osm.certificateProvider.kind=%s", "vault"),
324+
fmt.Sprintf("osm.vault.host=%s", testVaultHost),
325+
"osm.vault.token=",
326+
fmt.Sprintf("osm.vault.secret.name=%s", testVaultSecretName),
327+
fmt.Sprintf("osm.vault.secret.key=%s", testVaultSecretKey),
328+
}
329+
for _, val := range valuesConfig {
330+
// parses Helm strvals line and merges into a map
331+
err := strvals.ParseInto(val, expectedValues)
332+
Expect(err).NotTo(HaveOccurred())
333+
}
334+
335+
Expect(rel.Config).To(BeEquivalentTo(expectedValues))
336+
})
337+
338+
It("should be installed in the correct namespace", func() {
339+
Expect(rel.Namespace).To(Equal(settings.Namespace()))
340+
})
341+
})
342+
})
343+
261344
Describe("without required vault parameters", func() {
262345
var (
263346
installCmd installCmd
@@ -291,11 +374,32 @@ var _ = Describe("Running the install command", func() {
291374
Expect(err.Error()).To(ContainSubstring("osm.vault.host is required"))
292375
})
293376

294-
It("should error when token isn't set", func() {
377+
It("should error when token and token secret key are not set", func() {
378+
installCmd.setOptions = append(installCmd.setOptions,
379+
"osm.vault.host=my-host",
380+
"osm.vault.secret.name=secret",
381+
)
382+
err := installCmd.run(config)
383+
Expect(err).To(HaveOccurred())
384+
Expect(err.Error()).To(ContainSubstring("osm.vault.secret.key is required"))
385+
})
386+
387+
It("should error when token and token secret name are not set", func() {
388+
installCmd.setOptions = append(installCmd.setOptions,
389+
"osm.vault.host=my-host",
390+
"osm.vault.secret.key=key",
391+
)
392+
err := installCmd.run(config)
393+
Expect(err).To(HaveOccurred())
394+
Expect(err.Error()).To(ContainSubstring("osm.vault.secret.name is required"))
395+
})
396+
397+
It("should error when token and token secret name and key are not set", func() {
295398
installCmd.setOptions = append(installCmd.setOptions,
296399
"osm.vault.host=my-host",
297400
)
298401
err := installCmd.run(config)
402+
Expect(err).To(HaveOccurred())
299403
Expect(err.Error()).To(ContainSubstring("osm.vault.token is required"))
300404
})
301405
})

cmd/osm-bootstrap/osm-bootstrap.go

+27-13
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"k8s.io/kubectl/pkg/util"
2929

3030
configv1alpha2 "github.com/openservicemesh/osm/pkg/apis/config/v1alpha2"
31+
"github.com/openservicemesh/osm/pkg/certificate"
3132
configClientset "github.com/openservicemesh/osm/pkg/gen/client/config/clientset/versioned"
3233
"github.com/openservicemesh/osm/pkg/health"
3334

@@ -63,7 +64,8 @@ var (
6364
meshName string
6465
osmVersion string
6566

66-
certProviderKind string
67+
certProviderKind string
68+
enableMeshRootCertificate bool
6769

6870
tresorOptions providers.TresorOptions
6971
vaultOptions providers.VaultOptions
@@ -94,6 +96,7 @@ func init() {
9496

9597
// Generic certificate manager/provider options
9698
flags.StringVar(&certProviderKind, "certificate-manager", providers.TresorKind.String(), fmt.Sprintf("Certificate manager, one of [%v]", providers.ValidCertificateProviders))
99+
flags.BoolVar(&enableMeshRootCertificate, "enable-mesh-root-certificate", false, "Enable unsupported MeshRootCertificate to create the OSM Certificate Manager")
97100
flags.StringVar(&caBundleSecretName, "ca-bundle-secret-name", "", "Name of the Kubernetes Secret for the OSM CA bundle")
98101

99102
// Vault certificate manager/provider options
@@ -102,6 +105,8 @@ func init() {
102105
flags.StringVar(&vaultOptions.VaultToken, "vault-token", "", "Secret token for the the Hashi Vault")
103106
flags.StringVar(&vaultOptions.VaultRole, "vault-role", "openservicemesh", "Name of the Vault role dedicated to Open Service Mesh")
104107
flags.IntVar(&vaultOptions.VaultPort, "vault-port", 8200, "Port of the Hashi Vault")
108+
flags.StringVar(&vaultOptions.VaultTokenSecretName, "vault-token-secret-name", "", "Name of the secret storing the Vault token used in OSM")
109+
flags.StringVar(&vaultOptions.VaultTokenSecretKey, "vault-token-secret-key", "", "Key for the vault token used in OSM")
105110

106111
// Cert-manager certificate manager/provider options
107112
flags.StringVar(&certManagerOptions.IssuerName, "cert-manager-issuer-name", "osm-ca", "cert-manager issuer name")
@@ -122,6 +127,7 @@ func getCertOptions() (providers.Options, error) {
122127
tresorOptions.SecretName = caBundleSecretName
123128
return tresorOptions, nil
124129
case providers.VaultKind:
130+
vaultOptions.VaultTokenSecretNamespace = osmNamespace
125131
return vaultOptions, nil
126132
case providers.CertManagerKind:
127133
return certManagerOptions, nil
@@ -171,10 +177,12 @@ func main() {
171177
return
172178
}
173179

174-
err = bootstrap.ensureMeshRootCertificate()
175-
if err != nil {
176-
log.Fatal().Err(err).Msgf("Error setting up default MeshRootCertificate %s from ConfigMap %s", meshRootCertificateName, presetMeshRootCertificateName)
177-
return
180+
if enableMeshRootCertificate {
181+
err = bootstrap.ensureMeshRootCertificate()
182+
if err != nil {
183+
log.Fatal().Err(err).Msgf("Error setting up default MeshRootCertificate %s from ConfigMap %s", meshRootCertificateName, presetMeshRootCertificateName)
184+
return
185+
}
178186
}
179187

180188
err = bootstrap.initiatilizeKubernetesEventsRecorder()
@@ -214,10 +222,19 @@ func main() {
214222
log.Fatal().Err(err).Msg("Error getting certificate options")
215223
}
216224

217-
certManager, err := providers.NewCertificateManager(ctx, kubeClient, kubeConfig, cfg, osmNamespace, certOpts, msgBroker, informerCollection, 5*time.Second)
218-
if err != nil {
219-
events.GenericEventRecorder().FatalEvent(err, events.InvalidCertificateManager,
220-
"Error initializing certificate manager of kind %s", certProviderKind)
225+
var certManager *certificate.Manager
226+
if enableMeshRootCertificate {
227+
certManager, err = providers.NewCertificateManagerFromMRC(ctx, kubeClient, kubeConfig, cfg, osmNamespace, certOpts, msgBroker, informerCollection, 5*time.Second)
228+
if err != nil {
229+
events.GenericEventRecorder().FatalEvent(err, events.InvalidCertificateManager,
230+
"Error initializing certificate manager of kind %s from MRC", certProviderKind)
231+
}
232+
} else {
233+
certManager, err = providers.NewCertificateManager(ctx, kubeClient, kubeConfig, cfg, osmNamespace, certOpts, msgBroker, 5*time.Second)
234+
if err != nil {
235+
events.GenericEventRecorder().FatalEvent(err, events.InvalidCertificateManager,
236+
"Error initializing certificate manager of kind %s", certProviderKind)
237+
}
221238
}
222239

223240
// Initialize the crd conversion webhook server to support the conversion of OSM's CRDs
@@ -414,7 +431,7 @@ func (b *bootstrap) createMeshRootCertificate() error {
414431

415432
_, err = b.configClient.ConfigV1alpha2().MeshRootCertificates(b.namespace).UpdateStatus(context.Background(), createdMRC, metav1.UpdateOptions{})
416433
if apierrors.IsAlreadyExists(err) {
417-
log.Info().Msgf("MeshRootCertificate statys already exists in %s. Skip creating.", b.namespace)
434+
log.Info().Msgf("MeshRootCertificate status already exists in %s. Skip creating.", b.namespace)
418435
}
419436

420437
if err != nil {
@@ -440,9 +457,6 @@ func buildMeshRootCertificate(presetMeshRootCertificateConfigMap *corev1.ConfigM
440457
},
441458
ObjectMeta: metav1.ObjectMeta{
442459
Name: meshRootCertificateName,
443-
Annotations: map[string]string{
444-
constants.MRCVersionAnnotation: "0",
445-
},
446460
},
447461
Spec: presetMeshRootCertificateSpec,
448462
}

0 commit comments

Comments
 (0)