Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
04a2c57
Initial plumbing
alvaroaleman Oct 18, 2018
d79d9fd
Full plumbing
alvaroaleman Oct 18, 2018
4fdf143
Add business logic to machineDeployment defaulting and validation
alvaroaleman Oct 18, 2018
e0e5677
Check for len(errs) not fore != nil
alvaroaleman Oct 18, 2018
fdfdedf
Only create a jsonpatch if there were changes
alvaroaleman Oct 18, 2018
d425446
Use evanphx/json-patch, hopefully not buggy
alvaroaleman Oct 18, 2018
310f1be
Test
alvaroaleman Oct 18, 2018
09af17f
Revert back to mattbairds jsonpatch library
alvaroaleman Oct 18, 2018
340a9bd
Add some debug logging
alvaroaleman Oct 18, 2018
ae4db04
Update e2e testing to use MatatingAdmissionWebhook
alvaroaleman Oct 18, 2018
5402daf
Merge branch 'master' into admission-webhook
alvaroaleman Oct 18, 2018
74c81a9
Increase size of e2e controlller to check if it helps
alvaroaleman Oct 19, 2018
4b7aef7
Use ipvs on kubeadm-controller in e2e tests
alvaroaleman Oct 19, 2018
c03b573
Revert "Use ipvs on kubeadm-controller in e2e tests"
alvaroaleman Oct 19, 2018
69a36e7
Move webhook into a dedicated app
alvaroaleman Oct 19, 2018
2a3e150
Move webhook into a dedicated deployment
alvaroaleman Oct 19, 2018
505a06a
Fix name of service
alvaroaleman Oct 19, 2018
181ae61
Block webhook shutdown
alvaroaleman Oct 19, 2018
a44c132
Use one replica for the webhook
alvaroaleman Oct 19, 2018
2734863
Small fixes
alvaroaleman Oct 19, 2018
b569ac6
Clean up unneeded temporal changes
alvaroaleman Oct 19, 2018
62c7555
Fix docker-image target
alvaroaleman Oct 19, 2018
1af777f
Fix test if machine-controller is running
alvaroaleman Oct 19, 2018
b981212
Use one docker image for everything
alvaroaleman Oct 19, 2018
278030e
Merge branch 'master' into admission-webhook
alvaroaleman Oct 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ jobs:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
- run: DEP_RELEASE_TAG=v0.5.0 curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
- run: make machine-controller
- run: make webhook
- save_cache:
key: machine-controller-{{ .Revision }}
paths:
- /go/src/github.com/kubermatic/machine-controller
- /go/src/github.com/kubermatic/webhook
end-to-end:
<<: *defaults
steps:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ test/tools/verify/verify
terraform
terraform-provider-hcloud
.kubeconfig
examples/*.pem
examples/*.csr
examples/*.srl
webhook
!cmd/webhook
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ FROM alpine:3.7
RUN apk add --no-cache ca-certificates cdrkit

COPY machine-controller /usr/local/bin
COPY webhook /usr/local/bin

USER nobody
14 changes: 14 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 35 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ machine-controller: $(shell find cmd pkg -name '*.go') vendor
-o machine-controller \
github.com/kubermatic/machine-controller/cmd/controller

docker-image: machine-controller docker-image-nodep
webhook: $(shell find cmd pkg -name '*.go') vendor
go build -v \
-ldflags '-s -w' \
-o webhook \
github.com/kubermatic/machine-controller/cmd/webhook

docker-image: machine-controller admission-webhook docker-image-nodep

# This target exists because in our CI
# we do not want to restore the vendor
Expand Down Expand Up @@ -68,3 +74,31 @@ e2e-cluster:
e2e-destroy:
./test/tools/integration/cleanup_machines.sh
make -C test/tools/integration destroy

examples/ca-key.pem:
openssl genrsa -out examples/ca-key.pem 4096

examples/ca-cert.pem: examples/ca-key.pem
openssl req -x509 -new -nodes -key examples/ca-key.pem \
-subj "/C=US/ST=CA/O=Acme/CN=k8s-machine-controller-ca" \
-sha256 -days 10000 -out examples/ca-cert.pem

examples/admission-key.pem: examples/ca-cert.pem
openssl genrsa -out examples/admission-key.pem 2048
chmod 0600 examples/admission-key.pem

examples/admission-cert.pem: examples/admission-key.pem
openssl req -new -sha256 \
-key examples/admission-key.pem \
-subj "/C=US/ST=CA/O=Acme/CN=machine-controller-webhook.kube-system.svc" \
-out examples/admission.csr
openssl x509 -req -in examples/admission.csr -CA examples/ca-cert.pem \
-CAkey examples/ca-key.pem -CAcreateserial \
-out examples/admission-cert.pem -days 10000 -sha256

deploy: examples/admission-cert.pem
@cat examples/machine-controller.yaml \
|sed "s/__admission_ca_cert__/$(shell cat examples/ca-cert.pem|base64 -w0)/g" \
|sed "s/__admission_cert__/$(shell cat examples/admission-cert.pem|base64 -w0)/g" \
|sed "s/__admission_key__/$(shell cat examples/admission-key.pem|base64 -w0)/g" \
|kubectl apply -f -
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

## Deploy the machine-controller

`kubectl apply -f examples/machine-controller.yaml`
`make deploy`

## Creating a machineDeployment
```bash
Expand Down
34 changes: 34 additions & 0 deletions cmd/webhook/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"flag"

"github.com/golang/glog"

"github.com/kubermatic/machine-controller/pkg/admission"
)

var (
admissionListenAddress string
admissionTLSCertPath string
admissionTLSKeyPath string
)

func main() {
flag.StringVar(&admissionListenAddress, "listen-address", ":9876", "The address on which the MutatingWebhook will listen on")
flag.StringVar(&admissionTLSCertPath, "tls-cert-path", "/tmp/cert/cert.pem", "The path of the TLS cert for the MutatingWebhook")
flag.StringVar(&admissionTLSKeyPath, "tls-key-path", "/tmp/cert/key.pem", "The path of the TLS key for the MutatingWebhook")
flag.Parse()

s := admission.New(admissionListenAddress)
if err := s.ListenAndServeTLS(admissionTLSCertPath, admissionTLSKeyPath); err != nil {
glog.Fatalf("Failed to start server: %v", err)
}
defer func() {
if err := s.Close(); err != nil {
glog.Fatalf("Failed to shutdown server: %v", err)
}
}()
glog.Infof("Listening on %s", admissionListenAddress)
select {}
}
93 changes: 93 additions & 0 deletions examples/machine-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,75 @@ spec:
port: 8085
periodSeconds: 5
---
apiVersion: apps/v1beta2
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until I put this into a dedicated Deployment, the e2e tests always had some failures because of a connection reset when the APIServer tried to call the Webhook

kind: Deployment
metadata:
name: machine-controller-webhook
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: machine-controller-webhook
template:
metadata:
labels:
app: machine-controller-webhook
spec:
containers:
- image: kubermatic/machine-controller:latest
imagePullPolicy: IfNotPresent
name: webhook
command:
- /usr/local/bin/webhook
- -logtostderr
- -v=6
- -listen-address=0.0.0.0:9876
volumeMounts:
- name: machine-controller-admission-cert
mountPath: /tmp/cert
livenessProbe:
httpGet:
path: /healthz
port: 9876
scheme: HTTPS
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /healthz
port: 9876
scheme: HTTPS
periodSeconds: 5
volumes:
- name: machine-controller-admission-cert
secret:
secretName: machine-controller-admission-cert
---
apiVersion: v1
kind: Secret
metadata:
name: machine-controller-admission-cert
namespace: kube-system
data:
"cert.pem": __admission_cert__
"key.pem": __admission_key__
---
apiVersion: v1
kind: Service
metadata:
name: machine-controller-webhook
namespace: kube-system
spec:
ports:
- name: 443-9876
port: 443
protocol: TCP
targetPort: 9876
selector:
app: machine-controller-webhook
type: ClusterIP
---
apiVersion: v1
kind: ServiceAccount
metadata:
Expand Down Expand Up @@ -404,3 +473,27 @@ subjects:
- kind: ServiceAccount
name: machine-controller
namespace: kube-system
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: machinedeployments.machine-controller.kubermatic.io
webhooks:
- name: machinedeployments.machine-controller.kubermatic.io
failurePolicy: Fail
rules:
- apiGroups:
- "cluster.k8s.io"
apiVersions:
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- machinedeployments
clientConfig:
service:
namespace: kube-system
name: machine-controller-webhook
path: /machinedeployments
caBundle: __admission_ca_cert__
49 changes: 49 additions & 0 deletions pkg/admission/admission.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package admission

import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"time"

"github.com/golang/glog"
"github.com/mattbaird/jsonpatch"

"k8s.io/apimachinery/pkg/runtime"
)

func New(listenAddress string) *http.Server {
m := http.NewServeMux()
m.HandleFunc("/machinedeployments", handleFuncFactory(mutateMachineDeployments))
m.HandleFunc("/healthz", healthZHandler)
return &http.Server{
Addr: listenAddress,
Handler: m,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
}

func healthZHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}

func newJSONPatch(original, current runtime.Object) ([]jsonpatch.JsonPatchOperation, error) {
originalGVK := original.GetObjectKind().GroupVersionKind()
currentGVK := current.GetObjectKind().GroupVersionKind()
if !reflect.DeepEqual(originalGVK, currentGVK) {
return nil, fmt.Errorf("GroupVersionKind %#v is expected to match %#v", originalGVK, currentGVK)
}
ori, err := json.Marshal(original)
if err != nil {
return nil, err
}
glog.V(4).Infof("jsonpatch: Marshaled original: %s", string(ori))
cur, err := json.Marshal(current)
if err != nil {
return nil, err
}
glog.V(4).Infof("jsonpatch: Marshaled target: %s", string(cur))
return jsonpatch.CreatePatch(ori, cur)
}
Loading