Skip to content

Commit fab9827

Browse files
committed
set up logging and make certvalidity configurable
1 parent 3169daa commit fab9827

File tree

6 files changed

+123
-35
lines changed

6 files changed

+123
-35
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,6 @@ __pycache__/
347347

348348
# always include vendor directory
349349
!/vendor/**
350+
351+
# ignore example cert-controller binary
352+
cert-controller

Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ COPY pkg pkg
1111
COPY main.go ./
1212
RUN go build -o cert-controller main.go
1313

14-
1514
FROM scratch
1615
WORKDIR /app
1716

@@ -20,4 +19,4 @@ COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
2019

2120
USER 1000:1000
2221

23-
CMD ["/app/cert-controller"]
22+
ENTRYPOINT ["/app/cert-controller", "-cert-restart-on-secret-refresh"]

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/onsi/gomega v1.10.1
77
github.com/pkg/errors v0.9.1
88
go.uber.org/atomic v1.4.0
9+
go.uber.org/zap v1.10.0
910
k8s.io/api v0.18.6
1011
k8s.io/apimachinery v0.18.6
1112
k8s.io/client-go v0.18.6

main.go

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package main
22

33
import (
4+
"go.uber.org/zap"
45
"flag"
5-
"fmt"
66
"k8s.io/apimachinery/pkg/api/meta"
77
"k8s.io/client-go/rest"
88
"k8s.io/client-go/tools/clientcmd/api"
@@ -13,56 +13,59 @@ import (
1313
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
1414
ctrl "sigs.k8s.io/controller-runtime"
1515
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
16+
"time"
1617
)
1718

19+
// TODO: make all defaults "" and map loop to blow up when value is ""
20+
// TODO: call flag parse to maybe fix arguments
1821
var (
19-
certDir = flag.String("cert-dir", "/etc/tls-certs", "The directory where certs are stored, defaults to /certs")
20-
caName = flag.String("ca-name", "ca-name", "The name of the ca cert, defaults to ca-name")
21-
secretName = flag.String("secret-name", "secret-name", "The name of the secret, defaults to secret-name")
22-
serviceName = flag.String("service-name", "webhook-service-name", "The name of the service, defaults to webhook-service-name")
23-
caOrganization = flag.String("caOrganization", "organization", "The name of the CA organization, defaults to organization")
24-
nameSpace = flag.String("namespace", "kube-system", "The namespace of your service, defaults to kube-system")
25-
dnsName = flag.String("dns-name", *serviceName + "." + *nameSpace + ".svc", "The dns name of your service <service name>.<namespace>.svc")
26-
webhookName = flag.String("webhook-name", "webhook-name", "Your webhook name, defaults to webhook-name")
22+
certDir = flag.String("cert-dir", "", "The directory where certs are stored")
23+
caName = flag.String("ca-name", "", "The name of the ca cert")
24+
secretName = flag.String("secret-name", "", "The name of the secret")
25+
serviceName = flag.String("service-name", "", "The name of the service")
26+
caOrganization = flag.String("ca-organization", "", "The name of the CA organization")
27+
nameSpace = flag.String("namespace", "", "The namespace of your service")
28+
dnsName = flag.String("dns-name", "", "The dns name of your service <service name>.<namespace>.svc")
29+
webhookName = flag.String("webhook-name", "", "Your webhook name")
2730
)
2831

32+
2933
var webhooks = []rotator.WebhookInfo{
3034
{
3135
Name: *webhookName,
3236
Type: rotator.Mutating, // Todo: allow selecting types
3337
},
3438
}
3539

36-
// TODO: print when it updates the secrets
37-
// TODO: add a nice logger
38-
// TODO: remove all the default values, PR to cert-controller say this is a POC to run as a standalone
39-
// TODO: put all the vpa values in there
4040
func main() {
41-
fmt.Println("starting")
41+
flag.Parse()
42+
43+
// configure logging.
44+
logger, _ := zap.NewDevelopment()
45+
46+
logger.Info("sleeping to demonstrate restart behavior")
47+
time.Sleep(5 * time.Second)
48+
49+
logger.Info("starting cert-controller")
4250
config := ctrl.GetConfigOrDie()
4351
scheme := runtime.NewScheme()
4452

4553
_ = clientgoscheme.AddToScheme(scheme)
4654
_ = api.AddToScheme(scheme)
4755

4856
mgr, err := ctrl.NewManager(config, ctrl.Options{
49-
Scheme: scheme, //TODO: try to remove
50-
MetricsBindAddress: "0", //TODO: try to remove
5157
LeaderElection: false,
52-
Port: 443, //TODO: try to remove
5358
CertDir: *certDir,
54-
HealthProbeBindAddress: ":9090", //TODO: try to remove
5559
MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) {
5660
return apiutil.NewDynamicRESTMapper(c)
5761
},
5862
})
5963
if err != nil {
60-
fmt.Println("unable to start manager:", err)
64+
logger.Error("unable to start manager", zap.Error(err))
6165
os.Exit(1)
6266
}
6367

6468
// Make sure certs are generated and valid if cert rotation is enabled.
65-
fmt.Println("setting up cert rotation")
6669
if err := rotator.AddRotator(mgr, &rotator.CertRotator{
6770
SecretKey: types.NamespacedName{
6871
Namespace: *nameSpace,
@@ -74,25 +77,20 @@ func main() {
7477
DNSName: *dnsName,
7578
Webhooks: webhooks,
7679
}); err != nil {
77-
fmt.Println("unable to set up cert rotation:", err)
80+
logger.Error("unable to set up cert rotation", zap.Error(err))
81+
7882
os.Exit(1)
7983
}
8084

81-
fmt.Println("starting manager")
85+
logger.Info("starting manager")
8286
hadError := false
8387
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
84-
fmt.Println("problem running manager:", err)
88+
logger.Error("problem running manager", zap.Error(err))
8589
hadError = true
8690
}
8791

88-
// Manager stops controllers asynchronously.
89-
// Instead, we use ControllerSwitch to synchronously prevent them from doing more work.
90-
// This can be removed when finalizer and status teardown is removed.
91-
fmt.Println("disabling controllers...")
92-
// sw.Stop() TODO: see if this is safely deleted
93-
9492
if hadError {
95-
fmt.Println("had error:", err)
93+
logger.Error("Error running manager", zap.Error(err))
9694
os.Exit(1)
9795
}
9896
}

pkg/rotator/rotator.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ const (
4141
caCertName = "ca.crt"
4242
caKeyName = "ca.key"
4343
rotationCheckFrequency = 12 * time.Hour
44-
certValidityDuration = 10 * time.Minute
4544
lookaheadInterval = 90 * 24 * time.Hour
4645
)
4746

@@ -63,6 +62,9 @@ var _ manager.Runnable = &CertRotator{}
6362

6463
var restartOnSecretRefresh = false
6564

65+
var certValidityDuration = flag.Duration("cert-validity-duration", 10 * 365 * 24 * time.Hour, "Sets how long the cert is valid for, defaults to 10 years")
66+
67+
6668
//WebhookInfo is used by the rotator to receive info about resources to be updated with certificates
6769
type WebhookInfo struct {
6870
//Name is the name of the webhook for a validating or mutating webhook, or the CRD name in case of a CRD conversion webhook
@@ -71,7 +73,7 @@ type WebhookInfo struct {
7173
}
7274

7375
func init() {
74-
flag.BoolVar(&restartOnSecretRefresh, "cert-restart-on-secret-refresh", false, "Kills the process when secrets are refreshed so that the pod can be restarted (secrets take up to 60s to be updated by running pods)")
76+
flag.BoolVar(&restartOnSecretRefresh, "cert-restart-on-secret-refresh", true, "Kills the process when secrets are refreshed so that the pod can be restarted (secrets take up to 60s to be updated by running pods)")
7577
}
7678

7779
func (w WebhookInfo) gvk() schema.GroupVersionKind {
@@ -262,7 +264,7 @@ func (cr *CertRotator) refreshCerts(refreshCA bool, secret *corev1.Secret) error
262264
var caArtifacts *KeyPairArtifacts
263265
now := time.Now()
264266
begin := now.Add(-1 * time.Hour)
265-
end := now.Add(certValidityDuration)
267+
end := now.Add(*certValidityDuration)
266268
if refreshCA {
267269
var err error
268270
caArtifacts, err = cr.CreateCACert(begin, end)

test.yaml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
apiVersion: apps/v1
3+
kind: Deployment
4+
metadata:
5+
name: vpa-admission-controller
6+
namespace: default
7+
labels:
8+
app: busybox
9+
spec:
10+
replicas: 1
11+
selector:
12+
matchLabels:
13+
app: busybox
14+
template:
15+
metadata:
16+
labels:
17+
app: busybox
18+
foo: bar4
19+
spec:
20+
containers:
21+
- name: busybox
22+
image: busybox
23+
command: ["sh", "-c", "watch ls /certs"]
24+
volumeMounts:
25+
- name: certs
26+
mountPath: "/certs"
27+
readOnly: true
28+
- name: cert-controller
29+
args:
30+
- cert-dir=/certs
31+
- ca-name=foocaname
32+
- secret-name=vpa-admission-controller-secret
33+
- service-name=fooservice
34+
- ca-organization=fooorg
35+
- namespace=default
36+
- dns-name=foo.bar.svc
37+
- webhook-name=vpa-webhook-config
38+
imagePullPolicy: Never
39+
image: cert-controller
40+
volumes:
41+
- name: certs
42+
secret:
43+
secretName: vpa-admission-controller-secret
44+
---
45+
apiVersion: admissionregistration.k8s.io/v1
46+
kind: MutatingWebhookConfiguration
47+
metadata:
48+
name: vpa-webhook-config
49+
labels:
50+
product: foundation
51+
team: compute
52+
project: vertical-pod-autoscaler
53+
role: admission-controller
54+
annotations:
55+
samson/server_side_apply: 'true'
56+
webhooks:
57+
- name: vpa.k8s.io
58+
failurePolicy: Ignore
59+
admissionReviewVersions: ["v1beta1"]
60+
rules:
61+
- apiGroups: [""]
62+
apiVersions: ["v1"]
63+
operations: ["CREATE"]
64+
resources: ["pods"]
65+
clientConfig:
66+
service:
67+
namespace: default
68+
name: vpa-webhook
69+
sideEffects: None
70+
timeoutSeconds: 30
71+
72+
# We need to create a bogus secret for the updater to fill
73+
---
74+
apiVersion: v1
75+
kind: Secret
76+
metadata:
77+
labels:
78+
project: foo
79+
team: compute
80+
role: bar
81+
product: foundation
82+
name: vpa-admission-controller-secret
83+
namespace: default
84+
annotations:
85+
samson/server_side_apply: 'true'

0 commit comments

Comments
 (0)