Install MWC and VWC During Installation (#2806)

* Update helm charts to include webhooks config and TLS secret
* Update the webhooks to read the secret cert and key
* Update webhooks to not recreate config on restart
* Ensure upgrade preserve existing secrets
* Revert the change to rename the webhook configs

The renaming change breaks upgrade, where the new webhook configs conflict with
the existing ones. The older resources  aren't deleted during upgrade because
they are dynamically created.

* Make the secret volume read-only
* Remove unnecessary exported getter functions
* Remove obsolete mwc and vwc templates

Signed-off-by: Ivan Sim <ivan@buoyant.io>
This commit is contained in:
Ivan Sim 2019-05-20 12:43:50 -07:00 committed by GitHub
parent 7973715ee4
commit 5a5f8bbfe8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 790 additions and 312 deletions

View File

@ -41,4 +41,36 @@ apiVersion: v1
metadata:
name: linkerd-proxy-injector
namespace: {{.Namespace}}
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: {{ .Namespace }}
labels:
{{ .ControllerComponentLabel }}: proxy-injector
annotations:
{{ .CreatedByAnnotation }}: {{ .CliVersion }}
type: Opaque
data:
crt.pem: {{ b64enc .ProxyInjector.CrtPEM }}
key.pem: {{ b64enc .ProxyInjector.KeyPEM }}
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: {{ .Namespace }}
path: "/"
caBundle: {{ b64enc .ProxyInjector.CrtPEM }}
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
{{end -}}

View File

@ -32,7 +32,6 @@ spec:
imagePullPolicy: {{.ImagePullPolicy}}
args:
- "proxy-injector"
- "-controller-namespace={{.Namespace}}"
- "-log-level={{.ControllerLogLevel}}"
ports:
- name: proxy-injector
@ -40,6 +39,9 @@ spec:
volumeMounts:
- name: config
mountPath: /var/run/linkerd/config
- name: tls
mountPath: /var/run/linkerd/tls
readOnly: true
livenessProbe:
httpGet:
path: /ping
@ -59,6 +61,9 @@ spec:
- name: config
configMap:
name: linkerd-config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
---
kind: Service
apiVersion: v1

View File

@ -35,4 +35,36 @@ apiVersion: v1
metadata:
name: linkerd-sp-validator
namespace: {{.Namespace}}
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: {{ .Namespace }}
labels:
{{ .ControllerComponentLabel }}: sp-validator
annotations:
{{ .CreatedByAnnotation }}: {{ .CliVersion }}
type: Opaque
data:
crt.pem: {{ b64enc .ProfileValidator.CrtPEM }}
key.pem: {{ b64enc .ProfileValidator.KeyPEM }}
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: {{ .Namespace }}
path: "/"
caBundle: {{ b64enc .ProfileValidator.CrtPEM }}
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
{{end -}}

View File

@ -50,11 +50,14 @@ spec:
imagePullPolicy: {{.ImagePullPolicy}}
args:
- "sp-validator"
- "-controller-namespace={{.Namespace}}"
- "-log-level={{.ControllerLogLevel}}"
ports:
- name: sp-validator
containerPort: 8443
volumeMounts:
- name: tls
mountPath: /var/run/linkerd/tls
readOnly: true
livenessProbe:
httpGet:
path: /ping
@ -71,7 +74,7 @@ spec:
securityContext:
runAsUser: {{.ControllerUID}}
volumes:
- name: config
configMap:
name: linkerd-config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
{{end -}}

View File

@ -68,7 +68,9 @@ type (
TapResources,
WebResources *resources
Identity *installIdentityValues
Identity *installIdentityValues
ProxyInjector *proxyInjectorValues
ProfileValidator *profileValidatorValues
}
configJSONs struct{ Global, Proxy, Install string }
@ -96,6 +98,18 @@ type (
CrtExpiryAnnotation string
}
proxyInjectorValues struct {
*tlsValues
}
profileValidatorValues struct {
*tlsValues
}
tlsValues struct {
KeyPEM, CrtPEM string
}
// installOptions holds values for command line flags that apply to the install
// command. All fields in this struct should have corresponding flags added in
// the newCmdInstall func later in this file. It also embeds proxyConfigOptions
@ -115,8 +129,9 @@ type (
recordedFlags []*pb.Install_Flag
// A function pointer that can be overridden for tests
generateUUID func() string
// function pointers that can be overridden for tests
generateUUID func() string
generateWebhookTLS func(webhook string) (*tlsValues, error)
}
installIdentityOptions struct {
@ -188,6 +203,18 @@ func newInstallOptionsWithDefaults() *installOptions {
}
return id.String()
},
generateWebhookTLS: func(webhook string) (*tlsValues, error) {
root, err := tls.GenerateRootCAWithDefaults(webhookCommonName(webhook))
if err != nil {
return nil, fmt.Errorf("failed to generate root certificate for control plane CA: %s", err)
}
return &tlsValues{
KeyPEM: root.Cred.EncodePrivateKeyPEM(),
CrtPEM: root.Cred.Crt.EncodeCertificatePEM(),
}, nil
},
}
}
@ -338,6 +365,19 @@ func (options *installOptions) validateAndBuild(stage string, flags *pflag.FlagS
return nil, nil, err
}
values.Identity = identityValues
proxyInjectorTLS, err := options.generateWebhookTLS(k8s.ProxyInjectorWebhookServiceName)
if err != nil {
return nil, nil, err
}
values.ProxyInjector = &proxyInjectorValues{proxyInjectorTLS}
profileValidatorTLS, err := options.generateWebhookTLS(k8s.SPValidatorWebhookServiceName)
if err != nil {
return nil, nil, err
}
values.ProfileValidator = &profileValidatorValues{profileValidatorTLS}
values.stage = stage
return values, configs, nil
@ -963,3 +1003,24 @@ func (idvals *installIdentityValues) toIdentityContext() *pb.IdentityContext {
ClockSkewAllowance: ptypes.DurationProto(csa),
}
}
func webhookCommonName(webhook string) string {
return fmt.Sprintf("%s.%s.svc", webhook, controlPlaneNamespace)
}
func webhookSecretName(webhook string) string {
return fmt.Sprintf("%s-tls", webhook)
}
func verifyWebhookTLS(value *tlsValues, webhook string) error {
crt, err := tls.DecodePEMCrt(value.CrtPEM)
if err != nil {
return err
}
roots := crt.CertPool()
if err := crt.Verify(roots, webhookCommonName(webhook)); err != nil {
return err
}
return nil
}

