Skip to content

Commit

Permalink
Rework cert generation so that it uses two deployments
Browse files Browse the repository at this point in the history
Signed-off-by: Josh Pinkney <joshpinkney@gmail.com>
  • Loading branch information
JPinkney committed Jun 8, 2020
1 parent 19ebfea commit 1a9c8db
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 267 deletions.
23 changes: 22 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ WEBHOOK_ENABLED ?= false
DEFAULT_ROUTING ?= basic
ADMIN_CTX ?= ""
REGISTRY_ENABLED ?= true
CERT_IMG ?= quay.io/che-incubator/che-workspace-controller-cert-gen:latest

all: help

Expand All @@ -19,6 +20,7 @@ _print_vars:
@echo " WEBHOOK_ENABLED=$(WEBHOOK_ENABLED)"
@echo " DEFAULT_ROUTING=$(DEFAULT_ROUTING)"
@echo " REGISTRY_ENABLED=$(REGISTRY_ENABLED)"
@echo " CERT_IMG=$(CERT_IMG)"

_set_ctx:
ifneq ($(ADMIN_CTX),"")
Expand Down Expand Up @@ -68,7 +70,12 @@ ifeq ($(TOOL),oc)
sed -i.bak -e "s|image: .*|image: $(IMG)|g" ./deploy/os/controller.yaml
sed -i.bak -e "s|imagePullPolicy: Always|imagePullPolicy: $(PULL_POLICY)|g" ./deploy/os/controller.yaml
sed -i.bak -e "s|kubectl.kubernetes.io/restartedAt: .*|kubectl.kubernetes.io/restartedAt: '$$(date +%Y-%m-%dT%H:%M:%S%z)'|g" ./deploy/os/controller.yaml

sed -i.bak -e "s|image: .*|image: $(CERT_IMG)|g" ./deploy/os/che-workspace-controller-cert-gen-deployment.yaml
sed -i.bak -e "s|kubectl.kubernetes.io/restartedAt: .*|kubectl.kubernetes.io/restartedAt: '$$(date +%Y-%m-%dT%H:%M:%S%z)'|g" ./deploy/os/che-workspace-controller-cert-gen-deployment.yaml

rm ./deploy/os/controller.yaml.bak
rm ./deploy/os/che-workspace-controller-cert-gen-deployment.yaml.bak
else
sed -i.bak -e "s|image: .*|image: $(IMG)|g" ./deploy/k8s/controller.yaml
sed -i.bak -e "s|imagePullPolicy: Always|imagePullPolicy: $(PULL_POLICY)|g" ./deploy/k8s/controller.yaml
Expand All @@ -87,7 +94,12 @@ ifeq ($(TOOL),oc)
sed -i.bak -e "s|image: $(IMG)|image: quay.io/che-incubator/che-workspace-controller:nightly|g" ./deploy/os/controller.yaml
sed -i.bak -e "s|imagePullPolicy: $(PULL_POLICY)|imagePullPolicy: Always|g" ./deploy/os/controller.yaml
sed -i.bak -e 's|kubectl.kubernetes.io/restartedAt: .*|kubectl.kubernetes.io/restartedAt: ""|g' ./deploy/os/controller.yaml

sed -i.bak -e "s|image: $(CERT_IMG)|image: quay.io/che-incubator/che-workspace-controller-cert-gen:latest|g" ./deploy/os/che-workspace-controller-cert-gen-deployment.yaml
sed -i.bak -e 's|kubectl.kubernetes.io/restartedAt: .*|kubectl.kubernetes.io/restartedAt: ""|g' ./deploy/os/che-workspace-controller-cert-gen-deployment.yaml

rm ./deploy/os/controller.yaml.bak
rm ./deploy/os/che-workspace-controller-cert-gen-deployment.yaml.bak
else
sed -i.bak -e "s|image: $(IMG)|image: quay.io/che-incubator/che-workspace-controller:nightly|g" ./deploy/k8s/controller.yaml
sed -i.bak -e "s|imagePullPolicy: $(PULL_POLICY)|imagePullPolicy: Always|g" ./deploy/k8s/controller.yaml
Expand All @@ -104,7 +116,10 @@ _update_controller_configmap:
_apply_controller_cfg:
$(TOOL) apply -f ./deploy
ifeq ($(TOOL),oc)
$(TOOL) apply -f ./deploy/os/
ifeq ($(WEBHOOK_ENABLED),true)
$(TOOL) apply -f ./deploy/os/che-workspace-controller-cert-gen-deployment.yaml
endif
$(TOOL) apply -f ./deploy/os/controller.yaml
else
$(TOOL) apply -f ./deploy/k8s/controller.yaml
endif
Expand Down Expand Up @@ -142,6 +157,11 @@ docker: _print_vars
docker build -t $(IMG) -f ./build/Dockerfile .
docker push $(IMG)

### docker_cert: build and push docker cert image
docker_cert: _print_vars
docker build -t $(CERT_IMG) -f ./cert-generation/Dockerfile .
docker push $(CERT_IMG)

### webhook: generate certificates for webhooks and deploy to cluster; no-op if running on OpenShift
webhook:
ifeq ($(WEBHOOK_ENABLED),true)
Expand Down Expand Up @@ -226,3 +246,4 @@ help: Makefile
@echo ' WEBHOOK_ENABLED - Whether webhooks should be enabled in the deployment'
@echo ' ADMIN_CTX - Kubectx entry that should be used during work with cluster. The current will be used if omitted'
@echo ' REGISTRY_ENABLED - Whether the plugin registry should be deployed'
@echo ' CERT_IMG - The name of the cert generator image'
31 changes: 31 additions & 0 deletions cert-generation/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
FROM golang:1.13.7-alpine3.11 as builder

WORKDIR /che-workspace-operator

