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 9, 2020
1 parent 19ebfea commit f7f7e0f
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 319 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
127 changes: 127 additions & 0 deletions cert-generation/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//
// Copyright (c) 2019-2020 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//

package main

import (
"io/ioutil"
"log"
"os"

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

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

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

func main() {
log.SetOutput(os.Stdout)

config, err := rest.InClusterConfig()
if err != nil {
log.Fatal("Failed when attempting to retrieve in cluster config: ", err)
}

clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal("Failed when attempting to retrieve in cluster config: ", err)
}

namespaceByte, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
if err != nil {
log.Fatal("Could not retrieve namespace: ", err)
}

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,
}

// Create the configmap or update if it already exists
if _, err := clientset.CoreV1().ConfigMaps(namespace).Get(certConfigMapName, metav1.GetOptions{}); errors.IsNotFound(err) {
_, err = clientset.CoreV1().ConfigMaps(namespace).Create(configMap)
if err != nil {
log.Fatal("Failed when attempting to create configmap: ", err)
}
} else {
_, err = clientset.CoreV1().ConfigMaps(namespace).Update(configMap)
if err != nil {
log.Fatal("Failed when attempting to update configmap: ", err)
}
}

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

port := int32(443)
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: secureServiceName,
Namespace: namespace,
Labels: label,
Annotations: map[string]string{
"service.beta.openshift.io/serving-cert-secret-name": certSecretName,
},
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Port: port,
Protocol: "TCP",
TargetPort: intstr.FromString(webhookServerName),
},
},
Selector: label,
},
}

// Create secure service or update it if it already exists
if clusterService, err := clientset.CoreV1().Services(namespace).Get(secureServiceName, metav1.GetOptions{}); errors.IsNotFound(err) {
_, err = clientset.CoreV1().Services(namespace).Create(service)
if err != nil {
log.Fatal("Failed when attempting to create service: ", err)
}
} else {
// Cannot naively copy spec, as clusterIP is unmodifiable
clusterIP := clusterService.Spec.ClusterIP
service.Spec = clusterService.Spec
service.Spec.ClusterIP = clusterIP
service.ResourceVersion = clusterService.ResourceVersion

_, err = clientset.CoreV1().Services(namespace).Update(service)
if err != nil {
log.Fatal("Failed when attempting to update service: ", err)
}
}

// Wait until it's cleaned up by the workspace-controller
log.Println("I've done my work and waiting to be utilized. Don't feel sorry for me I was initially designed to die if everything is fine")
for {
}
}
22 changes: 22 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,22 @@
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
115 changes: 0 additions & 115 deletions pkg/webhook/server/cert_cfg.go

This file was deleted.

Loading

0 comments on commit f7f7e0f

Please sign in to comment.