View File

@ -7,6 +7,7 @@ import (
"testing"
"github.com/linkerd/linkerd2/controller/gen/config"
"github.com/linkerd/linkerd2/pkg/k8s"
)
func TestRender(t *testing.T) {
@ -57,6 +58,18 @@ func TestRender(t *testing.T) {
},
ControllerReplicas: 1,
Identity: defaultValues.Identity,
ProxyInjector: &proxyInjectorValues{
&tlsValues{
KeyPEM: "proxy injector key",
CrtPEM: "proxy injector crt",
},
},
ProfileValidator: &profileValidatorValues{
&tlsValues{
KeyPEM: "profile validator key",
CrtPEM: "profile validator crt",
},
},
}
haOptions := testInstallOptions()
@ -118,6 +131,7 @@ func testInstallOptions() *installOptions {
o.generateUUID = func() string {
return "deaab91a-f4ab-448a-b7d1-c832a2fa0a60"
}
o.generateWebhookTLS = fakeGenerateWebhookTLS
o.identityOptions.crtPEMFile = filepath.Join("testdata", "crt.pem")
o.identityOptions.keyPEMFile = filepath.Join("testdata", "key.pem")
o.identityOptions.trustPEMFile = filepath.Join("testdata", "trust-anchors.pem")
@ -182,3 +196,19 @@ func TestValidate(t *testing.T) {
}
})
}
func fakeGenerateWebhookTLS(webhook string) (*tlsValues, error) {
switch webhook {
case k8s.ProxyInjectorWebhookServiceName:
return &tlsValues{
KeyPEM: "proxy injector key",
CrtPEM: "proxy injector crt",
}, nil
case k8s.SPValidatorWebhookServiceName:
return &tlsValues{
KeyPEM: "profile validator key",
CrtPEM: "profile validator crt",
}, nil
}
return nil, nil
}

View File

@ -282,6 +282,38 @@ metadata:
name: linkerd-proxy-injector
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: proxy-injector
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJveHkgaW5qZWN0b3IgY3J0
key.pem: cHJveHkgaW5qZWN0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: linkerd
path: "/"
caBundle: cHJveHkgaW5qZWN0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
---
###
### Service Profile Validator RBAC
###
@ -318,6 +350,38 @@ metadata:
name: linkerd-sp-validator
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: sp-validator
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
key.pem: cHJvZmlsZSB2YWxpZGF0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: linkerd
path: "/"
caBundle: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
---
###
### Tap RBAC
###

