mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
2277 lines
46 KiB
Go
2277 lines
46 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package krusty_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
|
)
|
|
|
|
func TestBasicVariableRef(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
namePrefix: base-
|
|
resources:
|
|
- pod.yaml
|
|
vars:
|
|
- name: POD_NAME
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
name: clown
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
|
|
th.WriteF("pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: clown
|
|
spec:
|
|
containers:
|
|
- name: frown
|
|
image: frown
|
|
command:
|
|
- echo
|
|
- "$(POD_NAME)"
|
|
env:
|
|
- name: FOO
|
|
value: "$(POD_NAME)"
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: base-clown
|
|
spec:
|
|
containers:
|
|
- command:
|
|
- echo
|
|
- base-clown
|
|
env:
|
|
- name: FOO
|
|
value: base-clown
|
|
image: frown
|
|
name: frown
|
|
`)
|
|
}
|
|
|
|
func TestBasicVarCollision(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base1", `
|
|
namePrefix: base1-
|
|
resources:
|
|
- pod.yaml
|
|
vars:
|
|
- name: POD_NAME
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
name: kelley
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base1/pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: kelley
|
|
spec:
|
|
containers:
|
|
- name: smile
|
|
image: smile
|
|
command:
|
|
- echo
|
|
- "$(POD_NAME)"
|
|
env:
|
|
- name: FOO
|
|
value: "$(POD_NAME)"
|
|
`)
|
|
|
|
th.WriteK("base2", `
|
|
namePrefix: base2-
|
|
resources:
|
|
- pod.yaml
|
|
vars:
|
|
- name: POD_NAME
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
name: grimaldi
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base2/pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: grimaldi
|
|
spec:
|
|
containers:
|
|
- name: dance
|
|
image: dance
|
|
command:
|
|
- echo
|
|
- "$(POD_NAME)"
|
|
env:
|
|
- name: FOO
|
|
value: "$(POD_NAME)"
|
|
`)
|
|
|
|
th.WriteK("overlay", `
|
|
resources:
|
|
- ../base1
|
|
- ../base2
|
|
`)
|
|
err := th.RunWithErr("overlay", th.MakeDefaultOptions())
|
|
if err == nil {
|
|
t.Fatalf("should have an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "var 'POD_NAME' already encountered") {
|
|
t.Fatalf("unexpected err: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVarPropagatesUp(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base1", `
|
|
namePrefix: base1-
|
|
resources:
|
|
- pod.yaml
|
|
vars:
|
|
- name: POD_NAME1
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
name: kelley
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base1/pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: kelley
|
|
spec:
|
|
containers:
|
|
- name: smile
|
|
image: smile
|
|
command:
|
|
- echo
|
|
- "$(POD_NAME1)"
|
|
env:
|
|
- name: FOO
|
|
value: "$(POD_NAME1)"
|
|
`)
|
|
|
|
th.WriteK("base2", `
|
|
namePrefix: base2-
|
|
resources:
|
|
- pod.yaml
|
|
vars:
|
|
- name: POD_NAME2
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
name: grimaldi
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base2/pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: grimaldi
|
|
spec:
|
|
containers:
|
|
- name: dance
|
|
image: dance
|
|
command:
|
|
- echo
|
|
- "$(POD_NAME2)"
|
|
env:
|
|
- name: FOO
|
|
value: "$(POD_NAME2)"
|
|
`)
|
|
|
|
th.WriteK("overlay", `
|
|
resources:
|
|
- pod.yaml
|
|
- ../base1
|
|
- ../base2
|
|
`)
|
|
th.WriteF("overlay/pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: circus
|
|
spec:
|
|
containers:
|
|
- name: ring
|
|
image: ring
|
|
command:
|
|
- echo
|
|
- "$(POD_NAME1)"
|
|
- "$(POD_NAME2)"
|
|
env:
|
|
- name: P1
|
|
value: "$(POD_NAME1)"
|
|
- name: P2
|
|
value: "$(POD_NAME2)"
|
|
`)
|
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: circus
|
|
spec:
|
|
containers:
|
|
- command:
|
|
- echo
|
|
- base1-kelley
|
|
- base2-grimaldi
|
|
env:
|
|
- name: P1
|
|
value: base1-kelley
|
|
- name: P2
|
|
value: base2-grimaldi
|
|
image: ring
|
|
name: ring
|
|
---
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: base1-kelley
|
|
spec:
|
|
containers:
|
|
- command:
|
|
- echo
|
|
- base1-kelley
|
|
env:
|
|
- name: FOO
|
|
value: base1-kelley
|
|
image: smile
|
|
name: smile
|
|
---
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: base2-grimaldi
|
|
spec:
|
|
containers:
|
|
- command:
|
|
- echo
|
|
- base2-grimaldi
|
|
env:
|
|
- name: FOO
|
|
value: base2-grimaldi
|
|
image: dance
|
|
name: dance
|
|
`)
|
|
}
|
|
|
|
// Not so much a bug as a desire for local variables
|
|
// with less than global scope. Currently all variables
|
|
// are global. So if a base with a variable is included
|
|
// twice, it's a collision, so it's denied.
|
|
func TestBug506(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
namePrefix: base-
|
|
resources:
|
|
- pod.yaml
|
|
vars:
|
|
- name: POD_NAME
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Pod
|
|
name: myServerPod
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base/pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: myServerPod
|
|
spec:
|
|
containers:
|
|
- name: myServer
|
|
image: whatever
|
|
env:
|
|
- name: POD_NAME
|
|
value: $(POD_NAME)
|
|
`)
|
|
th.WriteK("o1", `
|
|
nameprefix: p1-
|
|
resources:
|
|
- ../base
|
|
`)
|
|
th.WriteK("o2", `
|
|
nameprefix: p2-
|
|
resources:
|
|
- ../base
|
|
`)
|
|
th.WriteK("top", `
|
|
resources:
|
|
- ../o1
|
|
- ../o2
|
|
`)
|
|
|
|
/*
|
|
const presumablyDesired = `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: p1-base-myServerPod
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: POD_NAME
|
|
value: p1-base-myServerPod
|
|
image: whatever
|
|
name: myServer
|
|
---
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: p2-base-myServerPod
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: POD_NAME
|
|
value: p2-base-myServerPod
|
|
image: whatever
|
|
name: myServer
|
|
`
|
|
*/
|
|
err := th.RunWithErr("top", th.MakeDefaultOptions())
|
|
if err == nil {
|
|
t.Fatalf("should have an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "var 'POD_NAME' already encountered") {
|
|
t.Fatalf("unexpected err: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestSimpleServicePortVarReplace(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- service.yaml
|
|
- statefulset.yaml
|
|
vars:
|
|
- name: THE_PORT
|
|
objref:
|
|
kind: StatefulSet
|
|
name: cockroachdb
|
|
apiVersion: apps/v1beta1
|
|
fieldref:
|
|
fieldpath: spec.template.spec.containers[0].ports[1].containerPort
|
|
`)
|
|
th.WriteF("service.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: myService
|
|
spec:
|
|
ports:
|
|
- port: $(THE_PORT)
|
|
targetPort: $(THE_PORT)
|
|
name: grpc
|
|
`)
|
|
th.WriteF("statefulset.yaml", `
|
|
apiVersion: apps/v1beta1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: cockroachdb
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: cockroachdb
|
|
image: cockroachdb/cockroach:v1.1.5
|
|
ports:
|
|
- containerPort: 26257
|
|
name: grpc
|
|
- containerPort: 8888
|
|
name: http
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: myService
|
|
spec:
|
|
ports:
|
|
- name: grpc
|
|
port: 8888
|
|
targetPort: 8888
|
|
---
|
|
apiVersion: apps/v1beta1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: cockroachdb
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: cockroachdb/cockroach:v1.1.5
|
|
name: cockroachdb
|
|
ports:
|
|
- containerPort: 26257
|
|
name: grpc
|
|
- containerPort: 8888
|
|
name: http
|
|
`)
|
|
}
|
|
|
|
// TODO(3449): Yield bare primitives in var replacements from configmaps.
|
|
// The ConfigMap data field is always strings, and anything that looks
|
|
// like a boolean or int or float must be quoted, or the API server won't
|
|
// accept the map. This creates a problem if one wants to use a var to
|
|
// inject a raw number or raw boolean sourced from a configmap, because as
|
|
// far as the configmap representation is concerned, it's a string.
|
|
// A workaround would be to source the var from another Kind, from a field
|
|
// that allowed unquoted vars or booleans.
|
|
func TestIssue3449(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- workflow.yaml
|
|
|
|
configurations:
|
|
- kustomization-config.yaml
|
|
|
|
configMapGenerator:
|
|
- name: kustomize-vars
|
|
envs:
|
|
- vars.env
|
|
|
|
vars:
|
|
- name: DBT_TARGET
|
|
objref: &config-map-ref
|
|
kind: ConfigMap
|
|
name: kustomize-vars
|
|
version: v1
|
|
fieldref:
|
|
fieldpath: data.DBT_TARGET
|
|
- name: SUSPENDED
|
|
objref: *config-map-ref
|
|
fieldref:
|
|
fieldpath: data.SUSPENDED
|
|
`)
|
|
th.WriteF("workflow.yaml", `
|
|
apiVersion: argoproj.io/v1alpha1
|
|
kind: CronWorkflow
|
|
metadata:
|
|
name: cron-core-load-workflow
|
|
spec:
|
|
schedule: "45 2 * * *"
|
|
timezone: "Europe/Vienna"
|
|
concurrencyPolicy: Forbid
|
|
suspend: $(SUSPENDED)
|
|
workflowMetadata:
|
|
labels:
|
|
workflowName: core-load-workflow
|
|
workflowSpec:
|
|
workflowTemplateRef:
|
|
name: core-load-pipeline
|
|
arguments:
|
|
parameters:
|
|
- name: dbt_target
|
|
value: $(DBT_TARGET)
|
|
`)
|
|
th.WriteF("kustomization-config.yaml", `
|
|
nameReference:
|
|
- kind: ConfigMap
|
|
version: v1
|
|
fieldSpecs:
|
|
- kind: CronWorkflow
|
|
version: v1alpha1
|
|
path: spec/workflowSpec/arguments/parameters/value
|
|
varReference:
|
|
- path: spec/workflowSpec/arguments/parameters/value
|
|
kind: CronWorkflow
|
|
group: argoproj.io
|
|
version: v1alpha1
|
|
- path: spec
|
|
kind: CronWorkflow
|
|
group: argoproj.io
|
|
version: v1alpha1
|
|
`)
|
|
th.WriteF("vars.env", `
|
|
DBT_TARGET=development
|
|
SUSPENDED=True
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: argoproj.io/v1alpha1
|
|
kind: CronWorkflow
|
|
metadata:
|
|
name: cron-core-load-workflow
|
|
spec:
|
|
concurrencyPolicy: Forbid
|
|
schedule: 45 2 * * *
|
|
suspend: "True"
|
|
timezone: Europe/Vienna
|
|
workflowMetadata:
|
|
labels:
|
|
workflowName: core-load-workflow
|
|
workflowSpec:
|
|
arguments:
|
|
parameters:
|
|
- name: dbt_target
|
|
value: development
|
|
workflowTemplateRef:
|
|
name: core-load-pipeline
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
DBT_TARGET: development
|
|
SUSPENDED: "True"
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: kustomize-vars-7mhm8cg5kg
|
|
`)
|
|
}
|
|
|
|
func TestVarRefBig(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
namePrefix: base-
|
|
resources:
|
|
- role-stuff.yaml
|
|
- services.yaml
|
|
- statefulset.yaml
|
|
- cronjob.yaml
|
|
- pdb.yaml
|
|
configMapGenerator:
|
|
- name: test-config-map
|
|
literals:
|
|
- foo=bar
|
|
- baz=qux
|
|
vars:
|
|
- name: CDB_PUBLIC_SVC
|
|
objref:
|
|
kind: Service
|
|
name: cockroachdb-public
|
|
apiVersion: v1
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
- name: CDB_STATEFULSET_NAME
|
|
objref:
|
|
kind: StatefulSet
|
|
name: cockroachdb
|
|
apiVersion: apps/v1beta1
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
- name: CDB_HTTP_PORT
|
|
objref:
|
|
kind: StatefulSet
|
|
name: cockroachdb
|
|
apiVersion: apps/v1beta1
|
|
fieldref:
|
|
fieldpath: spec.template.spec.containers[0].ports[1].containerPort
|
|
- name: CDB_STATEFULSET_SVC
|
|
objref:
|
|
kind: Service
|
|
name: cockroachdb
|
|
apiVersion: v1
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
|
|
- name: TEST_CONFIG_MAP
|
|
objref:
|
|
kind: ConfigMap
|
|
name: test-config-map
|
|
apiVersion: v1
|
|
fieldref:
|
|
fieldpath: metadata.name`)
|
|
th.WriteF("base/cronjob.yaml", `
|
|
apiVersion: batch/v1beta1
|
|
kind: CronJob
|
|
metadata:
|
|
name: cronjob-example
|
|
spec:
|
|
schedule: "*/1 * * * *"
|
|
concurrencyPolicy: Forbid
|
|
jobTemplate:
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: cronjob-example
|
|
image: cockroachdb/cockroach:v1.1.5
|
|
command:
|
|
- echo
|
|
- "$(CDB_STATEFULSET_NAME)"
|
|
- "$(TEST_CONFIG_MAP)"
|
|
env:
|
|
- name: CDB_PUBLIC_SVC
|
|
value: "$(CDB_PUBLIC_SVC)"
|
|
`)
|
|
th.WriteF("base/services.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: cockroachdb
|
|
labels:
|
|
app: cockroachdb
|
|
annotations:
|
|
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
|
# Enable automatic monitoring of all instances when Prometheus is running in the cluster.
|
|
prometheus.io/scrape: "true"
|
|
prometheus.io/path: "_status/vars"
|
|
prometheus.io/port: "8080"
|
|
spec:
|
|
ports:
|
|
- port: 26257
|
|
targetPort: 26257
|
|
name: grpc
|
|
- port: $(CDB_HTTP_PORT)
|
|
targetPort: $(CDB_HTTP_PORT)
|
|
name: http
|
|
clusterIP: None
|
|
selector:
|
|
app: cockroachdb
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
# This service is meant to be used by clients of the database. It exposes a ClusterIP that will
|
|
# automatically load balance connections to the different database pods.
|
|
name: cockroachdb-public
|
|
labels:
|
|
app: cockroachdb
|
|
spec:
|
|
ports:
|
|
# The main port, served by gRPC, serves Postgres-flavor SQL, internode
|
|
# traffic and the cli.
|
|
- port: 26257
|
|
targetPort: 26257
|
|
name: grpc
|
|
# The secondary port serves the UI as well as health and debug endpoints.
|
|
- port: $(CDB_HTTP_PORT)
|
|
targetPort: $(CDB_HTTP_PORT)
|
|
name: http
|
|
selector:
|
|
app: cockroachdb
|
|
`)
|
|
th.WriteF("base/role-stuff.yaml", `
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: cockroachdb
|
|
labels:
|
|
app: cockroachdb
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: Role
|
|
metadata:
|
|
name: cockroachdb
|
|
labels:
|
|
app: cockroachdb
|
|
rules:
|
|
- apiGroups:
|
|
- ""
|
|
resources:
|
|
- secrets
|
|
verbs:
|
|
- create
|
|
- get
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: cockroachdb
|
|
labels:
|
|
app: cockroachdb
|
|
rules:
|
|
- apiGroups:
|
|
- certificates.k8s.io
|
|
resources:
|
|
- certificatesigningrequests
|
|
verbs:
|
|
- create
|
|
- get
|
|
- watch
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: cockroachdb
|
|
labels:
|
|
app: cockroachdb
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: Role
|
|
name: cockroachdb
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: cockroachdb
|
|
namespace: default
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: cockroachdb
|
|
labels:
|
|
app: cockroachdb
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: ClusterRole
|
|
name: cockroachdb
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: cockroachdb
|
|
namespace: default
|
|
`)
|
|
th.WriteF("base/pdb.yaml", `
|
|
apiVersion: policy/v1beta1
|
|
kind: PodDisruptionBudget
|
|
metadata:
|
|
name: cockroachdb-budget
|
|
labels:
|
|
app: cockroachdb
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: cockroachdb
|
|
maxUnavailable: 1
|
|
`)
|
|
th.WriteF("base/statefulset.yaml", `
|
|
apiVersion: apps/v1beta1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: cockroachdb
|
|
spec:
|
|
serviceName: "cockroachdb"
|
|
replicas: 3
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
spec:
|
|
serviceAccountName: cockroachdb
|
|
# Init containers are run only once in the lifetime of a pod, before
|
|
# it's started up for the first time. It has to exit successfully
|
|
# before the pod's main containers are allowed to start.
|
|
initContainers:
|
|
# The init-certs container sends a certificate signing request to the
|
|
# kubernetes cluster.
|
|
# You can see pending requests using: kubectl get csr
|
|
# CSRs can be approved using: kubectl certificate approve <csr name>
|
|
#
|
|
# All addresses used to contact a node must be specified in the --addresses arg.
|
|
#
|
|
# In addition to the node certificate and key, the init-certs entrypoint will symlink
|
|
# the cluster CA to the certs directory.
|
|
- name: init-certs
|
|
image: cockroachdb/cockroach-k8s-request-cert:0.2
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- "/bin/ash"
|
|
- "-ecx"
|
|
- "/request-cert"
|
|
- -namespace=${POD_NAMESPACE}
|
|
- -certs-dir=/cockroach-certs
|
|
- -type=node
|
|
- -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut -f 1-2 -d '.'),$(CDB_PUBLIC_SVC)
|
|
- -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
env:
|
|
- name: POD_IP
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: status.podIP
|
|
- name: POD_NAMESPACE
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.namespace
|
|
volumeMounts:
|
|
- name: certs
|
|
mountPath: /cockroach-certs
|
|
|
|
affinity:
|
|
podAntiAffinity:
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- weight: 100
|
|
podAffinityTerm:
|
|
labelSelector:
|
|
matchExpressions:
|
|
- key: app
|
|
operator: In
|
|
values:
|
|
- cockroachdb
|
|
topologyKey: kubernetes.io/hostname
|
|
containers:
|
|
- name: cockroachdb
|
|
image: cockroachdb/cockroach:v1.1.5
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- containerPort: 26257
|
|
name: grpc
|
|
- containerPort: 8080
|
|
name: http
|
|
volumeMounts:
|
|
- name: datadir
|
|
mountPath: /cockroach/cockroach-data
|
|
- name: certs
|
|
mountPath: /cockroach/cockroach-certs
|
|
command:
|
|
- "/bin/bash"
|
|
- "-ecx"
|
|
- "exec /cockroach/cockroach start --logtostderr"
|
|
- --certs-dir /cockroach/cockroach-certs
|
|
- --host $(hostname -f)
|
|
- --http-host 0.0.0.0
|
|
- --join $(CDB_STATEFULSET_NAME)-0.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-1.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-2.$(CDB_STATEFULSET_SVC)
|
|
- --cache 25%
|
|
- --max-sql-memory 25%
|
|
# No pre-stop hook is required, a SIGTERM plus some time is all that's
|
|
# needed for graceful shutdown of a node.
|
|
terminationGracePeriodSeconds: 60
|
|
volumes:
|
|
- name: datadir
|
|
persistentVolumeClaim:
|
|
claimName: datadir
|
|
- name: certs
|
|
emptyDir: {}
|
|
updateStrategy:
|
|
type: RollingUpdate
|
|
volumeClaimTemplates:
|
|
- metadata:
|
|
name: datadir
|
|
spec:
|
|
accessModes:
|
|
- "ReadWriteOnce"
|
|
resources:
|
|
requests:
|
|
storage: 1Gi
|
|
`)
|
|
th.WriteK("overlay/staging", `
|
|
namePrefix: dev-
|
|
resources:
|
|
- ../../base
|
|
`)
|
|
m := th.Run("overlay/staging", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: Role
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb
|
|
rules:
|
|
- apiGroups:
|
|
- ""
|
|
resources:
|
|
- secrets
|
|
verbs:
|
|
- create
|
|
- get
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: ClusterRole
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb
|
|
rules:
|
|
- apiGroups:
|
|
- certificates.k8s.io
|
|
resources:
|
|
- certificatesigningrequests
|
|
verbs:
|
|
- create
|
|
- get
|
|
- watch
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: RoleBinding
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: Role
|
|
name: dev-base-cockroachdb
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: dev-base-cockroachdb
|
|
namespace: default
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: ClusterRole
|
|
name: dev-base-cockroachdb
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: dev-base-cockroachdb
|
|
namespace: default
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
annotations:
|
|
prometheus.io/path: _status/vars
|
|
prometheus.io/port: "8080"
|
|
prometheus.io/scrape: "true"
|
|
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb
|
|
spec:
|
|
clusterIP: None
|
|
ports:
|
|
- name: grpc
|
|
port: 26257
|
|
targetPort: 26257
|
|
- name: http
|
|
port: 8080
|
|
targetPort: 8080
|
|
selector:
|
|
app: cockroachdb
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb-public
|
|
spec:
|
|
ports:
|
|
- name: grpc
|
|
port: 26257
|
|
targetPort: 26257
|
|
- name: http
|
|
port: 8080
|
|
targetPort: 8080
|
|
selector:
|
|
app: cockroachdb
|
|
---
|
|
apiVersion: apps/v1beta1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: dev-base-cockroachdb
|
|
spec:
|
|
replicas: 3
|
|
serviceName: dev-base-cockroachdb
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
spec:
|
|
affinity:
|
|
podAntiAffinity:
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- podAffinityTerm:
|
|
labelSelector:
|
|
matchExpressions:
|
|
- key: app
|
|
operator: In
|
|
values:
|
|
- cockroachdb
|
|
topologyKey: kubernetes.io/hostname
|
|
weight: 100
|
|
containers:
|
|
- command:
|
|
- /bin/bash
|
|
- -ecx
|
|
- exec /cockroach/cockroach start --logtostderr
|
|
- --certs-dir /cockroach/cockroach-certs
|
|
- --host $(hostname -f)
|
|
- --http-host 0.0.0.0
|
|
- --join dev-base-cockroachdb-0.dev-base-cockroachdb,dev-base-cockroachdb-1.dev-base-cockroachdb,dev-base-cockroachdb-2.dev-base-cockroachdb
|
|
- --cache 25%
|
|
- --max-sql-memory 25%
|
|
image: cockroachdb/cockroach:v1.1.5
|
|
imagePullPolicy: IfNotPresent
|
|
name: cockroachdb
|
|
ports:
|
|
- containerPort: 26257
|
|
name: grpc
|
|
- containerPort: 8080
|
|
name: http
|
|
volumeMounts:
|
|
- mountPath: /cockroach/cockroach-data
|
|
name: datadir
|
|
- mountPath: /cockroach/cockroach-certs
|
|
name: certs
|
|
initContainers:
|
|
- command:
|
|
- /bin/ash
|
|
- -ecx
|
|
- /request-cert
|
|
- -namespace=${POD_NAMESPACE}
|
|
- -certs-dir=/cockroach-certs
|
|
- -type=node
|
|
- -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut
|
|
-f 1-2 -d '.'),dev-base-cockroachdb-public
|
|
- -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
env:
|
|
- name: POD_IP
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: status.podIP
|
|
- name: POD_NAMESPACE
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.namespace
|
|
image: cockroachdb/cockroach-k8s-request-cert:0.2
|
|
imagePullPolicy: IfNotPresent
|
|
name: init-certs
|
|
volumeMounts:
|
|
- mountPath: /cockroach-certs
|
|
name: certs
|
|
serviceAccountName: dev-base-cockroachdb
|
|
terminationGracePeriodSeconds: 60
|
|
volumes:
|
|
- name: datadir
|
|
persistentVolumeClaim:
|
|
claimName: datadir
|
|
- emptyDir: {}
|
|
name: certs
|
|
updateStrategy:
|
|
type: RollingUpdate
|
|
volumeClaimTemplates:
|
|
- metadata:
|
|
name: datadir
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 1Gi
|
|
---
|
|
apiVersion: batch/v1beta1
|
|
kind: CronJob
|
|
metadata:
|
|
name: dev-base-cronjob-example
|
|
spec:
|
|
concurrencyPolicy: Forbid
|
|
jobTemplate:
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- command:
|
|
- echo
|
|
- dev-base-cockroachdb
|
|
- dev-base-test-config-map-6b85g79g7g
|
|
env:
|
|
- name: CDB_PUBLIC_SVC
|
|
value: dev-base-cockroachdb-public
|
|
image: cockroachdb/cockroach:v1.1.5
|
|
name: cronjob-example
|
|
schedule: '*/1 * * * *'
|
|
---
|
|
apiVersion: policy/v1beta1
|
|
kind: PodDisruptionBudget
|
|
metadata:
|
|
labels:
|
|
app: cockroachdb
|
|
name: dev-base-cockroachdb-budget
|
|
spec:
|
|
maxUnavailable: 1
|
|
selector:
|
|
matchLabels:
|
|
app: cockroachdb
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
baz: qux
|
|
foo: bar
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: dev-base-test-config-map-6b85g79g7g
|
|
`)
|
|
}
|
|
|
|
func TestVariableRefIngressBasic(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
resources:
|
|
- ingress.yaml
|
|
- deployment.yaml
|
|
|
|
vars:
|
|
- name: DEPLOYMENT_NAME
|
|
objref:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
name: nginxDep
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginxDep
|
|
`)
|
|
|
|
th.WriteF("ingress.yaml", `
|
|
apiVersion: networking.k8s.io/v1beta1
|
|
kind: Ingress
|
|
metadata:
|
|
name: nginxIngress
|
|
spec:
|
|
rules:
|
|
- host: $(DEPLOYMENT_NAME).example.com
|
|
tls:
|
|
- hosts:
|
|
- $(DEPLOYMENT_NAME).example.com
|
|
secretName: $(DEPLOYMENT_NAME).example.com-tls
|
|
`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: networking.k8s.io/v1beta1
|
|
kind: Ingress
|
|
metadata:
|
|
name: nginxIngress
|
|
spec:
|
|
rules:
|
|
- host: nginxDep.example.com
|
|
tls:
|
|
- hosts:
|
|
- nginxDep.example.com
|
|
secretName: nginxDep.example.com-tls
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginxDep
|
|
`)
|
|
}
|
|
|
|
func TestVariableRefIngressOverlay(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
resources:
|
|
- service.yaml
|
|
- deployment.yaml
|
|
- ingress.yaml
|
|
|
|
vars:
|
|
- name: DEPLOYMENT_NAME
|
|
objref:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
name: nginx
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base/deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/component: nginx
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:1.15.7-alpine
|
|
ports:
|
|
- name: http
|
|
containerPort: 80
|
|
`)
|
|
th.WriteF("base/ingress.yaml", `
|
|
apiVersion: networking.k8s.io/v1beta1
|
|
kind: Ingress
|
|
metadata:
|
|
name: nginx
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
rules:
|
|
- host: $(DEPLOYMENT_NAME).example.com
|
|
http:
|
|
paths:
|
|
- backend:
|
|
serviceName: nginx
|
|
servicePort: 80
|
|
path: /
|
|
tls:
|
|
- hosts:
|
|
- $(DEPLOYMENT_NAME).example.com
|
|
secretName: $(DEPLOYMENT_NAME).example.com-tls
|
|
`)
|
|
th.WriteF("base/service.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: nginx
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
ports:
|
|
- name: http
|
|
port: 80
|
|
protocol: TCP
|
|
targetPort: http
|
|
`)
|
|
th.WriteK("overlay", `
|
|
nameprefix: kustomized-
|
|
resources:
|
|
- ../base
|
|
`)
|
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
name: kustomized-nginx
|
|
spec:
|
|
ports:
|
|
- name: http
|
|
port: 80
|
|
protocol: TCP
|
|
targetPort: http
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
name: kustomized-nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/component: nginx
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
containers:
|
|
- image: nginx:1.15.7-alpine
|
|
name: nginx
|
|
ports:
|
|
- containerPort: 80
|
|
name: http
|
|
---
|
|
apiVersion: networking.k8s.io/v1beta1
|
|
kind: Ingress
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
name: kustomized-nginx
|
|
spec:
|
|
rules:
|
|
- host: kustomized-nginx.example.com
|
|
http:
|
|
paths:
|
|
- backend:
|
|
serviceName: kustomized-nginx
|
|
servicePort: 80
|
|
path: /
|
|
tls:
|
|
- hosts:
|
|
- kustomized-nginx.example.com
|
|
secretName: kustomized-nginx.example.com-tls
|
|
`)
|
|
}
|
|
|
|
func TestVariableRefMountPath(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
resources:
|
|
- deployment.yaml
|
|
- namespace.yaml
|
|
|
|
vars:
|
|
- name: NAMESPACE
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
name: my-namespace
|
|
|
|
`)
|
|
th.WriteF("base/deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: my-deployment
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: app
|
|
image: busybox
|
|
volumeMounts:
|
|
- name: my-volume
|
|
mountPath: "/$(NAMESPACE)"
|
|
env:
|
|
- name: NAMESPACE
|
|
value: $(NAMESPACE)
|
|
volumes:
|
|
- name: my-volume
|
|
emptyDir: {}
|
|
`)
|
|
th.WriteF("base/namespace.yaml", `
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: my-namespace
|
|
`)
|
|
|
|
m := th.Run("base", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: my-deployment
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: NAMESPACE
|
|
value: my-namespace
|
|
image: busybox
|
|
name: app
|
|
volumeMounts:
|
|
- mountPath: /my-namespace
|
|
name: my-volume
|
|
volumes:
|
|
- emptyDir: {}
|
|
name: my-volume
|
|
---
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: my-namespace
|
|
`)
|
|
}
|
|
|
|
func TestVariableRefMaps(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
resources:
|
|
- deployment.yaml
|
|
- namespace.yaml
|
|
vars:
|
|
- name: NAMESPACE
|
|
objref:
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
name: my-namespace
|
|
`)
|
|
th.WriteF("base/deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: my-deployment
|
|
labels:
|
|
my-label: $(NAMESPACE)
|
|
annotations:
|
|
my-annotation: $(NAMESPACE)
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: app
|
|
image: busybox
|
|
`)
|
|
th.WriteF("base/namespace.yaml", `
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: my-namespace
|
|
`)
|
|
|
|
m := th.Run("base", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
annotations:
|
|
my-annotation: my-namespace
|
|
labels:
|
|
my-label: my-namespace
|
|
name: my-deployment
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: busybox
|
|
name: app
|
|
---
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: my-namespace
|
|
`)
|
|
}
|
|
|
|
func TestVaribaleRefDifferentPrefix(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
namePrefix: base-
|
|
resources:
|
|
- dev
|
|
- test
|
|
`)
|
|
|
|
th.WriteK("base/dev", `
|
|
namePrefix: dev-
|
|
resources:
|
|
- elasticsearch-dev-service.yml
|
|
vars:
|
|
- name: elasticsearch-dev-service-name
|
|
objref:
|
|
kind: Service
|
|
name: elasticsearch
|
|
apiVersion: v1
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
|
|
`)
|
|
th.WriteF("base/dev/elasticsearch-dev-service.yml", `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: elasticsearch
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: elasticsearch
|
|
env:
|
|
- name: DISCOVERY_SERVICE
|
|
value: "$(elasticsearch-dev-service-name).monitoring.svc.cluster.local"
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: elasticsearch
|
|
spec:
|
|
ports:
|
|
- name: transport
|
|
port: 9300
|
|
protocol: TCP
|
|
clusterIP: None
|
|
`)
|
|
|
|
th.WriteK("base/test", `
|
|
namePrefix: test-
|
|
resources:
|
|
- elasticsearch-test-service.yml
|
|
vars:
|
|
- name: elasticsearch-test-service-name
|
|
objref:
|
|
kind: Service
|
|
name: elasticsearch
|
|
apiVersion: v1
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base/test/elasticsearch-test-service.yml", `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: elasticsearch
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: elasticsearch
|
|
env:
|
|
- name: DISCOVERY_SERVICE
|
|
value: "$(elasticsearch-test-service-name).monitoring.svc.cluster.local"
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: elasticsearch
|
|
spec:
|
|
ports:
|
|
- name: transport
|
|
port: 9300
|
|
protocol: TCP
|
|
clusterIP: None
|
|
`)
|
|
|
|
m := th.Run("base", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: base-dev-elasticsearch
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: DISCOVERY_SERVICE
|
|
value: base-dev-elasticsearch.monitoring.svc.cluster.local
|
|
name: elasticsearch
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: base-dev-elasticsearch
|
|
spec:
|
|
clusterIP: None
|
|
ports:
|
|
- name: transport
|
|
port: 9300
|
|
protocol: TCP
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: base-test-elasticsearch
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- env:
|
|
- name: DISCOVERY_SERVICE
|
|
value: base-test-elasticsearch.monitoring.svc.cluster.local
|
|
name: elasticsearch
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: base-test-elasticsearch
|
|
spec:
|
|
clusterIP: None
|
|
ports:
|
|
- name: transport
|
|
port: 9300
|
|
protocol: TCP
|
|
`)
|
|
}
|
|
|
|
func TestVariableRefNFSServer(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK("base", `
|
|
resources:
|
|
- pv_pvc.yaml
|
|
- nfs_deployment.yaml
|
|
- nfs_service.yaml
|
|
- Deployment.yaml
|
|
- CronJob.yaml
|
|
- DaemonSet.yaml
|
|
- ReplicaSet.yaml
|
|
- StatefulSet.yaml
|
|
- Pod.yaml
|
|
- Job.yaml
|
|
- nfs_pv.yaml
|
|
|
|
vars:
|
|
- name: NFS_SERVER_SERVICE_NAME
|
|
objref:
|
|
kind: Service
|
|
name: nfs-server-service
|
|
apiVersion: v1
|
|
fieldref:
|
|
fieldpath: metadata.name
|
|
`)
|
|
th.WriteF("base/pv_pvc.yaml", `
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: shared-volume-claim
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 10Gi
|
|
`)
|
|
th.WriteF("base/nfs_deployment.yaml", `
|
|
apiVersion: extensions/v1beta1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nfs-server
|
|
spec:
|
|
replicas: 1
|
|
template:
|
|
spec:
|
|
metadata:
|
|
labels:
|
|
role: nfs-server
|
|
containers:
|
|
- name: nfs-server
|
|
image: gcr.io/google_containers/volume-nfs:0.8
|
|
ports:
|
|
- name: nfs
|
|
containerPort: 2049
|
|
- name: mountd
|
|
containerPort: 20048
|
|
- name: rpcbind
|
|
containerPort: 111
|
|
securityContext:
|
|
privileged: true
|
|
volumeMounts:
|
|
- mountPath: /exports
|
|
name: shared-files
|
|
volumes:
|
|
- name: shared-files
|
|
persistentVolumeClaim:
|
|
claimName: shared-volume-claim
|
|
`)
|
|
th.WriteF("base/nfs_service.yaml", `
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: nfs-server-service
|
|
spec:
|
|
ports:
|
|
- name: nfs
|
|
port: 2049
|
|
- name: mountd
|
|
port: 20048
|
|
- name: rpcbind
|
|
port: 111
|
|
selector:
|
|
role: nfs-server
|
|
`)
|
|
th.WriteF("base/Deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nginx
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/component: nginx
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:1.15.7-alpine
|
|
ports:
|
|
- name: http
|
|
containerPort: 80
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
`)
|
|
th.WriteF("base/CronJob.yaml", `
|
|
apiVersion: batch/v1beta1
|
|
kind: CronJob
|
|
metadata:
|
|
name: hello
|
|
spec:
|
|
schedule: "*/1 * * * *"
|
|
jobTemplate:
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: hello
|
|
image: busybox
|
|
args:
|
|
- /bin/sh
|
|
- -c
|
|
- date; echo Hello from the Kubernetes cluster
|
|
restartPolicy: OnFailure
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
`)
|
|
th.WriteF("base/DaemonSet.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: DaemonSet
|
|
metadata:
|
|
name: fluentd-elasticsearch
|
|
namespace: kube-system
|
|
labels:
|
|
k8s-app: fluentd-logging
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
name: fluentd-elasticsearch
|
|
template:
|
|
metadata:
|
|
labels:
|
|
name: fluentd-elasticsearch
|
|
spec:
|
|
tolerations:
|
|
- key: node-role.kubernetes.io/master
|
|
effect: NoSchedule
|
|
containers:
|
|
- name: fluentd-elasticsearch
|
|
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
|
|
resources:
|
|
limits:
|
|
memory: 200Mi
|
|
requests:
|
|
cpu: 100m
|
|
memory: 200Mi
|
|
volumeMounts:
|
|
- name: varlog
|
|
mountPath: /var/log
|
|
- name: varlibdockercontainers
|
|
mountPath: /var/lib/docker/containers
|
|
readOnly: true
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
terminationGracePeriodSeconds: 30
|
|
volumes:
|
|
- name: varlog
|
|
hostPath:
|
|
path: /var/log
|
|
- name: varlibdockercontainers
|
|
hostPath:
|
|
path: /var/lib/docker/containers
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
`)
|
|
th.WriteF("base/ReplicaSet.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: ReplicaSet
|
|
metadata:
|
|
name: frontend
|
|
labels:
|
|
app: guestbook
|
|
tier: frontend
|
|
spec:
|
|
# modify replicas according to your case
|
|
replicas: 3
|
|
selector:
|
|
matchLabels:
|
|
tier: frontend
|
|
template:
|
|
metadata:
|
|
labels:
|
|
tier: frontend
|
|
spec:
|
|
containers:
|
|
- name: php-redis
|
|
image: gcr.io/google_samples/gb-frontend:v3
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
`)
|
|
|
|
th.WriteF("base/Job.yaml", `
|
|
apiVersion: batch/v1
|
|
kind: Job
|
|
metadata:
|
|
name: pi
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: pi
|
|
image: perl
|
|
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
restartPolicy: Never
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
backoffLimit: 4
|
|
`)
|
|
th.WriteF("base/StatefulSet.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: web
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: nginx # has to match .spec.template.metadata.labels
|
|
serviceName: "nginx"
|
|
replicas: 3 # by default is 1
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: nginx # has to match .spec.selector.matchLabels
|
|
spec:
|
|
terminationGracePeriodSeconds: 10
|
|
containers:
|
|
- name: nginx
|
|
image: registry.k8s.io/nginx-slim:0.8
|
|
ports:
|
|
- containerPort: 80
|
|
name: web
|
|
volumeMounts:
|
|
- name: www
|
|
mountPath: /usr/share/nginx/html
|
|
volumeClaimTemplates:
|
|
- metadata:
|
|
name: www
|
|
spec:
|
|
accessModes: [ "ReadWriteMany" ]
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
`)
|
|
th.WriteF("base/Pod.yaml", `
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: myapp-pod
|
|
labels:
|
|
app: myapp
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:1.15.7-alpine
|
|
ports:
|
|
- name: http
|
|
containerPort: 80
|
|
volumeMounts:
|
|
- name: nfs-files-vol
|
|
mountPath: shared-files
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
`)
|
|
th.WriteF("base/nfs_pv.yaml", `
|
|
apiVersion: v1
|
|
kind: PersistentVolume
|
|
metadata:
|
|
name: nfs-files-pv
|
|
spec:
|
|
capacity:
|
|
storage: 10Gi
|
|
accessModes:
|
|
- ReadWriteMany
|
|
nfs:
|
|
server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
|
|
path: /
|
|
readOnly: false
|
|
`)
|
|
th.WriteK("overlay", `
|
|
nameprefix: kustomized-
|
|
resources:
|
|
- ../base
|
|
`)
|
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: kustomized-shared-volume-claim
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 10Gi
|
|
---
|
|
apiVersion: extensions/v1beta1
|
|
kind: Deployment
|
|
metadata:
|
|
name: kustomized-nfs-server
|
|
spec:
|
|
replicas: 1
|
|
template:
|
|
spec:
|
|
containers:
|
|
- image: gcr.io/google_containers/volume-nfs:0.8
|
|
name: nfs-server
|
|
ports:
|
|
- containerPort: 2049
|
|
name: nfs
|
|
- containerPort: 20048
|
|
name: mountd
|
|
- containerPort: 111
|
|
name: rpcbind
|
|
securityContext:
|
|
privileged: true
|
|
volumeMounts:
|
|
- mountPath: /exports
|
|
name: shared-files
|
|
metadata:
|
|
labels:
|
|
role: nfs-server
|
|
volumes:
|
|
- name: shared-files
|
|
persistentVolumeClaim:
|
|
claimName: kustomized-shared-volume-claim
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: kustomized-nfs-server-service
|
|
spec:
|
|
ports:
|
|
- name: nfs
|
|
port: 2049
|
|
- name: mountd
|
|
port: 20048
|
|
- name: rpcbind
|
|
port: 111
|
|
selector:
|
|
role: nfs-server
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
name: kustomized-nginx
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/component: nginx
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/component: nginx
|
|
spec:
|
|
containers:
|
|
- image: nginx:1.15.7-alpine
|
|
name: nginx
|
|
ports:
|
|
- containerPort: 80
|
|
name: http
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
---
|
|
apiVersion: batch/v1beta1
|
|
kind: CronJob
|
|
metadata:
|
|
name: kustomized-hello
|
|
spec:
|
|
jobTemplate:
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- args:
|
|
- /bin/sh
|
|
- -c
|
|
- date; echo Hello from the Kubernetes cluster
|
|
image: busybox
|
|
name: hello
|
|
restartPolicy: OnFailure
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
schedule: '*/1 * * * *'
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: DaemonSet
|
|
metadata:
|
|
labels:
|
|
k8s-app: fluentd-logging
|
|
name: kustomized-fluentd-elasticsearch
|
|
namespace: kube-system
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
name: fluentd-elasticsearch
|
|
template:
|
|
metadata:
|
|
labels:
|
|
name: fluentd-elasticsearch
|
|
spec:
|
|
containers:
|
|
- image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
|
|
name: fluentd-elasticsearch
|
|
resources:
|
|
limits:
|
|
memory: 200Mi
|
|
requests:
|
|
cpu: 100m
|
|
memory: 200Mi
|
|
volumeMounts:
|
|
- mountPath: /var/log
|
|
name: varlog
|
|
- mountPath: /var/lib/docker/containers
|
|
name: varlibdockercontainers
|
|
readOnly: true
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
terminationGracePeriodSeconds: 30
|
|
tolerations:
|
|
- effect: NoSchedule
|
|
key: node-role.kubernetes.io/master
|
|
volumes:
|
|
- hostPath:
|
|
path: /var/log
|
|
name: varlog
|
|
- hostPath:
|
|
path: /var/lib/docker/containers
|
|
name: varlibdockercontainers
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: ReplicaSet
|
|
metadata:
|
|
labels:
|
|
app: guestbook
|
|
tier: frontend
|
|
name: kustomized-frontend
|
|
spec:
|
|
replicas: 3
|
|
selector:
|
|
matchLabels:
|
|
tier: frontend
|
|
template:
|
|
metadata:
|
|
labels:
|
|
tier: frontend
|
|
spec:
|
|
containers:
|
|
- image: gcr.io/google_samples/gb-frontend:v3
|
|
name: php-redis
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: kustomized-web
|
|
spec:
|
|
replicas: 3
|
|
selector:
|
|
matchLabels:
|
|
app: nginx
|
|
serviceName: nginx
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: nginx
|
|
spec:
|
|
containers:
|
|
- image: registry.k8s.io/nginx-slim:0.8
|
|
name: nginx
|
|
ports:
|
|
- containerPort: 80
|
|
name: web
|
|
volumeMounts:
|
|
- mountPath: /usr/share/nginx/html
|
|
name: www
|
|
terminationGracePeriodSeconds: 10
|
|
volumeClaimTemplates:
|
|
- metadata:
|
|
name: www
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteMany
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
---
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
labels:
|
|
app: myapp
|
|
name: kustomized-myapp-pod
|
|
spec:
|
|
containers:
|
|
- image: nginx:1.15.7-alpine
|
|
name: nginx
|
|
ports:
|
|
- containerPort: 80
|
|
name: http
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
---
|
|
apiVersion: batch/v1
|
|
kind: Job
|
|
metadata:
|
|
name: kustomized-pi
|
|
spec:
|
|
backoffLimit: 4
|
|
template:
|
|
spec:
|
|
containers:
|
|
- command:
|
|
- perl
|
|
- -Mbignum=bpi
|
|
- -wle
|
|
- print bpi(2000)
|
|
image: perl
|
|
name: pi
|
|
volumeMounts:
|
|
- mountPath: shared-files
|
|
name: nfs-files-vol
|
|
restartPolicy: Never
|
|
volumes:
|
|
- name: nfs-files-vol
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
---
|
|
apiVersion: v1
|
|
kind: PersistentVolume
|
|
metadata:
|
|
name: kustomized-nfs-files-pv
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteMany
|
|
capacity:
|
|
storage: 10Gi
|
|
nfs:
|
|
path: /
|
|
readOnly: false
|
|
server: kustomized-nfs-server-service.default.srv.cluster.local
|
|
`)
|
|
}
|
|
|
|
func TestDeploymentAnnotations(t *testing.T) {
|
|
th := kusttest_test.MakeHarness(t)
|
|
th.WriteK(".", `
|
|
configMapGenerator:
|
|
- name: theConfigMap
|
|
envs:
|
|
- test.properties
|
|
|
|
vars:
|
|
- name: SOMERIVER
|
|
objref:
|
|
kind: ConfigMap
|
|
name: theConfigMap
|
|
apiVersion: v1
|
|
fieldref:
|
|
fieldpath: data.waterway
|
|
|
|
commonAnnotations:
|
|
river: $(SOMERIVER)
|
|
|
|
resources:
|
|
- deployment.yaml
|
|
`)
|
|
|
|
th.WriteF("deployment.yaml", `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: theDeployment
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: test
|
|
`)
|
|
th.WriteF("test.properties", `waterway=mississippi`)
|
|
m := th.Run(".", th.MakeDefaultOptions())
|
|
th.AssertActualEqualsExpected(m, `
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
annotations:
|
|
river: mississippi
|
|
name: theDeployment
|
|
spec:
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
river: mississippi
|
|
spec:
|
|
containers:
|
|
- name: test
|
|
---
|
|
apiVersion: v1
|
|
data:
|
|
waterway: mississippi
|
|
kind: ConfigMap
|
|
metadata:
|
|
annotations:
|
|
river: mississippi
|
|
name: theConfigMap-hdd8h8cgdt
|
|
`)
|
|
}
|