Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automated GCP Credentials Addon Prototype #8682

Merged
merged 39 commits into from
Jul 21, 2020
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
652ebd6
metadata addon works
Jan 27, 2020
5cd023c
Add code for metadata server image and makefile rules
Jan 27, 2020
582ed25
remove log message
Jan 28, 2020
615b35f
update to work with v1.13.11
Jan 29, 2020
4c20014
update readme
Apr 20, 2020
d138d42
Merge branch 'metadata-addon' of github.com:priyawadhwa/minikube into…
sharifelgamal Jun 2, 2020
8a202f0
fix metadata addon stuff for newer codebase
sharifelgamal Jun 4, 2020
b0fc07a
buncha changes
sharifelgamal Jun 15, 2020
66d37c8
just so many changes
sharifelgamal Jun 30, 2020
b186746
Merge branch 'master' of github.com:kubernetes/minikube into metadata
sharifelgamal Jun 30, 2020
60e3d32
ch-ch-ch-ch-changes
sharifelgamal Jul 7, 2020
9ae5bc4
addon works
sharifelgamal Jul 8, 2020
7722419
update readme
sharifelgamal Jul 8, 2020
09478c9
Merge branch 'master' of github.com:kubernetes/minikube into metadata
sharifelgamal Jul 8, 2020
95c9ff9
boilerplate
sharifelgamal Jul 8, 2020
ec11746
revert unrelated change
sharifelgamal Jul 8, 2020
216462b
move server code to another repo
sharifelgamal Jul 8, 2020
a8abf43
switch addon name to gcp-auth
sharifelgamal Jul 8, 2020
488c625
metadata -> gcp-auth
sharifelgamal Jul 10, 2020
839e581
missed one
sharifelgamal Jul 10, 2020
f4fb523
Merge branch 'master' of github.com:kubernetes/minikube into metadata
sharifelgamal Jul 13, 2020
3046d00
Merge branch 'master' of github.com:kubernetes/minikube into metadata
sharifelgamal Jul 14, 2020
b5d9e3c
automate finding of credentials
sharifelgamal Jul 14, 2020
76d4dc3
remove unnecessary comment
sharifelgamal Jul 14, 2020
a34eca7
address comments
sharifelgamal Jul 14, 2020
3f86eff
Update README.md
sharifelgamal Jul 14, 2020
aabbbe0
Update README.md
sharifelgamal Jul 15, 2020
dde94b5
use mustload everywhere
sharifelgamal Jul 15, 2020
603040d
Merge branch 'metadata' of github.com:sharifelgamal/minikube into met…
sharifelgamal Jul 15, 2020
e651fab
swap selector condition
sharifelgamal Jul 15, 2020
dd89c1c
upgrade kube-webhook-certgen to 1.3
sharifelgamal Jul 15, 2020
142192b
move paths to constants
sharifelgamal Jul 15, 2020
3353198
Merge branch 'master' of github.com:kubernetes/minikube into metadata
sharifelgamal Jul 15, 2020
0a67568
add notice to user on addon enable
sharifelgamal Jul 15, 2020
0ee4b71
adding addon documentation
sharifelgamal Jul 16, 2020
2d136d1
Merge branch 'master' of github.com:kubernetes/minikube into metadata
sharifelgamal Jul 19, 2020
f6f5057
Merge branch 'master' of github.com:kubernetes/minikube into metadata
sharifelgamal Jul 21, 2020
ce0d41a
move addons documentation inside handbook
sharifelgamal Jul 21, 2020
f07dd49
remove old addons docs location
sharifelgamal Jul 21, 2020
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
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
out/buildroot*

sharifelgamal marked this conversation as resolved.
Show resolved Hide resolved
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -675,3 +675,18 @@ help:
@printf "\033[1mAvailable targets for minikube ${VERSION}\033[21m\n"
@printf "\033[1m--------------------------------------\033[21m\n"
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'


metadata-server: out/metadata-server

out/metadata-server:
CGO_ENABLED=0 GOOS=linux go build -o $@ -ldflags=$(PROVISIONER_LDFLAGS) cmd/metadata-server/server.go

.PHONY: metadata-server-image
metadata-server-image: out/metadata-server ## Build metadata-server docker image
docker build -t $(REGISTRY)/metadata-server:snapshot -f deploy/metadata-server/Dockerfile ./out