View File

@ -1273,7 +1273,6 @@ spec:
containers:
- args:
- proxy-injector
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1297,6 +1296,9 @@ spec:
volumeMounts:
- mountPath: /var/run/linkerd/config
name: config
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1414,6 +1416,9 @@ spec:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity
@ -1490,7 +1495,6 @@ spec:
containers:
- args:
- sp-validator
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1511,6 +1515,10 @@ spec:
resources: {}
securityContext:
runAsUser: 2103
volumeMounts:
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1625,9 +1633,9 @@ spec:
terminationMessagePolicy: FallbackToLogsOnError
serviceAccountName: linkerd-sp-validator
volumes:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity

View File

@ -282,6 +282,38 @@ metadata:
name: linkerd-proxy-injector
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: proxy-injector
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJveHkgaW5qZWN0b3IgY3J0
key.pem: cHJveHkgaW5qZWN0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: linkerd
path: "/"
caBundle: cHJveHkgaW5qZWN0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
---
###
### Service Profile Validator RBAC
###
@ -318,6 +350,38 @@ metadata:
name: linkerd-sp-validator
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: sp-validator
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
key.pem: cHJvZmlsZSB2YWxpZGF0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: linkerd
path: "/"
caBundle: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
---
###
### Tap RBAC
###
@ -1630,7 +1694,6 @@ spec:
containers:
- args:
- proxy-injector
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1654,6 +1717,9 @@ spec:
volumeMounts:
- mountPath: /var/run/linkerd/config
name: config
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1771,6 +1837,9 @@ spec:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity
@ -1847,7 +1916,6 @@ spec:
containers:
- args:
- sp-validator
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1868,6 +1936,10 @@ spec:
resources: {}
securityContext:
runAsUser: 2103
volumeMounts:
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1982,9 +2054,9 @@ spec:
terminationMessagePolicy: FallbackToLogsOnError
serviceAccountName: linkerd-sp-validator
volumes:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity

View File

@ -282,6 +282,38 @@ metadata:
name: linkerd-proxy-injector
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: proxy-injector
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJveHkgaW5qZWN0b3IgY3J0
key.pem: cHJveHkgaW5qZWN0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: linkerd
path: "/"
caBundle: cHJveHkgaW5qZWN0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
---
###
### Service Profile Validator RBAC
###
@ -318,6 +350,38 @@ metadata:
name: linkerd-sp-validator
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: sp-validator
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
key.pem: cHJvZmlsZSB2YWxpZGF0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: linkerd
path: "/"
caBundle: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
---
###
### Tap RBAC
###
@ -1663,7 +1727,6 @@ spec:
containers:
- args:
- proxy-injector
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1690,6 +1753,9 @@ spec:
volumeMounts:
- mountPath: /var/run/linkerd/config
name: config
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1810,6 +1876,9 @@ spec:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity
@ -1886,7 +1955,6 @@ spec:
containers:
- args:
- sp-validator
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1910,6 +1978,10 @@ spec:
memory: 50Mi
securityContext:
runAsUser: 2103
volumeMounts:
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -2027,9 +2099,9 @@ spec:
terminationMessagePolicy: FallbackToLogsOnError
serviceAccountName: linkerd-sp-validator
volumes:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity

View File

@ -282,6 +282,38 @@ metadata:
name: linkerd-proxy-injector
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: proxy-injector
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJveHkgaW5qZWN0b3IgY3J0
key.pem: cHJveHkgaW5qZWN0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: linkerd
path: "/"
caBundle: cHJveHkgaW5qZWN0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
---
###
### Service Profile Validator RBAC
###
@ -318,6 +350,38 @@ metadata:
name: linkerd-sp-validator
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: sp-validator
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
key.pem: cHJvZmlsZSB2YWxpZGF0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: linkerd
path: "/"
caBundle: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
---
###
### Tap RBAC
###
@ -1663,7 +1727,6 @@ spec:
containers:
- args:
- proxy-injector
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1690,6 +1753,9 @@ spec:
volumeMounts:
- mountPath: /var/run/linkerd/config
name: config
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1810,6 +1876,9 @@ spec:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity
@ -1886,7 +1955,6 @@ spec:
containers:
- args:
- sp-validator
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1910,6 +1978,10 @@ spec:
memory: 50Mi
securityContext:
runAsUser: 2103
volumeMounts:
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -2027,9 +2099,9 @@ spec:
terminationMessagePolicy: FallbackToLogsOnError
serviceAccountName: linkerd-sp-validator
volumes:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity

View File

@ -282,6 +282,38 @@ metadata:
name: linkerd-proxy-injector
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: proxy-injector
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJveHkgaW5qZWN0b3IgY3J0
key.pem: cHJveHkgaW5qZWN0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: linkerd
path: "/"
caBundle: cHJveHkgaW5qZWN0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
---
###
### Service Profile Validator RBAC
###
@ -318,6 +350,38 @@ metadata:
name: linkerd-sp-validator
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: sp-validator
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
key.pem: cHJvZmlsZSB2YWxpZGF0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: linkerd
path: "/"
caBundle: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
---
###
### Tap RBAC
###
@ -1480,7 +1544,6 @@ spec:
containers:
- args:
- proxy-injector
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1504,6 +1567,9 @@ spec:
volumeMounts:
- mountPath: /var/run/linkerd/config
name: config
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1591,6 +1657,9 @@ spec:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity
@ -1667,7 +1736,6 @@ spec:
containers:
- args:
- sp-validator
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:install-control-plane-version
imagePullPolicy: IfNotPresent
@ -1688,6 +1756,10 @@ spec:
resources: {}
securityContext:
runAsUser: 2103
volumeMounts:
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1772,9 +1844,9 @@ spec:
name: linkerd-identity-end-entity
serviceAccountName: linkerd-sp-validator
volumes:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity

View File

@ -282,6 +282,38 @@ metadata:
name: linkerd-proxy-injector
namespace: Namespace
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: Namespace
labels:
ControllerComponentLabel: proxy-injector
annotations:
CreatedByAnnotation: CliVersion
type: Opaque
data:
crt.pem: cHJveHkgaW5qZWN0b3IgY3J0
key.pem: cHJveHkgaW5qZWN0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: Namespace
path: "/"
caBundle: cHJveHkgaW5qZWN0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
---
###
### Service Profile Validator RBAC
###
@ -318,6 +350,38 @@ metadata:
name: linkerd-sp-validator
namespace: Namespace
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: Namespace
labels:
ControllerComponentLabel: sp-validator
annotations:
CreatedByAnnotation: CliVersion
type: Opaque
data:
crt.pem: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
key.pem: cHJvZmlsZSB2YWxpZGF0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: Namespace
path: "/"
caBundle: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
---
###
### Tap RBAC
###
@ -1456,7 +1520,6 @@ spec:
containers:
- args:
- proxy-injector
- -controller-namespace=Namespace
- -log-level=ControllerLogLevel
image: ControllerImage
imagePullPolicy: ImagePullPolicy
@ -1480,6 +1543,9 @@ spec:
volumeMounts:
- mountPath: /var/run/linkerd/config
name: config
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1564,6 +1630,9 @@ spec:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
status: {}
---
kind: Service
@ -1638,7 +1707,6 @@ spec:
containers:
- args:
- sp-validator
- -controller-namespace=Namespace
- -log-level=ControllerLogLevel
image: ControllerImage
imagePullPolicy: ImagePullPolicy
@ -1659,6 +1727,10 @@ spec:
resources: {}
securityContext:
runAsUser: 2103
volumeMounts:
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1740,9 +1812,9 @@ spec:
terminationMessagePolicy: FallbackToLogsOnError
serviceAccountName: linkerd-sp-validator
volumes:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
status: {}
---
###

View File

