Skip to content
This repository has been archived by the owner on Oct 30, 2024. It is now read-only.

Commit

Permalink
Add k8s resources, restructure flags and add Circle / Architect (#16)
Browse files Browse the repository at this point in the history
* Restructure flags to follow g8s naming convention.

* Deployment and configmap and updated readme with how to create the secret

* Save certificates as k8s secrets and implement delete watch (#15)

* addFunc saves the certificate as a k8s secret

* deleteFunc deletes the k8s secret that stores the certificate

* Creating and deleting secrets should both be idempotent

* Label the secret with clusterComponent received from the TPO

* Updated certificatetpr dev

* Restructure flags to follow g8s naming convention.

* Deployment and configmap and updated readme with how to create the secret

* Fix Vault flag structure

* Fix typo in Vault token error message

* Fix secret name and the quoting of the CLI args

* Add Circle CI for architect builds

* TLS.CertFile should be TLS.CrtFile
  • Loading branch information
rossf7 authored Mar 24, 2017
1 parent aefe74b commit 48257b0
Show file tree
Hide file tree
Showing 25 changed files with 235 additions and 58 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![CircleCI](https://circleci.com/gh/giantswarm/cert-operator.svg?style=svg)](https://circleci.com/gh/giantswarm/cert-operator)

# cert-operator

Cert Operator creates/configure/manages certificates for Kubernetes clusters running on Giantnetes.
Expand Down Expand Up @@ -46,3 +48,32 @@ cert-operator is under the Apache 2.0 license. See the [LICENSE](LICENSE) file f
## Credit
- https://golang.org
- https://github.com/giantswarm/microkit


### Secrets
The cert-operator is deployed via Kubernetes.

Here the plain Vault token has to be inserted.
```
service:
vault:
config:
token: 'TODO'
```

Here the base64 representation of the data structure above has to be inserted.
```
apiVersion: v1
kind: Secret
metadata:
name: cert-operator-secret
namespace: giantswarm
type: Opaque
data:
secret.yml: 'TODO'
```

To create the secret manually do this.
```
kubectl create -f ./path/to/secret.yml
```
20 changes: 20 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
machine:
services:
- docker

dependencies:
override:
- |
wget -q $(curl -sS -H "Authorization: token $RELEASE_TOKEN" https://api.github.com/repos/giantswarm/architect/releases/latest | grep browser_download_url | head -n 1 | cut -d '"' -f 4)
- chmod +x ./architect
- ./architect version

test:
override:
- ./architect build --golang-version=1.8.0

deployment:
master:
branch: master
commands:
- ./architect deploy
12 changes: 6 additions & 6 deletions client/k8s/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ type Config struct {

func newRawClientConfig(config Config) *rest.Config {
tlsClientConfig := rest.TLSClientConfig{
CertFile: config.Viper.GetString(config.Flag.Kubernetes.TLS.CertFile),
KeyFile: config.Viper.GetString(config.Flag.Kubernetes.TLS.KeyFile),
CAFile: config.Viper.GetString(config.Flag.Kubernetes.TLS.CAFile),
CertFile: config.Viper.GetString(config.Flag.Service.Kubernetes.TLS.CrtFile),
KeyFile: config.Viper.GetString(config.Flag.Service.Kubernetes.TLS.KeyFile),
CAFile: config.Viper.GetString(config.Flag.Service.Kubernetes.TLS.CAFile),
}
rawClientConfig := &rest.Config{
Host: config.Viper.GetString(config.Flag.Kubernetes.Address),
Host: config.Viper.GetString(config.Flag.Service.Kubernetes.Address),
QPS: MaxQPS,
Burst: MaxBurst,
TLSClientConfig: tlsClientConfig,
Expand All @@ -48,9 +48,9 @@ func getRawClientConfig(config Config) (*rest.Config, error) {
var rawClientConfig *rest.Config
var err error

address := config.Viper.GetString(config.Flag.Kubernetes.Address)
address := config.Viper.GetString(config.Flag.Service.Kubernetes.Address)

if config.Viper.GetBool(config.Flag.Kubernetes.InCluster) {
if config.Viper.GetBool(config.Flag.Service.Kubernetes.InCluster) {
config.Logger.Log("debug", "creating in-cluster config")
rawClientConfig, err = rest.InClusterConfig()
if err != nil {
Expand Down
14 changes: 7 additions & 7 deletions client/k8s/k8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestGetRawClientConfig(t *testing.T) {
}
}

certFile := "/var/run/kubernetes/client-admin.crt"
crtFile := "/var/run/kubernetes/client-admin.crt"
keyFile := "/var/run/kubernetes/client-admin.key"
caFile := "/var/run/kubernetes/server-ca.crt"

Expand Down Expand Up @@ -65,11 +65,11 @@ func TestGetRawClientConfig(t *testing.T) {
f := flag.New()
v := viper.New()

v.Set(f.Kubernetes.InCluster, tc.inCluster)
v.Set(f.Kubernetes.Address, tc.expectedAddress)
v.Set(f.Kubernetes.TLS.CertFile, certFile)
v.Set(f.Kubernetes.TLS.KeyFile, keyFile)
v.Set(f.Kubernetes.TLS.CAFile, caFile)
v.Set(f.Service.Kubernetes.InCluster, tc.inCluster)
v.Set(f.Service.Kubernetes.Address, tc.expectedAddress)
v.Set(f.Service.Kubernetes.TLS.CrtFile, crtFile)
v.Set(f.Service.Kubernetes.TLS.KeyFile, keyFile)
v.Set(f.Service.Kubernetes.TLS.CAFile, caFile)

config := Config{
Logger: newLogger,
Expand All @@ -85,7 +85,7 @@ func TestGetRawClientConfig(t *testing.T) {
}
assert.Nil(t, err, fmt.Sprintf("[%s] An error was unexpected", tc.name))
assert.Equal(t, tc.expectedAddress, rawClientConfig.Host, fmt.Sprintf("[%s] Hosts should be equal", tc.name))
assert.Equal(t, certFile, rawClientConfig.TLSClientConfig.CertFile, fmt.Sprintf("[%s] CertFiles should be equal", tc.name))
assert.Equal(t, crtFile, rawClientConfig.TLSClientConfig.CertFile, fmt.Sprintf("[%s] CertFiles should be equal", tc.name))
assert.Equal(t, keyFile, rawClientConfig.TLSClientConfig.KeyFile, fmt.Sprintf("[%s] KeyFiles should be equal", tc.name))
assert.Equal(t, caFile, rawClientConfig.TLSClientConfig.CAFile, fmt.Sprintf("[%s] CAFiles should be equal", tc.name))
}
Expand Down
6 changes: 3 additions & 3 deletions client/vault/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ type Config struct {
}

func NewClient(config Config) (*vaultapi.Client, error) {
address := config.Viper.GetString(config.Flag.Vault.Address)
token := config.Viper.GetString(config.Flag.Vault.Token)
address := config.Viper.GetString(config.Flag.Service.Vault.Config.Address)
token := config.Viper.GetString(config.Flag.Service.Vault.Config.Token)

if address == "" {
return nil, microerror.MaskAnyf(invalidConfigError, "vault address must not be empty")
Expand All @@ -32,7 +32,7 @@ func NewClient(config Config) (*vaultapi.Client, error) {
}

if token == "" {
return nil, microerror.MaskAnyf(invalidConfigError, "vault address must not be empty")
return nil, microerror.MaskAnyf(invalidConfigError, "vault token must not be empty")
}

newClientConfig := vaultapi.DefaultConfig()
Expand Down
4 changes: 2 additions & 2 deletions client/vault/vault_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ func TestNewClient(t *testing.T) {
f := flag.New()
v := viper.New()

v.Set(f.Vault.Address, tc.address)
v.Set(f.Vault.Token, tc.token)
v.Set(f.Service.Vault.Config.Address, tc.address)
v.Set(f.Service.Vault.Config.Token, tc.token)

config := Config{
Flag: f,
Expand Down
6 changes: 2 additions & 4 deletions flag/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package flag
import (
"github.com/giantswarm/microkit/flag"

"github.com/giantswarm/cert-operator/flag/kubernetes"
"github.com/giantswarm/cert-operator/flag/vault"
"github.com/giantswarm/cert-operator/flag/service"
)

type Flag struct {
Kubernetes kubernetes.Kubernetes
Vault vault.Vault
Service service.Service
}

func New() *Flag {
Expand Down
7 changes: 0 additions & 7 deletions flag/kubernetes/tls/tls.go

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package kubernetes

import (
"github.com/giantswarm/cert-operator/flag/kubernetes/tls"
"github.com/giantswarm/cert-operator/flag/service/kubernetes/tls"
)

type Kubernetes struct {
Expand Down
7 changes: 7 additions & 0 deletions flag/service/kubernetes/tls/tls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tls

type TLS struct {
CAFile string
CrtFile string
KeyFile string
}
11 changes: 11 additions & 0 deletions flag/service/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package service

import (
"github.com/giantswarm/cert-operator/flag/service/kubernetes"
"github.com/giantswarm/cert-operator/flag/service/vault"
)

type Service struct {
Kubernetes kubernetes.Kubernetes
Vault vault.Vault
}
12 changes: 12 additions & 0 deletions flag/service/vault/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package config

import (
"github.com/giantswarm/cert-operator/flag/service/vault/config/pki"
)

type Config struct {
Address string
Token string

PKI pki.PKI
}
5 changes: 5 additions & 0 deletions flag/service/vault/config/pki/ca/ca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ca

type CA struct {
TTL string
}
5 changes: 5 additions & 0 deletions flag/service/vault/config/pki/commonname/commonname.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package commonname

type CommonName struct {
Format string
}
11 changes: 11 additions & 0 deletions flag/service/vault/config/pki/pki.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package pki

import (
"github.com/giantswarm/cert-operator/flag/service/vault/config/pki/ca"
"github.com/giantswarm/cert-operator/flag/service/vault/config/pki/commonname"
)

type PKI struct {
CA ca.CA
CommonName commonname.CommonName
}
5 changes: 5 additions & 0 deletions flag/service/vault/pki/ca/ca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ca

type CA struct {
TTL string
}
5 changes: 5 additions & 0 deletions flag/service/vault/pki/commonname/commonname.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package commonname

type CommonName struct {
Format string
}
12 changes: 12 additions & 0 deletions flag/service/vault/pki/pki.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package pki

import (
"github.com/giantswarm/cert-operator/flag/service/vault/pki/ca"
"github.com/giantswarm/cert-operator/flag/service/vault/pki/commonname"
)

type PKI struct {
CA ca.CA
CATTL string
CommonName commonname.CommonName
}
9 changes: 9 additions & 0 deletions flag/service/vault/vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package vault

import (
"github.com/giantswarm/cert-operator/flag/service/vault/config"
)

type Vault struct {
Config config.Config
}
6 changes: 0 additions & 6 deletions flag/vault/pki/pki.go

This file was deleted.

11 changes: 0 additions & 11 deletions flag/vault/vault.go

This file was deleted.

19 changes: 19 additions & 0 deletions kubernetes/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: cert-operator-configmap
namespace: giantswarm
data:
config.yml: |
server:
listen:
address: 'http://0.0.0.0:8000'
service:
vault:
config:
address: 'https://leaseweb-vault-private.giantswarm.io:8200'
pki:
ca:
ttl: '86400h'
commonname:
format: '%s.g8s.fra-1.giantswarm.io'
51 changes: 51 additions & 0 deletions kubernetes/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: cert-operator
namespace: giantswarm
labels:
app: cert-operator
spec:
replicas: 2
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: cert-operator
spec:
volumes:
- name: cert-operator-configmap
configMap:
name: cert-operator-configmap
items:
- key: config.yml
path: config.yml
- name: cert-operator-secret
secret:
secretName: cert-operator-secret
items:
- key: secret.yml
path: secret.yml
- name: certs
hostPath:
path: /etc/ssl/certs/ca-certificates.crt
containers:
- name: cert-operator
image: registry.giantswarm.io/giantswarm/cert-operator:%%DOCKER_TAG%%
volumeMounts:
- name: cert-operator-configmap
mountPath: /var/run/cert-operator/configmap/
- name: cert-operator-secret
mountPath: /var/run/cert-operator/secret/
- name: certs
mountPath: /etc/ssl/certs/ca-certificate.crt
ports:
- name: http
containerPort: 8000
args:
- daemon
- --config.dirs="/var/run/cert-operator/configmap/ /var/run/cert-operator/secret/"
- --config.files="config secret"
imagePullSecrets:
- name: circleci-giantswarm-registry
18 changes: 9 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ func main() {

daemonCommand := newCommand.DaemonCommand().CobraCommand()

daemonCommand.PersistentFlags().String(f.Kubernetes.Address, "", "Address used to connect to Kubernetes. When empty in-cluster config is created.")
daemonCommand.PersistentFlags().Bool(f.Kubernetes.InCluster, true, "Whether to use the in-cluster config to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Kubernetes.TLS.CAFile, "", "Certificate authority file path to use to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Kubernetes.TLS.CertFile, "", "Certificate file path to use to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Kubernetes.TLS.KeyFile, "", "Key file path to use to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Vault.Address, "", "Address used to connect to Vault.")
daemonCommand.PersistentFlags().String(f.Vault.Token, "", "Token used to authenticate against Vault.")
daemonCommand.PersistentFlags().String(f.Vault.PKI.CATTL, "", "TTL used to generate a new Cluster CA.")
daemonCommand.PersistentFlags().String(f.Vault.PKI.CommonNameFormat, "", "Common name used to generate a new Cluster CA.")
daemonCommand.PersistentFlags().String(f.Service.Kubernetes.Address, "", "Address used to connect to Kubernetes. When empty in-cluster config is created.")
daemonCommand.PersistentFlags().Bool(f.Service.Kubernetes.InCluster, true, "Whether to use the in-cluster config to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Service.Kubernetes.TLS.CAFile, "", "Certificate authority file path to use to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Service.Kubernetes.TLS.CrtFile, "", "Certificate file path to use to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Service.Kubernetes.TLS.KeyFile, "", "Key file path to use to authenticate with Kubernetes.")
daemonCommand.PersistentFlags().String(f.Service.Vault.Config.Address, "", "Address used to connect to Vault.")
daemonCommand.PersistentFlags().String(f.Service.Vault.Config.Token, "", "Token used to authenticate against Vault.")
daemonCommand.PersistentFlags().String(f.Service.Vault.Config.PKI.CA.TTL, "", "TTL used to generate a new Cluster CA.")
daemonCommand.PersistentFlags().String(f.Service.Vault.Config.PKI.CommonName.Format, "", "Common name used to generate a new Cluster CA.")

newCommand.CobraCommand().Execute()
}
Loading

0 comments on commit 48257b0

Please sign in to comment.