.PHONY: push-metadata-server-image
push-metadata-server-image: metadata-server-image ## Push metadata-server docker image using gcloud
gcloud docker -- push $(REGISTRY)/metadata-server
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ minikube is a Kubernetes [#sig-cluster-lifecycle](https://github.com/kubernetes/

Join our meetings:
* [Bi-weekly office hours, Mondays @ 11am PST](https://tinyurl.com/minikube-oh)
* [Triage Party](https://minikube.sigs.k8s.io/docs/contrib/triage/)
* [Triage Party](https://minikube.sigs.k8s.io/docs/contrib/triage/)
sharifelgamal marked this conversation as resolved.
Show resolved Hide resolved
225 changes: 225 additions & 0 deletions cmd/metadata-server/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*
Copyright 2020 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"

admissionv1 "k8s.io/api/admission/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
)

var (
runtimeScheme = runtime.NewScheme()
codecs = serializer.NewCodecFactory(runtimeScheme)
deserializer = codecs.UniversalDeserializer()
)

type patchOperation struct {
Op string `json:"op"`
Path string `json:"path"`
Value interface{} `json:"value,omitempty"`
}

func mutateHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("%v\n", r)

var body []byte
if r.Body != nil {
if data, err := ioutil.ReadAll(r.Body); err == nil {
body = data
}
}

if len(body) == 0 {
log.Print("request body was empty, returning")
http.Error(w, "empty body", http.StatusBadRequest)
return
}

var admissionResponse *admissionv1.AdmissionResponse

ar := admissionv1.AdmissionReview{}
if _, _, err := deserializer.Decode(body, nil, &ar); err != nil {
log.Printf("Can't decode body: %v", err)
admissionResponse = &admissionv1.AdmissionResponse{
Result: &metav1.Status{
Message: err.Error(),
},
}
}

req := ar.Request
var pod corev1.Pod
if err := json.Unmarshal(req.Object.Raw, &pod); err != nil {
log.Printf("Could not unmarshal raw object: %v", err)
admissionResponse = &admissionv1.AdmissionResponse{
Result: &metav1.Status{
Message: err.Error(),
},
}
}

var patch []patchOperation

// Define the volume to mount in
v := corev1.Volume{
Name: "gcp-creds",
sharifelgamal marked this conversation as resolved.
Show resolved Hide resolved
VolumeSource: corev1.VolumeSource{
HostPath: func() *corev1.HostPathVolumeSource {
h := corev1.HostPathVolumeSource{
Path: "/tmp/google_application_credentials.json",
Type: func() *corev1.HostPathType {
hpt := corev1.HostPathFile
return &hpt
}(),
}
return &h
}(),
},
}

// Mount the volume in
mount := corev1.VolumeMount{
Name: "gcp-creds",
MountPath: "/google-app-creds.json",
ReadOnly: true,
}

// Define the env var
e := corev1.EnvVar{
Name: "GOOGLE_APPLICATION_CREDENTIALS",
Value: "/google-app-creds.json",
}

// If GOOGLE_CLOUD_PROJECT is set in the VM, set it for all GCP apps.
var e2 corev1.EnvVar
if _, err := os.Stat("/tmp/google_cloud_project"); err == nil {
project, err := ioutil.ReadFile("/tmp/google_cloud_project")
if err == nil {
e2 = corev1.EnvVar{
Name: "GOOGLE_CLOUD_PROJECT",
Value: string(project),
}
}
}

envVars := []corev1.EnvVar{e}
if e2.Name != "" {
envVars = append(envVars, e2)
}

patch = append(patch, patchOperation{
Op: "add",
Path: "/spec/volumes",
Value: append(pod.Spec.Volumes, v),
})

for i, c := range pod.Spec.Containers {
if len(c.VolumeMounts) == 0 {
patch = append(patch, patchOperation{
Op: "add",
Path: fmt.Sprintf("/spec/containers/%d/volumeMounts", i),
Value: []corev1.VolumeMount{mount},
})
} else {
patch = append(patch, patchOperation{
Op: "add",
Path: fmt.Sprintf("/spec/containers/%d/volumeMounts", i),
Value: append(c.VolumeMounts, mount),
})
}
if len(c.Env) == 0 {
patch = append(patch, patchOperation{
Op: "add",
Path: fmt.Sprintf("/spec/containers/%d/env", i),
Value: envVars,
})
} else {
patch = append(patch, patchOperation{
Op: "add",
Path: fmt.Sprintf("/spec/containers/%d/env", i),
Value: append(c.Env, envVars...),
})
}
}

patchBytes, err := json.Marshal(patch)
if err != nil {
admissionResponse = &admissionv1.AdmissionResponse{
Result: &metav1.Status{
Message: err.Error(),
},
}
}

if admissionResponse == nil {
admissionResponse = &admissionv1.AdmissionResponse{
Allowed: true,
Patch: patchBytes,
PatchType: func() *admissionv1.PatchType {
pt := admissionv1.PatchTypeJSONPatch
return &pt
}(),
}
}

admissionReview := admissionv1.AdmissionReview{}
if admissionResponse != nil {
admissionReview.Response = admissionResponse
if ar.Request != nil {
admissionReview.Response.UID = ar.Request.UID
}
}
admissionReview.Kind = "AdmissionReview"
admissionReview.APIVersion = "admission.k8s.io/v1"

resp, err := json.Marshal(admissionReview)
if err != nil {
log.Printf("Can't encode response: %v", err)
http.Error(w, fmt.Sprintf("could not encode response: %v", err), http.StatusInternalServerError)
}
log.Printf("Ready to write reponse ...")
if _, err := w.Write(resp); err != nil {
log.Printf("Can't write response: %v", err)
http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError)
}

}

func main() {
log.Print("Mutate webhook server started! Take 5.")

mux := http.NewServeMux()

mux.HandleFunc("/mutate", mutateHandler)

s := &http.Server{
Addr: ":8443",
Handler: mux,
}

log.Fatal(s.ListenAndServeTLS("/etc/webhook/certs/cert", "/etc/webhook/certs/key"))
}
28 changes: 28 additions & 0 deletions deploy/addons/metadata/metadata-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: metadata
namespace: metadata
spec:
selector:
matchLabels:
app: metadata
template:
metadata:
labels:
app: metadata
spec:
containers:
- name: metadata
image: gcr.io/k8s-minikube/metadata-server:snapshot
imagePullPolicy: Never
ports:
- containerPort: 8443
volumeMounts:
- name: webhook-certs
mountPath: /etc/webhook/certs
readOnly: true
volumes:
- name: webhook-certs
secret:
secretName: metadata-certs
Loading