@ -282,6 +282,38 @@ metadata:
name: linkerd-proxy-injector
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-proxy-injector-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: proxy-injector
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJveHkgaW5qZWN0b3IgY3J0
key.pem: cHJveHkgaW5qZWN0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: linkerd-proxy-injector-webhook-config
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: linkerd
path: "/"
caBundle: cHJveHkgaW5qZWN0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
---
###
### Service Profile Validator RBAC
###
@ -318,6 +350,38 @@ metadata:
name: linkerd-sp-validator
namespace: linkerd
---
kind: Secret
apiVersion: v1
metadata:
name: linkerd-sp-validator-tls
namespace: linkerd
labels:
linkerd.io/control-plane-component: sp-validator
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
type: Opaque
data:
crt.pem: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
key.pem: cHJvZmlsZSB2YWxpZGF0b3Iga2V5
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: linkerd-sp-validator-webhook-config
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: linkerd
path: "/"
caBundle: cHJvZmlsZSB2YWxpZGF0b3IgY3J0
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]
---
###
### Tap RBAC
###
@ -1635,7 +1699,6 @@ spec:
containers:
- args:
- proxy-injector
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:UPGRADE-CONTROL-PLANE-VERSION
imagePullPolicy: IfNotPresent
@ -1659,6 +1722,9 @@ spec:
volumeMounts:
- mountPath: /var/run/linkerd/config
name: config
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1777,6 +1843,9 @@ spec:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-proxy-injector-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity
@ -1853,7 +1922,6 @@ spec:
containers:
- args:
- sp-validator
- -controller-namespace=linkerd
- -log-level=info
image: gcr.io/linkerd-io/controller:UPGRADE-CONTROL-PLANE-VERSION
imagePullPolicy: IfNotPresent
@ -1874,6 +1942,10 @@ spec:
resources: {}
securityContext:
runAsUser: 2103
volumeMounts:
- mountPath: /var/run/linkerd/tls
name: tls
readOnly: true
- env:
- name: LINKERD2_PROXY_LOG
value: warn,linkerd2_proxy=info
@ -1989,9 +2061,9 @@ spec:
terminationMessagePolicy: FallbackToLogsOnError
serviceAccountName: linkerd-sp-validator
volumes:
- configMap:
name: linkerd-config
name: config
- name: tls
secret:
secretName: linkerd-sp-validator-tls
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity

View File