# Populate the module cache based on the go.{mod,sum} files.
COPY go.mod .
COPY go.sum .
RUN go mod download

# copy the rest of the sources code
COPY . .
# compile workspace controller binaries
RUN CGO_ENABLED=0 GOOS=linux go build \
-o _output/bin/che-workspace-controller-cert-gen \
-gcflags all=-trimpath=/ \
-asmflags all=-trimpath=/ \
cert-generation/main.go

FROM registry.access.redhat.com/ubi8-minimal:8.1-279
COPY --from=builder /che-workspace-operator/_output/bin/che-workspace-controller-cert-gen /usr/local/bin/che-workspace-controller-cert-gen

ENV USER_UID=1001 \
USER_NAME=che-workspace-controller-cert-gen

COPY build/bin /usr/local/bin
RUN /usr/local/bin/user_setup

USER ${USER_UID}

ENTRYPOINT ["/usr/local/bin/entrypoint"]
CMD /usr/local/bin/che-workspace-controller-cert-gen
109 changes: 46 additions & 63 deletions pkg/webhook/server/cert_cfg.go → cert-generation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,60 @@
// Red Hat, Inc. - initial API and implementation
//

package server
package main

import (
"io/ioutil"
"os"

"k8s.io/apimachinery/pkg/util/intstr"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

const (
secureServiceName = "workspace-controller"
certConfigMapName = "che-workspace-controller-secure-service"
certSecretName = "workspace-controller"
certVolumeName = "webhook-tls-certs"
webhookServerName = "webhook-server"
)

func getSecureServiceSpec(namespace string) *corev1.Service {
func main() {
config, err := rest.InClusterConfig()
if err != nil {
os.Exit(1)
}

clientset, err := kubernetes.NewForConfig(config)
if err != nil {
os.Exit(1)
}

namespaceByte, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
if err != nil {
os.Exit(1)
}

namespace := string(namespaceByte)
configMapData := make(map[string]string, 0)
configMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: certConfigMapName,
Namespace: namespace,
Annotations: map[string]string{
"service.beta.openshift.io/inject-cabundle": "true",
},
},
Data: configMapData,
}
_, err = clientset.CoreV1().ConfigMaps(namespace).Create(configMap)
if err != nil {
os.Exit(1)
}

label := map[string]string{"app": "che-workspace-controller"}

port := int32(443)
Expand All @@ -50,66 +87,12 @@ func getSecureServiceSpec(namespace string) *corev1.Service {
Selector: label,
},
}

return service
}

func getSecureConfigMapSpec(namespace string) *corev1.ConfigMap {
return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: certConfigMapName,
Namespace: namespace,
Annotations: map[string]string{
"service.beta.openshift.io/inject-cabundle": "true",
},
},
_, err = clientset.CoreV1().Services(namespace).Create(service)
if err != nil {
os.Exit(1)
}
}

func getCertVolume() corev1.Volume {
return corev1.Volume{
Name: certVolumeName,
VolumeSource: corev1.VolumeSource{
Projected: &corev1.ProjectedVolumeSource{
Sources: []corev1.VolumeProjection{
{
ConfigMap: &corev1.ConfigMapProjection{
LocalObjectReference: corev1.LocalObjectReference{
Name: certConfigMapName,
},
Items: []corev1.KeyToPath{
{
Key: "service-ca.crt",
Path: "./ca.crt",
},
},
},
},
{
Secret: &corev1.SecretProjection{
LocalObjectReference: corev1.LocalObjectReference{
Name: certSecretName,
},
},
},
},
},
},
}
}

func getCertVolumeMount() corev1.VolumeMount {
return corev1.VolumeMount{
Name: certVolumeName,
MountPath: webhookServerCertDir,
ReadOnly: true,
}
}

func getPort() corev1.ContainerPort {
port := int32(8443)
return corev1.ContainerPort{
ContainerPort: port,
Name: webhookServerName,
// Wait until its cleaned up by the workspace-controller
for {
}
}
23 changes: 23 additions & 0 deletions deploy/os/che-workspace-controller-cert-gen-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: che-workspace-controller-cert-gen
namespace: che-workspace-controller
spec:
replicas: 1
selector:
matchLabels:
app: che-workspace-controller-cert-gen
template:
metadata:
labels:
app: che-workspace-controller-cert-gen
annotations:
kubectl.kubernetes.io/restartedAt: ""
spec:
serviceAccountName: che-workspace-controller
containers:
- name: che-workspace-controller-cert-gen
image: quay.io/che-incubator/che-workspace-controller-cert-gen:latest
imagePullPolicy: Always

15 changes: 15 additions & 0 deletions deploy/os/controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,18 @@ spec:
ports:
- name: webhook-server
containerPort: 8443
volumeMounts:
- name: webhook-tls-certs
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
volumes:
- name: webhook-tls-certs
projected:
sources:
- configMap:
name: che-workspace-controller-secure-service
items:
- key: service-ca.crt
path: ./ca.crt
- secret:
name: workspace-controller
8 changes: 2 additions & 6 deletions pkg/webhook/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package server

import (
"context"
"errors"
"io/ioutil"
"os"

Expand Down Expand Up @@ -54,12 +55,7 @@ func ConfigureWebhookServer(mgr manager.Manager, ctx context.Context) error {

CABundle, err = ioutil.ReadFile(webhookServerCertDir + "/ca.crt")
if os.IsNotExist(err) {
log.Info("CA certificate is not found. Webhook server will now attempt to setup")
err = InitWebhookServer(ctx)
if err != nil {
return err
}
return nil
return errors.New("CA certificate is not found. Unable to setup webhook server")
}
if err != nil {
return err
Expand Down
Loading

0 comments on commit 1a9c8db

Please sign in to comment.