@ -13,6 +13,7 @@ import (
"github.com/linkerd/linkerd2/pkg/version"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
@ -27,12 +28,15 @@ const (
type upgradeOptions struct {
manifests string
*installOptions
verifyTLS func(tls *tlsValues, service string) error
}
func newUpgradeOptionsWithDefaults() *upgradeOptions {
return &upgradeOptions{
manifests: "",
installOptions: newInstallOptionsWithDefaults(),
verifyTLS: verifyWebhookTLS,
}
}
@ -236,6 +240,21 @@ func (options *upgradeOptions) validateAndBuild(stage string, k kubernetes.Inter
return nil, nil, fmt.Errorf("could not build install configuration: %s", err)
}
values.Identity = identity
// if exist, re-use the proxy injector and profile validator TLS secrets,
// otherwise, generate new ones.
proxyInjectorTLS, err := fetchWebhookTLS(k, k8s.ProxyInjectorWebhookServiceName, options)
if err != nil {
return nil, nil, fmt.Errorf("could not fetch existing proxy injector secret: %s", err)
}
values.ProxyInjector = &proxyInjectorValues{proxyInjectorTLS}
profileValidatorTLS, err := fetchWebhookTLS(k, k8s.SPValidatorWebhookServiceName, options)
if err != nil {
return nil, nil, fmt.Errorf("could not fetch existing profile validator secret: %s", err)
}
values.ProfileValidator = &profileValidatorValues{profileValidatorTLS}
values.stage = stage
return values, configs, nil
@ -281,6 +300,36 @@ func fetchConfigs(k kubernetes.Interface) (*pb.All, error) {
return config.FromConfigMap(configMap.Data)
}
func fetchWebhookTLS(k kubernetes.Interface, webhook string, options *upgradeOptions) (*tlsValues, error) {
var value *tlsValues
secret, err := k.CoreV1().
Secrets(controlPlaneNamespace).
Get(webhookSecretName(webhook), metav1.GetOptions{})
if err != nil {
if !kerrors.IsNotFound(err) {
return nil, err
}
value, err = options.generateWebhookTLS(webhook)
if err != nil {
return nil, err
}
} else {
value = &tlsValues{
KeyPEM: string(secret.Data["key.pem"]),
CrtPEM: string(secret.Data["crt.pem"]),
}
}
if err := options.verifyTLS(value, webhook); err != nil {
return nil, err
}
return value, nil
}
// fetchIdentityValue checks the kubernetes API to fetch an existing
// linkerd identity configuration.
//

View File

@ -24,6 +24,10 @@ func testUpgradeOptions() *upgradeOptions {
o := newUpgradeOptionsWithDefaults()
o.controlPlaneVersion = upgradeControlPlaneVersion
o.proxyVersion = upgradeProxyVersion
o.generateWebhookTLS = fakeGenerateWebhookTLS
o.verifyTLS = func(tls *tlsValues, service string) error {
return nil
}
return o
}

View File

@ -3,21 +3,13 @@ package main
import (
"github.com/linkerd/linkerd2/controller/k8s"
injector "github.com/linkerd/linkerd2/controller/proxy-injector"
"github.com/linkerd/linkerd2/controller/proxy-injector/tmpl"
"github.com/linkerd/linkerd2/controller/webhook"
pkgK8s "github.com/linkerd/linkerd2/pkg/k8s"
)
func main() {
config := &webhook.Config{
TemplateStr: tmpl.MutatingWebhookConfigurationSpec,
Ops: &injector.Ops{},
}
webhook.Launch(
config,
[]k8s.APIResource{k8s.NS, k8s.RS},
9995,
pkgK8s.ProxyInjectorWebhookServiceName,
injector.Inject,
)
}

View File

@ -2,21 +2,13 @@ package main
import (
validator "github.com/linkerd/linkerd2/controller/sp-validator"
"github.com/linkerd/linkerd2/controller/sp-validator/tmpl"
"github.com/linkerd/linkerd2/controller/webhook"
pkgK8s "github.com/linkerd/linkerd2/pkg/k8s"
)
func main() {
config := &webhook.Config{
TemplateStr: tmpl.ValidatingWebhookConfigurationSpec,
Ops: &validator.Ops{},
}
webhook.Launch(
config,
nil,
9997,
pkgK8s.SPValidatorWebhookServiceName,
validator.AdmitSP,
)
}

View File

@ -1,24 +0,0 @@
package tmpl
// MutatingWebhookConfigurationSpec provides a template for a
// MutatingWebhookConfiguration.
var MutatingWebhookConfigurationSpec = `
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: {{ .WebhookConfigName }}
labels:
linkerd.io/control-plane-component: proxy-injector
webhooks:
- name: linkerd-proxy-injector.linkerd.io
clientConfig:
service:
name: linkerd-proxy-injector
namespace: {{ .ControllerNamespace }}
path: "/"
caBundle: {{ .CABundle }}
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]`

View File

@ -1,24 +0,0 @@
package tmpl
// ValidatingWebhookConfigurationSpec provides a template for a
// ValidatingWebhookConfiguration.
var ValidatingWebhookConfigurationSpec = `
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: {{ .WebhookConfigName }}
labels:
linkerd.io/control-plane-component: sp-validator
webhooks:
- name: linkerd-sp-validator.linkerd.io
clientConfig:
service:
name: linkerd-sp-validator
namespace: {{ .ControllerNamespace }}
path: "/"
caBundle: {{ .CABundle }}
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: ["linkerd.io"]
apiVersions: ["v1alpha1"]
resources: ["serviceprofiles"]`

View File

@ -1,78 +0,0 @@
package webhook
import (
"bytes"
"encoding/base64"
"html/template"
"github.com/linkerd/linkerd2/pkg/tls"
log "github.com/sirupsen/logrus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
clientArv1beta1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1"
)
// ConfigOps declares the methods used to manage the webhook configs in the cluster
type ConfigOps interface {
Create(clientArv1beta1.AdmissionregistrationV1beta1Interface, *bytes.Buffer) (string, error)
Delete(clientArv1beta1.AdmissionregistrationV1beta1Interface) error
Exists(clientArv1beta1.AdmissionregistrationV1beta1Interface) error
Name() string
}
// Config contains all the necessary data to build and persist the webhook resource
type Config struct {
TemplateStr string
Ops ConfigOps
client clientArv1beta1.AdmissionregistrationV1beta1Interface
controllerNamespace string
rootCA *tls.CA
}
// Create deletes the webhook config if it already exists and then creates
// a new one
func (c *Config) Create() (string, error) {
exists, err := c.Exists()
if err != nil {
return "", err
}
if exists {
log.Info("deleting existing webhook configuration")
if err := c.Ops.Delete(c.client); err != nil {
return "", err
}
}
var (
buf = &bytes.Buffer{}
trustAnchor = []byte(c.rootCA.Cred.EncodeCertificatePEM())
spec = struct {
WebhookConfigName string
ControllerNamespace string
CABundle string
}{
WebhookConfigName: c.Ops.Name(),
ControllerNamespace: c.controllerNamespace,
CABundle: base64.StdEncoding.EncodeToString(trustAnchor),
}
)
t := template.Must(template.New("webhook").Parse(c.TemplateStr))
if err := t.Execute(buf, spec); err != nil {
return "", err
}
return c.Ops.Create(c.client, buf)
}
// Exists returns true if the webhook already exists
func (c *Config) Exists() (bool, error) {
if err := c.Ops.Exists(c.client); err != nil {
if apierrors.IsNotFound(err) {
return false, nil
}
return false, err
}
return true, nil
}

View File

@ -1,78 +0,0 @@
package webhook
import (
"fmt"
"testing"
"github.com/linkerd/linkerd2/controller/k8s"
injector "github.com/linkerd/linkerd2/controller/proxy-injector"
injectorTmpl "github.com/linkerd/linkerd2/controller/proxy-injector/tmpl"
validator "github.com/linkerd/linkerd2/controller/sp-validator"
validatorTmpl "github.com/linkerd/linkerd2/controller/sp-validator/tmpl"
"github.com/linkerd/linkerd2/pkg/tls"
)
func TestCreate(t *testing.T) {
k8sAPI, err := k8s.NewFakeAPI()
if err != nil {
panic(err)
}
rootCA, err := tls.GenerateRootCAWithDefaults("Test CA")
if err != nil {
t.Fatalf("failed to create root CA: %s", err)
}
testCases := []struct {
testName string
templateStr string
ops ConfigOps
}{
{
testName: "Mutating webhook",
templateStr: injectorTmpl.MutatingWebhookConfigurationSpec,
ops: &injector.Ops{},
},
{
testName: "Validating webhook",
templateStr: validatorTmpl.ValidatingWebhookConfigurationSpec,
ops: &validator.Ops{},
},
}
for _, tc := range testCases {
tc := tc // pin
t.Run(fmt.Sprintf(tc.testName), func(t *testing.T) {
webhookConfig := &Config{
TemplateStr: tc.templateStr,
Ops: tc.ops,
client: k8sAPI.Client.AdmissionregistrationV1beta1(),
controllerNamespace: "linkerd",
rootCA: rootCA,
}
// expect configuration to not exist
exists, err := webhookConfig.Exists()
if err != nil {
t.Fatal("Unexpected error: ", err)
}
if exists {
t.Error("Unexpected webhook configuration. Expect resource to not exist")
}
// create the webhook configuration
if _, err := webhookConfig.Create(); err != nil {
t.Fatal("Unexpected error: ", err)
}
// expect webhook configuration to exist
exists, err = webhookConfig.Exists()
if err != nil {
t.Fatal("Unexpected error: ", err)
}
if !exists {
t.Error("Expected webhook configuration to exist")
}
})
}
}

View File

@ -12,16 +12,16 @@ import (
"github.com/linkerd/linkerd2/controller/k8s"
"github.com/linkerd/linkerd2/pkg/admin"
"github.com/linkerd/linkerd2/pkg/flags"
pkgk8s "github.com/linkerd/linkerd2/pkg/k8s"
"github.com/linkerd/linkerd2/pkg/tls"
log "github.com/sirupsen/logrus"
)
// Launch sets up and starts the webhook and metrics servers
func Launch(config *Config, APIResources []k8s.APIResource, metricsPort uint32, serviceName string, handler handlerFunc) {
func Launch(APIResources []k8s.APIResource, metricsPort uint32, handler handlerFunc) {
metricsAddr := flag.String("metrics-addr", fmt.Sprintf(":%d", metricsPort), "address to serve scrapable metrics on")
addr := flag.String("addr", ":8443", "address to serve on")
kubeconfig := flag.String("kubeconfig", "", "path to kubeconfig")
controllerNamespace := flag.String("controller-namespace", "linkerd", "namespace in which Linkerd is installed")
flags.ConfigureAndParse()
stop := make(chan os.Signal, 1)
@ -33,22 +33,12 @@ func Launch(config *Config, APIResources []k8s.APIResource, metricsPort uint32,
log.Fatalf("failed to initialize Kubernetes API: %s", err)
}
rootCA, err := tls.GenerateRootCAWithDefaults(serviceName)
cred, err := tls.ReadPEMCreds(pkgk8s.MountPathTLSKeyPEM, pkgk8s.MountPathTLSCrtPEM)
if err != nil {
log.Fatalf("failed to create root CA: %s", err)
log.Fatalf("failed to read TLS secrets: %s", err)
}
config.client = k8sAPI.Client.AdmissionregistrationV1beta1()
config.controllerNamespace = *controllerNamespace
config.rootCA = rootCA
selfLink, err := config.Create()
if err != nil {
log.Fatalf("failed to create the webhook configurations resource: %s", err)
}
log.Infof("created webhook configuration: %s", selfLink)
s, err := NewServer(k8sAPI, *addr, serviceName, *controllerNamespace, rootCA, handler)
s, err := NewServer(k8sAPI, *addr, cred, handler)
if err != nil {
log.Fatalf("failed to initialize the webhook server: %s", err)
}

View File

@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
@ -21,24 +20,30 @@ type handlerFunc func(*k8s.API, *admissionv1beta1.AdmissionRequest) (*admissionv
// Server describes the https server implementing the webhook
type Server struct {
*http.Server
api *k8s.API
handler handlerFunc
controllerNamespace string
api *k8s.API
handler handlerFunc
}
// NewServer returns a new instance of Server
func NewServer(api *k8s.API, addr, name, controllerNamespace string, rootCA *pkgTls.CA, handler handlerFunc) (*Server, error) {
c, err := tlsConfig(rootCA, name, controllerNamespace)
func NewServer(api *k8s.API, addr string, cred *pkgTls.Cred, handler handlerFunc) (*Server, error) {
var (
certPEM = cred.EncodePEM()
keyPEM = cred.EncodePrivateKeyPEM()
)
cert, err := tls.X509KeyPair([]byte(certPEM), []byte(keyPEM))
if err != nil {
return nil, err
}
server := &http.Server{
Addr: addr,
TLSConfig: c,
Addr: addr,
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{cert},
},
}
s := &Server{server, api, handler, controllerNamespace}
s := &Server{server, api, handler}
s.Handler = http.HandlerFunc(s.serve)
return s, nil
}
@ -123,29 +128,6 @@ func (s *Server) Shutdown(ctx context.Context) error {
return s.Server.Shutdown(ctx)
}
func tlsConfig(rootCA *pkgTls.CA, name, controllerNamespace string) (*tls.Config, error) {
// must use the service short name in this TLS identity as the k8s api server
// looks for the webhook at <svc_name>.<namespace>.svc, without the cluster
// domain.
dnsName := fmt.Sprintf("%s.%s.svc", name, controllerNamespace)
cred, err := rootCA.GenerateEndEntityCred(dnsName)
if err != nil {
return nil, err
}
certPEM := cred.EncodePEM()
keyPEM := cred.EncodePrivateKeyPEM()
cert, err := tls.X509KeyPair([]byte(certPEM), []byte(keyPEM))
if err != nil {
return nil, err
}
return &tls.Config{
Certificates: []tls.Certificate{cert},
}, nil
}
func decode(data []byte) (*admissionv1beta1.AdmissionReview, error) {
var admissionReview admissionv1beta1.AdmissionReview
err := yaml.Unmarshal(data, &admissionReview)

View File

@ -18,7 +18,7 @@ func TestServe(t *testing.T) {
if err != nil {
panic(err)
}
testServer := &Server{nil, k8sAPI, nil, "linkerd"}
testServer := &Server{nil, k8sAPI, nil}
in := bytes.NewReader(nil)
request := httptest.NewRequest(http.MethodGet, "/", in)
@ -38,7 +38,7 @@ func TestServe(t *testing.T) {
func TestShutdown(t *testing.T) {
server := &http.Server{Addr: ":0"}
testServer := &Server{server, nil, nil, "linkerd"}
testServer := &Server{server, nil, nil}
go func() {
if err := testServer.ListenAndServe(); err != nil {

View File

@ -240,6 +240,12 @@ const (
// store identity credentials.
MountPathEndEntity = MountPathBase + "/identity/end-entity"
// MountPathTLSKeyPEM is the path at which the TLS key PEM file is mounted.
MountPathTLSKeyPEM = MountPathBase + "/tls/key.pem"
// MountPathTLSCrtPEM is the path at which the TLS cert PEM file is mounted.
MountPathTLSCrtPEM = MountPathBase + "/tls/crt.pem"
// IdentityServiceAccountTokenPath is the path to the kubernetes service
// account token used by proxies to provision identity.
//