...

Source file src/sigs.k8s.io/kustomize/api/krusty/variableref_test.go

Documentation: sigs.k8s.io/kustomize/api/krusty

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package krusty_test
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
    11  )
    12  
    13  func TestBasicVariableRef(t *testing.T) {
    14  	th := kusttest_test.MakeHarness(t)
    15  	th.WriteK(".", `
    16  namePrefix: base-
    17  resources:
    18  - pod.yaml
    19  vars:
    20  - name: POD_NAME
    21    objref:
    22      apiVersion: v1
    23      kind: Pod
    24      name: clown
    25    fieldref:
    26      fieldpath: metadata.name
    27  `)
    28  
    29  	th.WriteF("pod.yaml", `
    30  apiVersion: v1
    31  kind: Pod
    32  metadata:
    33    name: clown
    34  spec:
    35    containers:
    36    - name: frown
    37      image: frown
    38      command:
    39      - echo
    40      - "$(POD_NAME)"
    41      env:
    42        - name: FOO
    43          value: "$(POD_NAME)"
    44  `)
    45  	m := th.Run(".", th.MakeDefaultOptions())
    46  	th.AssertActualEqualsExpected(m, `
    47  apiVersion: v1
    48  kind: Pod
    49  metadata:
    50    name: base-clown
    51  spec:
    52    containers:
    53    - command:
    54      - echo
    55      - base-clown
    56      env:
    57      - name: FOO
    58        value: base-clown
    59      image: frown
    60      name: frown
    61  `)
    62  }
    63  
    64  func TestBasicVarCollision(t *testing.T) {
    65  	th := kusttest_test.MakeHarness(t)
    66  	th.WriteK("base1", `
    67  namePrefix: base1-
    68  resources:
    69  - pod.yaml
    70  vars:
    71  - name: POD_NAME
    72    objref:
    73      apiVersion: v1
    74      kind: Pod
    75      name: kelley
    76    fieldref:
    77      fieldpath: metadata.name
    78  `)
    79  	th.WriteF("base1/pod.yaml", `
    80  apiVersion: v1
    81  kind: Pod
    82  metadata:
    83    name: kelley
    84  spec:
    85    containers:
    86    - name: smile
    87      image: smile
    88      command:
    89      - echo
    90      - "$(POD_NAME)"
    91      env:
    92        - name: FOO
    93          value: "$(POD_NAME)"
    94  `)
    95  
    96  	th.WriteK("base2", `
    97  namePrefix: base2-
    98  resources:
    99  - pod.yaml
   100  vars:
   101  - name: POD_NAME
   102    objref:
   103      apiVersion: v1
   104      kind: Pod
   105      name: grimaldi
   106    fieldref:
   107      fieldpath: metadata.name
   108  `)
   109  	th.WriteF("base2/pod.yaml", `
   110  apiVersion: v1
   111  kind: Pod
   112  metadata:
   113    name: grimaldi
   114  spec:
   115    containers:
   116    - name: dance
   117      image: dance
   118      command:
   119      - echo
   120      - "$(POD_NAME)"
   121      env:
   122        - name: FOO
   123          value: "$(POD_NAME)"
   124  `)
   125  
   126  	th.WriteK("overlay", `
   127  resources:
   128  - ../base1
   129  - ../base2
   130  `)
   131  	err := th.RunWithErr("overlay", th.MakeDefaultOptions())
   132  	if err == nil {
   133  		t.Fatalf("should have an error")
   134  	}
   135  	if !strings.Contains(err.Error(), "var 'POD_NAME' already encountered") {
   136  		t.Fatalf("unexpected err: %v", err)
   137  	}
   138  }
   139  
   140  func TestVarPropagatesUp(t *testing.T) {
   141  	th := kusttest_test.MakeHarness(t)
   142  	th.WriteK("base1", `
   143  namePrefix: base1-
   144  resources:
   145  - pod.yaml
   146  vars:
   147  - name: POD_NAME1
   148    objref:
   149      apiVersion: v1
   150      kind: Pod
   151      name: kelley
   152    fieldref:
   153      fieldpath: metadata.name
   154  `)
   155  	th.WriteF("base1/pod.yaml", `
   156  apiVersion: v1
   157  kind: Pod
   158  metadata:
   159    name: kelley
   160  spec:
   161    containers:
   162    - name: smile
   163      image: smile
   164      command:
   165      - echo
   166      - "$(POD_NAME1)"
   167      env:
   168        - name: FOO
   169          value: "$(POD_NAME1)"
   170  `)
   171  
   172  	th.WriteK("base2", `
   173  namePrefix: base2-
   174  resources:
   175  - pod.yaml
   176  vars:
   177  - name: POD_NAME2
   178    objref:
   179      apiVersion: v1
   180      kind: Pod
   181      name: grimaldi
   182    fieldref:
   183      fieldpath: metadata.name
   184  `)
   185  	th.WriteF("base2/pod.yaml", `
   186  apiVersion: v1
   187  kind: Pod
   188  metadata:
   189    name: grimaldi
   190  spec:
   191    containers:
   192    - name: dance
   193      image: dance
   194      command:
   195      - echo
   196      - "$(POD_NAME2)"
   197      env:
   198        - name: FOO
   199          value: "$(POD_NAME2)"
   200  `)
   201  
   202  	th.WriteK("overlay", `
   203  resources:
   204  - pod.yaml
   205  - ../base1
   206  - ../base2
   207  `)
   208  	th.WriteF("overlay/pod.yaml", `
   209  apiVersion: v1
   210  kind: Pod
   211  metadata:
   212    name: circus
   213  spec:
   214    containers:
   215    - name: ring
   216      image: ring
   217      command:
   218      - echo
   219      - "$(POD_NAME1)"
   220      - "$(POD_NAME2)"
   221      env:
   222        - name: P1
   223          value: "$(POD_NAME1)"
   224        - name: P2
   225          value: "$(POD_NAME2)"
   226  `)
   227  	m := th.Run("overlay", th.MakeDefaultOptions())
   228  	th.AssertActualEqualsExpected(m, `
   229  apiVersion: v1
   230  kind: Pod
   231  metadata:
   232    name: circus
   233  spec:
   234    containers:
   235    - command:
   236      - echo
   237      - base1-kelley
   238      - base2-grimaldi
   239      env:
   240      - name: P1
   241        value: base1-kelley
   242      - name: P2
   243        value: base2-grimaldi
   244      image: ring
   245      name: ring
   246  ---
   247  apiVersion: v1
   248  kind: Pod
   249  metadata:
   250    name: base1-kelley
   251  spec:
   252    containers:
   253    - command:
   254      - echo
   255      - base1-kelley
   256      env:
   257      - name: FOO
   258        value: base1-kelley
   259      image: smile
   260      name: smile
   261  ---
   262  apiVersion: v1
   263  kind: Pod
   264  metadata:
   265    name: base2-grimaldi
   266  spec:
   267    containers:
   268    - command:
   269      - echo
   270      - base2-grimaldi
   271      env:
   272      - name: FOO
   273        value: base2-grimaldi
   274      image: dance
   275      name: dance
   276  `)
   277  }
   278  
   279  // Not so much a bug as a desire for local variables
   280  // with less than global scope.  Currently all variables
   281  // are global.  So if a base with a variable is included
   282  // twice, it's a collision, so it's denied.
   283  func TestBug506(t *testing.T) {
   284  	th := kusttest_test.MakeHarness(t)
   285  	th.WriteK("base", `
   286  namePrefix: base-
   287  resources:
   288  - pod.yaml
   289  vars:
   290  - name: POD_NAME
   291    objref:
   292      apiVersion: v1
   293      kind: Pod
   294      name: myServerPod
   295    fieldref:
   296      fieldpath: metadata.name
   297  `)
   298  	th.WriteF("base/pod.yaml", `
   299  apiVersion: v1
   300  kind: Pod
   301  metadata:
   302    name: myServerPod
   303  spec:
   304    containers:
   305      - name: myServer
   306        image: whatever
   307        env:
   308          - name: POD_NAME
   309            value: $(POD_NAME)
   310  `)
   311  	th.WriteK("o1", `
   312  nameprefix: p1-
   313  resources:
   314  - ../base
   315  `)
   316  	th.WriteK("o2", `
   317  nameprefix: p2-
   318  resources:
   319  - ../base
   320  `)
   321  	th.WriteK("top", `
   322  resources:
   323  - ../o1
   324  - ../o2
   325  `)
   326  
   327  	/*
   328  	   	const presumablyDesired = `
   329  	   apiVersion: v1
   330  	   kind: Pod
   331  	   metadata:
   332  	     name: p1-base-myServerPod
   333  	   spec:
   334  	     containers:
   335  	     - env:
   336  	       - name: POD_NAME
   337  	         value: p1-base-myServerPod
   338  	       image: whatever
   339  	       name: myServer
   340  	   ---
   341  	   apiVersion: v1
   342  	   kind: Pod
   343  	   metadata:
   344  	     name: p2-base-myServerPod
   345  	   spec:
   346  	     containers:
   347  	     - env:
   348  	       - name: POD_NAME
   349  	         value: p2-base-myServerPod
   350  	       image: whatever
   351  	       name: myServer
   352  	   `
   353  	*/
   354  	err := th.RunWithErr("top", th.MakeDefaultOptions())
   355  	if err == nil {
   356  		t.Fatalf("should have an error")
   357  	}
   358  	if !strings.Contains(err.Error(), "var 'POD_NAME' already encountered") {
   359  		t.Fatalf("unexpected err: %v", err)
   360  	}
   361  }
   362  
   363  func TestSimpleServicePortVarReplace(t *testing.T) {
   364  	th := kusttest_test.MakeHarness(t)
   365  	th.WriteK(".", `
   366  resources:
   367  - service.yaml
   368  - statefulset.yaml
   369  vars:
   370   - name: THE_PORT
   371     objref:
   372       kind: StatefulSet
   373       name: cockroachdb
   374       apiVersion: apps/v1beta1
   375     fieldref:
   376       fieldpath: spec.template.spec.containers[0].ports[1].containerPort
   377  `)
   378  	th.WriteF("service.yaml", `
   379  apiVersion: v1
   380  kind: Service
   381  metadata:
   382    name: myService
   383  spec:
   384    ports:
   385    - port: $(THE_PORT)
   386      targetPort: $(THE_PORT)
   387      name: grpc
   388  `)
   389  	th.WriteF("statefulset.yaml", `
   390  apiVersion: apps/v1beta1
   391  kind: StatefulSet
   392  metadata:
   393    name: cockroachdb
   394  spec:
   395    template:
   396      spec:
   397        containers:
   398        - name: cockroachdb
   399          image: cockroachdb/cockroach:v1.1.5
   400          ports:
   401          - containerPort: 26257
   402            name: grpc
   403          - containerPort: 8888
   404            name: http
   405  `)
   406  	m := th.Run(".", th.MakeDefaultOptions())
   407  	th.AssertActualEqualsExpected(m, `
   408  apiVersion: v1
   409  kind: Service
   410  metadata:
   411    name: myService
   412  spec:
   413    ports:
   414    - name: grpc
   415      port: 8888
   416      targetPort: 8888
   417  ---
   418  apiVersion: apps/v1beta1
   419  kind: StatefulSet
   420  metadata:
   421    name: cockroachdb
   422  spec:
   423    template:
   424      spec:
   425        containers:
   426        - image: cockroachdb/cockroach:v1.1.5
   427          name: cockroachdb
   428          ports:
   429          - containerPort: 26257
   430            name: grpc
   431          - containerPort: 8888
   432            name: http
   433  `)
   434  }
   435  
   436  // TODO(3449): Yield bare primitives in var replacements from configmaps.
   437  // The ConfigMap data field is always strings, and anything that looks
   438  // like a boolean or int or float must be quoted, or the API server won't
   439  // accept the map.  This creates a problem if one wants to use a var to
   440  // inject a raw number or raw boolean sourced from a configmap, because as
   441  // far as the configmap representation is concerned, it's a string.
   442  // A workaround would be to source the var from another Kind, from a field
   443  // that allowed unquoted vars or booleans.
   444  func TestIssue3449(t *testing.T) {
   445  	th := kusttest_test.MakeHarness(t)
   446  	th.WriteK(".", `
   447  resources:
   448  - workflow.yaml
   449  
   450  configurations:
   451  - kustomization-config.yaml
   452  
   453  configMapGenerator:
   454  - name: kustomize-vars
   455    envs:
   456    - vars.env
   457  
   458  vars:
   459  - name: DBT_TARGET
   460    objref: &config-map-ref
   461      kind: ConfigMap
   462      name: kustomize-vars
   463      version: v1
   464    fieldref:
   465      fieldpath: data.DBT_TARGET
   466  - name: SUSPENDED
   467    objref: *config-map-ref
   468    fieldref:
   469      fieldpath: data.SUSPENDED
   470  `)
   471  	th.WriteF("workflow.yaml", `
   472  apiVersion: argoproj.io/v1alpha1
   473  kind: CronWorkflow
   474  metadata:
   475    name: cron-core-load-workflow
   476  spec:
   477    schedule: "45 2 * * *"
   478    timezone: "Europe/Vienna"
   479    concurrencyPolicy: Forbid
   480    suspend: $(SUSPENDED)
   481    workflowMetadata:
   482      labels:
   483        workflowName: core-load-workflow
   484    workflowSpec:
   485      workflowTemplateRef:
   486        name: core-load-pipeline
   487      arguments:
   488        parameters:
   489          - name: dbt_target
   490            value: $(DBT_TARGET)
   491  `)
   492  	th.WriteF("kustomization-config.yaml", `
   493  nameReference:
   494    - kind: ConfigMap
   495      version: v1
   496      fieldSpecs:
   497        - kind: CronWorkflow
   498          version: v1alpha1
   499          path: spec/workflowSpec/arguments/parameters/value
   500  varReference:
   501    - path: spec/workflowSpec/arguments/parameters/value
   502      kind: CronWorkflow
   503      group: argoproj.io
   504      version: v1alpha1
   505    - path: spec
   506      kind: CronWorkflow
   507      group: argoproj.io
   508      version: v1alpha1
   509  `)
   510  	th.WriteF("vars.env", `
   511  DBT_TARGET=development
   512  SUSPENDED=True
   513  `)
   514  	m := th.Run(".", th.MakeDefaultOptions())
   515  	th.AssertActualEqualsExpected(m, `
   516  apiVersion: argoproj.io/v1alpha1
   517  kind: CronWorkflow
   518  metadata:
   519    name: cron-core-load-workflow
   520  spec:
   521    concurrencyPolicy: Forbid
   522    schedule: 45 2 * * *
   523    suspend: "True"
   524    timezone: Europe/Vienna
   525    workflowMetadata:
   526      labels:
   527        workflowName: core-load-workflow
   528    workflowSpec:
   529      arguments:
   530        parameters:
   531        - name: dbt_target
   532          value: development
   533      workflowTemplateRef:
   534        name: core-load-pipeline
   535  ---
   536  apiVersion: v1
   537  data:
   538    DBT_TARGET: development
   539    SUSPENDED: "True"
   540  kind: ConfigMap
   541  metadata:
   542    name: kustomize-vars-7mhm8cg5kg
   543  `)
   544  }
   545  
   546  func TestVarRefBig(t *testing.T) {
   547  	th := kusttest_test.MakeHarness(t)
   548  	th.WriteK("base", `
   549  namePrefix: base-
   550  resources:
   551  - role-stuff.yaml
   552  - services.yaml
   553  - statefulset.yaml
   554  - cronjob.yaml
   555  - pdb.yaml
   556  configMapGenerator:
   557  - name: test-config-map
   558    literals:
   559    - foo=bar
   560    - baz=qux
   561  vars:
   562   - name: CDB_PUBLIC_SVC
   563     objref:
   564          kind: Service
   565          name: cockroachdb-public
   566          apiVersion: v1
   567     fieldref:
   568          fieldpath: metadata.name
   569   - name: CDB_STATEFULSET_NAME
   570     objref:
   571          kind: StatefulSet
   572          name: cockroachdb
   573          apiVersion: apps/v1beta1
   574     fieldref:
   575          fieldpath: metadata.name
   576   - name: CDB_HTTP_PORT
   577     objref:
   578          kind: StatefulSet
   579          name: cockroachdb
   580          apiVersion: apps/v1beta1
   581     fieldref:
   582          fieldpath: spec.template.spec.containers[0].ports[1].containerPort
   583   - name: CDB_STATEFULSET_SVC
   584     objref:
   585          kind: Service
   586          name: cockroachdb
   587          apiVersion: v1
   588     fieldref:
   589          fieldpath: metadata.name
   590  
   591   - name: TEST_CONFIG_MAP
   592     objref:
   593          kind: ConfigMap
   594          name: test-config-map
   595          apiVersion: v1
   596     fieldref:
   597          fieldpath: metadata.name`)
   598  	th.WriteF("base/cronjob.yaml", `
   599  apiVersion: batch/v1beta1
   600  kind: CronJob
   601  metadata:
   602    name: cronjob-example
   603  spec:
   604    schedule: "*/1 * * * *"
   605    concurrencyPolicy: Forbid
   606    jobTemplate:
   607      spec:
   608        template:
   609          spec:
   610            containers:
   611            - name: cronjob-example
   612              image: cockroachdb/cockroach:v1.1.5
   613              command:
   614              - echo
   615              - "$(CDB_STATEFULSET_NAME)"
   616              - "$(TEST_CONFIG_MAP)"
   617              env:
   618                - name: CDB_PUBLIC_SVC
   619                  value: "$(CDB_PUBLIC_SVC)"
   620  `)
   621  	th.WriteF("base/services.yaml", `
   622  apiVersion: v1
   623  kind: Service
   624  metadata:
   625    name: cockroachdb
   626    labels:
   627      app: cockroachdb
   628    annotations:
   629      service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
   630      # Enable automatic monitoring of all instances when Prometheus is running in the cluster.
   631      prometheus.io/scrape: "true"
   632      prometheus.io/path: "_status/vars"
   633      prometheus.io/port: "8080"
   634  spec:
   635    ports:
   636    - port: 26257
   637      targetPort: 26257
   638      name: grpc
   639    - port: $(CDB_HTTP_PORT)
   640      targetPort: $(CDB_HTTP_PORT)
   641      name: http
   642    clusterIP: None
   643    selector:
   644      app: cockroachdb
   645  ---
   646  apiVersion: v1
   647  kind: Service
   648  metadata:
   649    # This service is meant to be used by clients of the database. It exposes a ClusterIP that will
   650    # automatically load balance connections to the different database pods.
   651    name: cockroachdb-public
   652    labels:
   653      app: cockroachdb
   654  spec:
   655    ports:
   656    # The main port, served by gRPC, serves Postgres-flavor SQL, internode
   657    # traffic and the cli.
   658    - port: 26257
   659      targetPort: 26257
   660      name: grpc
   661    # The secondary port serves the UI as well as health and debug endpoints.
   662    - port: $(CDB_HTTP_PORT)
   663      targetPort: $(CDB_HTTP_PORT)
   664      name: http
   665    selector:
   666      app: cockroachdb
   667  `)
   668  	th.WriteF("base/role-stuff.yaml", `
   669  apiVersion: v1
   670  kind: ServiceAccount
   671  metadata:
   672    name: cockroachdb
   673    labels:
   674      app: cockroachdb
   675  ---
   676  apiVersion: rbac.authorization.k8s.io/v1beta1
   677  kind: Role
   678  metadata:
   679    name: cockroachdb
   680    labels:
   681      app: cockroachdb
   682  rules:
   683  - apiGroups:
   684    - ""
   685    resources:
   686    - secrets
   687    verbs:
   688    - create
   689    - get
   690  ---
   691  apiVersion: rbac.authorization.k8s.io/v1beta1
   692  kind: ClusterRole
   693  metadata:
   694    name: cockroachdb
   695    labels:
   696      app: cockroachdb
   697  rules:
   698  - apiGroups:
   699    - certificates.k8s.io
   700    resources:
   701    - certificatesigningrequests
   702    verbs:
   703    - create
   704    - get
   705    - watch
   706  ---
   707  apiVersion: rbac.authorization.k8s.io/v1beta1
   708  kind: RoleBinding
   709  metadata:
   710    name: cockroachdb
   711    labels:
   712      app: cockroachdb
   713  roleRef:
   714    apiGroup: rbac.authorization.k8s.io
   715    kind: Role
   716    name: cockroachdb
   717  subjects:
   718  - kind: ServiceAccount
   719    name: cockroachdb
   720    namespace: default
   721  ---
   722  apiVersion: rbac.authorization.k8s.io/v1beta1
   723  kind: ClusterRoleBinding
   724  metadata:
   725    name: cockroachdb
   726    labels:
   727      app: cockroachdb
   728  roleRef:
   729    apiGroup: rbac.authorization.k8s.io
   730    kind: ClusterRole
   731    name: cockroachdb
   732  subjects:
   733  - kind: ServiceAccount
   734    name: cockroachdb
   735    namespace: default
   736  `)
   737  	th.WriteF("base/pdb.yaml", `
   738  apiVersion: policy/v1beta1
   739  kind: PodDisruptionBudget
   740  metadata:
   741    name: cockroachdb-budget
   742    labels:
   743      app: cockroachdb
   744  spec:
   745    selector:
   746      matchLabels:
   747        app: cockroachdb
   748    maxUnavailable: 1
   749  `)
   750  	th.WriteF("base/statefulset.yaml", `
   751  apiVersion: apps/v1beta1
   752  kind: StatefulSet
   753  metadata:
   754    name: cockroachdb
   755  spec:
   756    serviceName: "cockroachdb"
   757    replicas: 3
   758    template:
   759      metadata:
   760        labels:
   761          app: cockroachdb
   762      spec:
   763        serviceAccountName: cockroachdb
   764        # Init containers are run only once in the lifetime of a pod, before
   765        # it's started up for the first time. It has to exit successfully
   766        # before the pod's main containers are allowed to start.
   767        initContainers:
   768        # The init-certs container sends a certificate signing request to the
   769        # kubernetes cluster.
   770        # You can see pending requests using: kubectl get csr
   771        # CSRs can be approved using:         kubectl certificate approve <csr name>
   772        #
   773        # All addresses used to contact a node must be specified in the --addresses arg.
   774        #
   775        # In addition to the node certificate and key, the init-certs entrypoint will symlink
   776        # the cluster CA to the certs directory.
   777        - name: init-certs
   778          image: cockroachdb/cockroach-k8s-request-cert:0.2
   779          imagePullPolicy: IfNotPresent
   780          command:
   781          - "/bin/ash"
   782          - "-ecx"
   783          - "/request-cert"
   784          - -namespace=${POD_NAMESPACE}
   785          - -certs-dir=/cockroach-certs
   786          - -type=node
   787          - -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut -f 1-2 -d '.'),$(CDB_PUBLIC_SVC)
   788          - -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
   789          env:
   790          - name: POD_IP
   791            valueFrom:
   792              fieldRef:
   793                fieldPath: status.podIP
   794          - name: POD_NAMESPACE
   795            valueFrom:
   796              fieldRef:
   797                fieldPath: metadata.namespace
   798          volumeMounts:
   799          - name: certs
   800            mountPath: /cockroach-certs
   801  
   802        affinity:
   803          podAntiAffinity:
   804            preferredDuringSchedulingIgnoredDuringExecution:
   805            - weight: 100
   806              podAffinityTerm:
   807                labelSelector:
   808                  matchExpressions:
   809                  - key: app
   810                    operator: In
   811                    values:
   812                    - cockroachdb
   813                topologyKey: kubernetes.io/hostname
   814        containers:
   815        - name: cockroachdb
   816          image: cockroachdb/cockroach:v1.1.5
   817          imagePullPolicy: IfNotPresent
   818          ports:
   819          - containerPort: 26257
   820            name: grpc
   821          - containerPort: 8080
   822            name: http
   823          volumeMounts:
   824          - name: datadir
   825            mountPath: /cockroach/cockroach-data
   826          - name: certs
   827            mountPath: /cockroach/cockroach-certs
   828          command:
   829            - "/bin/bash"
   830            - "-ecx"
   831            - "exec /cockroach/cockroach start --logtostderr"
   832            - --certs-dir /cockroach/cockroach-certs
   833            - --host $(hostname -f)
   834            - --http-host 0.0.0.0
   835            - --join $(CDB_STATEFULSET_NAME)-0.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-1.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-2.$(CDB_STATEFULSET_SVC)
   836            - --cache 25%
   837            - --max-sql-memory 25%
   838        # No pre-stop hook is required, a SIGTERM plus some time is all that's
   839        # needed for graceful shutdown of a node.
   840        terminationGracePeriodSeconds: 60
   841        volumes:
   842        - name: datadir
   843          persistentVolumeClaim:
   844            claimName: datadir
   845        - name: certs
   846          emptyDir: {}
   847    updateStrategy:
   848      type: RollingUpdate
   849    volumeClaimTemplates:
   850    - metadata:
   851        name: datadir
   852      spec:
   853        accessModes:
   854          - "ReadWriteOnce"
   855        resources:
   856          requests:
   857            storage: 1Gi
   858  `)
   859  	th.WriteK("overlay/staging", `
   860  namePrefix: dev-
   861  resources:
   862  - ../../base
   863  `)
   864  	m := th.Run("overlay/staging", th.MakeDefaultOptions())
   865  	th.AssertActualEqualsExpected(m, `
   866  apiVersion: v1
   867  kind: ServiceAccount
   868  metadata:
   869    labels:
   870      app: cockroachdb
   871    name: dev-base-cockroachdb
   872  ---
   873  apiVersion: rbac.authorization.k8s.io/v1beta1
   874  kind: Role
   875  metadata:
   876    labels:
   877      app: cockroachdb
   878    name: dev-base-cockroachdb
   879  rules:
   880  - apiGroups:
   881    - ""
   882    resources:
   883    - secrets
   884    verbs:
   885    - create
   886    - get
   887  ---
   888  apiVersion: rbac.authorization.k8s.io/v1beta1
   889  kind: ClusterRole
   890  metadata:
   891    labels:
   892      app: cockroachdb
   893    name: dev-base-cockroachdb
   894  rules:
   895  - apiGroups:
   896    - certificates.k8s.io
   897    resources:
   898    - certificatesigningrequests
   899    verbs:
   900    - create
   901    - get
   902    - watch
   903  ---
   904  apiVersion: rbac.authorization.k8s.io/v1beta1
   905  kind: RoleBinding
   906  metadata:
   907    labels:
   908      app: cockroachdb
   909    name: dev-base-cockroachdb
   910  roleRef:
   911    apiGroup: rbac.authorization.k8s.io
   912    kind: Role
   913    name: dev-base-cockroachdb
   914  subjects:
   915  - kind: ServiceAccount
   916    name: dev-base-cockroachdb
   917    namespace: default
   918  ---
   919  apiVersion: rbac.authorization.k8s.io/v1beta1
   920  kind: ClusterRoleBinding
   921  metadata:
   922    labels:
   923      app: cockroachdb
   924    name: dev-base-cockroachdb
   925  roleRef:
   926    apiGroup: rbac.authorization.k8s.io
   927    kind: ClusterRole
   928    name: dev-base-cockroachdb
   929  subjects:
   930  - kind: ServiceAccount
   931    name: dev-base-cockroachdb
   932    namespace: default
   933  ---
   934  apiVersion: v1
   935  kind: Service
   936  metadata:
   937    annotations:
   938      prometheus.io/path: _status/vars
   939      prometheus.io/port: "8080"
   940      prometheus.io/scrape: "true"
   941      service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
   942    labels:
   943      app: cockroachdb
   944    name: dev-base-cockroachdb
   945  spec:
   946    clusterIP: None
   947    ports:
   948    - name: grpc
   949      port: 26257
   950      targetPort: 26257
   951    - name: http
   952      port: 8080
   953      targetPort: 8080
   954    selector:
   955      app: cockroachdb
   956  ---
   957  apiVersion: v1
   958  kind: Service
   959  metadata:
   960    labels:
   961      app: cockroachdb
   962    name: dev-base-cockroachdb-public
   963  spec:
   964    ports:
   965    - name: grpc
   966      port: 26257
   967      targetPort: 26257
   968    - name: http
   969      port: 8080
   970      targetPort: 8080
   971    selector:
   972      app: cockroachdb
   973  ---
   974  apiVersion: apps/v1beta1
   975  kind: StatefulSet
   976  metadata:
   977    name: dev-base-cockroachdb
   978  spec:
   979    replicas: 3
   980    serviceName: dev-base-cockroachdb
   981    template:
   982      metadata:
   983        labels:
   984          app: cockroachdb
   985      spec:
   986        affinity:
   987          podAntiAffinity:
   988            preferredDuringSchedulingIgnoredDuringExecution:
   989            - podAffinityTerm:
   990                labelSelector:
   991                  matchExpressions:
   992                  - key: app
   993                    operator: In
   994                    values:
   995                    - cockroachdb
   996                topologyKey: kubernetes.io/hostname
   997              weight: 100
   998        containers:
   999        - command:
  1000          - /bin/bash
  1001          - -ecx
  1002          - exec /cockroach/cockroach start --logtostderr
  1003          - --certs-dir /cockroach/cockroach-certs
  1004          - --host $(hostname -f)
  1005          - --http-host 0.0.0.0
  1006          - --join dev-base-cockroachdb-0.dev-base-cockroachdb,dev-base-cockroachdb-1.dev-base-cockroachdb,dev-base-cockroachdb-2.dev-base-cockroachdb
  1007          - --cache 25%
  1008          - --max-sql-memory 25%
  1009          image: cockroachdb/cockroach:v1.1.5
  1010          imagePullPolicy: IfNotPresent
  1011          name: cockroachdb
  1012          ports:
  1013          - containerPort: 26257
  1014            name: grpc
  1015          - containerPort: 8080
  1016            name: http
  1017          volumeMounts:
  1018          - mountPath: /cockroach/cockroach-data
  1019            name: datadir
  1020          - mountPath: /cockroach/cockroach-certs
  1021            name: certs
  1022        initContainers:
  1023        - command:
  1024          - /bin/ash
  1025          - -ecx
  1026          - /request-cert
  1027          - -namespace=${POD_NAMESPACE}
  1028          - -certs-dir=/cockroach-certs
  1029          - -type=node
  1030          - -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut
  1031            -f 1-2 -d '.'),dev-base-cockroachdb-public
  1032          - -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  1033          env:
  1034          - name: POD_IP
  1035            valueFrom:
  1036              fieldRef:
  1037                fieldPath: status.podIP
  1038          - name: POD_NAMESPACE
  1039            valueFrom:
  1040              fieldRef:
  1041                fieldPath: metadata.namespace
  1042          image: cockroachdb/cockroach-k8s-request-cert:0.2
  1043          imagePullPolicy: IfNotPresent
  1044          name: init-certs
  1045          volumeMounts:
  1046          - mountPath: /cockroach-certs
  1047            name: certs
  1048        serviceAccountName: dev-base-cockroachdb
  1049        terminationGracePeriodSeconds: 60
  1050        volumes:
  1051        - name: datadir
  1052          persistentVolumeClaim:
  1053            claimName: datadir
  1054        - emptyDir: {}
  1055          name: certs
  1056    updateStrategy:
  1057      type: RollingUpdate
  1058    volumeClaimTemplates:
  1059    - metadata:
  1060        name: datadir
  1061      spec:
  1062        accessModes:
  1063        - ReadWriteOnce
  1064        resources:
  1065          requests:
  1066            storage: 1Gi
  1067  ---
  1068  apiVersion: batch/v1beta1
  1069  kind: CronJob
  1070  metadata:
  1071    name: dev-base-cronjob-example
  1072  spec:
  1073    concurrencyPolicy: Forbid
  1074    jobTemplate:
  1075      spec:
  1076        template:
  1077          spec:
  1078            containers:
  1079            - command:
  1080              - echo
  1081              - dev-base-cockroachdb
  1082              - dev-base-test-config-map-6b85g79g7g
  1083              env:
  1084              - name: CDB_PUBLIC_SVC
  1085                value: dev-base-cockroachdb-public
  1086              image: cockroachdb/cockroach:v1.1.5
  1087              name: cronjob-example
  1088    schedule: '*/1 * * * *'
  1089  ---
  1090  apiVersion: policy/v1beta1
  1091  kind: PodDisruptionBudget
  1092  metadata:
  1093    labels:
  1094      app: cockroachdb
  1095    name: dev-base-cockroachdb-budget
  1096  spec:
  1097    maxUnavailable: 1
  1098    selector:
  1099      matchLabels:
  1100        app: cockroachdb
  1101  ---
  1102  apiVersion: v1
  1103  data:
  1104    baz: qux
  1105    foo: bar
  1106  kind: ConfigMap
  1107  metadata:
  1108    name: dev-base-test-config-map-6b85g79g7g
  1109  `)
  1110  }
  1111  
  1112  func TestVariableRefIngressBasic(t *testing.T) {
  1113  	th := kusttest_test.MakeHarness(t)
  1114  	th.WriteK(".", `
  1115  resources:
  1116  - ingress.yaml
  1117  - deployment.yaml
  1118  
  1119  vars:
  1120  - name: DEPLOYMENT_NAME
  1121    objref:
  1122      apiVersion: apps/v1
  1123      kind: Deployment
  1124      name: nginxDep
  1125    fieldref:
  1126      fieldpath: metadata.name
  1127  `)
  1128  	th.WriteF("deployment.yaml", `
  1129  apiVersion: apps/v1
  1130  kind: Deployment
  1131  metadata:
  1132    name: nginxDep
  1133  `)
  1134  
  1135  	th.WriteF("ingress.yaml", `
  1136  apiVersion: networking.k8s.io/v1beta1
  1137  kind: Ingress
  1138  metadata:
  1139    name: nginxIngress
  1140  spec:
  1141    rules:
  1142    - host: $(DEPLOYMENT_NAME).example.com
  1143    tls:
  1144    - hosts:
  1145      - $(DEPLOYMENT_NAME).example.com
  1146      secretName: $(DEPLOYMENT_NAME).example.com-tls
  1147  `)
  1148  	m := th.Run(".", th.MakeDefaultOptions())
  1149  	th.AssertActualEqualsExpected(m, `
  1150  apiVersion: networking.k8s.io/v1beta1
  1151  kind: Ingress
  1152  metadata:
  1153    name: nginxIngress
  1154  spec:
  1155    rules:
  1156    - host: nginxDep.example.com
  1157    tls:
  1158    - hosts:
  1159      - nginxDep.example.com
  1160      secretName: nginxDep.example.com-tls
  1161  ---
  1162  apiVersion: apps/v1
  1163  kind: Deployment
  1164  metadata:
  1165    name: nginxDep
  1166  `)
  1167  }
  1168  
  1169  func TestVariableRefIngressOverlay(t *testing.T) {
  1170  	th := kusttest_test.MakeHarness(t)
  1171  	th.WriteK("base", `
  1172  resources:
  1173  - service.yaml
  1174  - deployment.yaml
  1175  - ingress.yaml
  1176  
  1177  vars:
  1178  - name: DEPLOYMENT_NAME
  1179    objref:
  1180      apiVersion: apps/v1
  1181      kind: Deployment
  1182      name: nginx
  1183    fieldref:
  1184      fieldpath: metadata.name
  1185  `)
  1186  	th.WriteF("base/deployment.yaml", `
  1187  apiVersion: apps/v1
  1188  kind: Deployment
  1189  metadata:
  1190    name: nginx
  1191    labels:
  1192      app.kubernetes.io/component: nginx
  1193  spec:
  1194    selector:
  1195      matchLabels:
  1196        app.kubernetes.io/component: nginx
  1197    template:
  1198      metadata:
  1199        labels:
  1200          app.kubernetes.io/component: nginx
  1201      spec:
  1202        containers:
  1203        - name: nginx
  1204          image: nginx:1.15.7-alpine
  1205          ports:
  1206          - name: http
  1207            containerPort: 80
  1208  `)
  1209  	th.WriteF("base/ingress.yaml", `
  1210  apiVersion: networking.k8s.io/v1beta1
  1211  kind: Ingress
  1212  metadata:
  1213    name: nginx
  1214    labels:
  1215      app.kubernetes.io/component: nginx
  1216  spec:
  1217    rules:
  1218    - host: $(DEPLOYMENT_NAME).example.com
  1219      http:
  1220        paths:
  1221        - backend:
  1222            serviceName: nginx
  1223            servicePort: 80
  1224          path: /
  1225    tls:
  1226    - hosts:
  1227      - $(DEPLOYMENT_NAME).example.com
  1228      secretName: $(DEPLOYMENT_NAME).example.com-tls
  1229  `)
  1230  	th.WriteF("base/service.yaml", `
  1231  apiVersion: v1
  1232  kind: Service
  1233  metadata:
  1234    name: nginx
  1235    labels:
  1236      app.kubernetes.io/component: nginx
  1237  spec:
  1238    ports:
  1239    - name: http
  1240      port: 80
  1241      protocol: TCP
  1242      targetPort: http
  1243  `)
  1244  	th.WriteK("overlay", `
  1245  nameprefix: kustomized-
  1246  resources:
  1247  - ../base
  1248  `)
  1249  	m := th.Run("overlay", th.MakeDefaultOptions())
  1250  	th.AssertActualEqualsExpected(m, `
  1251  apiVersion: v1
  1252  kind: Service
  1253  metadata:
  1254    labels:
  1255      app.kubernetes.io/component: nginx
  1256    name: kustomized-nginx
  1257  spec:
  1258    ports:
  1259    - name: http
  1260      port: 80
  1261      protocol: TCP
  1262      targetPort: http
  1263  ---
  1264  apiVersion: apps/v1
  1265  kind: Deployment
  1266  metadata:
  1267    labels:
  1268      app.kubernetes.io/component: nginx
  1269    name: kustomized-nginx
  1270  spec:
  1271    selector:
  1272      matchLabels:
  1273        app.kubernetes.io/component: nginx
  1274    template:
  1275      metadata:
  1276        labels:
  1277          app.kubernetes.io/component: nginx
  1278      spec:
  1279        containers:
  1280        - image: nginx:1.15.7-alpine
  1281          name: nginx
  1282          ports:
  1283          - containerPort: 80
  1284            name: http
  1285  ---
  1286  apiVersion: networking.k8s.io/v1beta1
  1287  kind: Ingress
  1288  metadata:
  1289    labels:
  1290      app.kubernetes.io/component: nginx
  1291    name: kustomized-nginx
  1292  spec:
  1293    rules:
  1294    - host: kustomized-nginx.example.com
  1295      http:
  1296        paths:
  1297        - backend:
  1298            serviceName: kustomized-nginx
  1299            servicePort: 80
  1300          path: /
  1301    tls:
  1302    - hosts:
  1303      - kustomized-nginx.example.com
  1304      secretName: kustomized-nginx.example.com-tls
  1305  `)
  1306  }
  1307  
  1308  func TestVariableRefMountPath(t *testing.T) {
  1309  	th := kusttest_test.MakeHarness(t)
  1310  	th.WriteK("base", `
  1311  resources:
  1312  - deployment.yaml
  1313  - namespace.yaml
  1314  
  1315  vars:
  1316  - name: NAMESPACE
  1317    objref:
  1318      apiVersion: v1
  1319      kind: Namespace
  1320      name: my-namespace
  1321  
  1322  `)
  1323  	th.WriteF("base/deployment.yaml", `
  1324    apiVersion: apps/v1
  1325    kind: Deployment
  1326    metadata:
  1327      name: my-deployment
  1328    spec:
  1329      template:
  1330        spec:
  1331          containers:
  1332          - name: app
  1333            image: busybox
  1334            volumeMounts:
  1335            - name: my-volume
  1336              mountPath: "/$(NAMESPACE)"
  1337            env:
  1338            - name: NAMESPACE
  1339              value: $(NAMESPACE)
  1340          volumes:
  1341          - name: my-volume
  1342            emptyDir: {}
  1343  `)
  1344  	th.WriteF("base/namespace.yaml", `
  1345    apiVersion: v1
  1346    kind: Namespace
  1347    metadata:
  1348      name: my-namespace
  1349  `)
  1350  
  1351  	m := th.Run("base", th.MakeDefaultOptions())
  1352  	th.AssertActualEqualsExpected(m, `
  1353  apiVersion: apps/v1
  1354  kind: Deployment
  1355  metadata:
  1356    name: my-deployment
  1357  spec:
  1358    template:
  1359      spec:
  1360        containers:
  1361        - env:
  1362          - name: NAMESPACE
  1363            value: my-namespace
  1364          image: busybox
  1365          name: app
  1366          volumeMounts:
  1367          - mountPath: /my-namespace
  1368            name: my-volume
  1369        volumes:
  1370        - emptyDir: {}
  1371          name: my-volume
  1372  ---
  1373  apiVersion: v1
  1374  kind: Namespace
  1375  metadata:
  1376    name: my-namespace
  1377  `)
  1378  }
  1379  
  1380  func TestVariableRefMaps(t *testing.T) {
  1381  	th := kusttest_test.MakeHarness(t)
  1382  	th.WriteK("base", `
  1383  resources:
  1384  - deployment.yaml
  1385  - namespace.yaml
  1386  vars:
  1387  - name: NAMESPACE
  1388    objref:
  1389      apiVersion: v1
  1390      kind: Namespace
  1391      name: my-namespace
  1392  `)
  1393  	th.WriteF("base/deployment.yaml", `
  1394    apiVersion: apps/v1
  1395    kind: Deployment
  1396    metadata:
  1397      name: my-deployment
  1398      labels:
  1399        my-label: $(NAMESPACE)
  1400      annotations:
  1401        my-annotation: $(NAMESPACE)
  1402    spec:
  1403      template:
  1404        spec:
  1405          containers:
  1406          - name: app
  1407            image: busybox
  1408  `)
  1409  	th.WriteF("base/namespace.yaml", `
  1410    apiVersion: v1
  1411    kind: Namespace
  1412    metadata:
  1413      name: my-namespace
  1414  `)
  1415  
  1416  	m := th.Run("base", th.MakeDefaultOptions())
  1417  	th.AssertActualEqualsExpected(m, `
  1418  apiVersion: apps/v1
  1419  kind: Deployment
  1420  metadata:
  1421    annotations:
  1422      my-annotation: my-namespace
  1423    labels:
  1424      my-label: my-namespace
  1425    name: my-deployment
  1426  spec:
  1427    template:
  1428      spec:
  1429        containers:
  1430        - image: busybox
  1431          name: app
  1432  ---
  1433  apiVersion: v1
  1434  kind: Namespace
  1435  metadata:
  1436    name: my-namespace
  1437  `)
  1438  }
  1439  
  1440  func TestVaribaleRefDifferentPrefix(t *testing.T) {
  1441  	th := kusttest_test.MakeHarness(t)
  1442  	th.WriteK("base", `
  1443  namePrefix: base-
  1444  resources:
  1445  - dev
  1446  - test
  1447  `)
  1448  
  1449  	th.WriteK("base/dev", `
  1450  namePrefix: dev-
  1451  resources:
  1452  - elasticsearch-dev-service.yml
  1453  vars:
  1454  - name: elasticsearch-dev-service-name
  1455    objref:
  1456      kind: Service
  1457      name: elasticsearch
  1458      apiVersion: v1
  1459    fieldref:
  1460      fieldpath: metadata.name
  1461  
  1462  `)
  1463  	th.WriteF("base/dev/elasticsearch-dev-service.yml", `
  1464  apiVersion: apps/v1
  1465  kind: StatefulSet
  1466  metadata:
  1467    name: elasticsearch
  1468  spec:
  1469    template:
  1470      spec:
  1471        containers:
  1472          - name: elasticsearch
  1473            env:
  1474              - name: DISCOVERY_SERVICE
  1475                value: "$(elasticsearch-dev-service-name).monitoring.svc.cluster.local"
  1476  ---
  1477  apiVersion: v1
  1478  kind: Service
  1479  metadata:
  1480    name: elasticsearch
  1481  spec:
  1482    ports:
  1483      - name: transport
  1484        port: 9300
  1485        protocol: TCP
  1486    clusterIP: None
  1487  `)
  1488  
  1489  	th.WriteK("base/test", `
  1490  namePrefix: test-
  1491  resources:
  1492  - elasticsearch-test-service.yml
  1493  vars:
  1494  - name: elasticsearch-test-service-name
  1495    objref:
  1496      kind: Service
  1497      name: elasticsearch
  1498      apiVersion: v1
  1499    fieldref:
  1500      fieldpath: metadata.name
  1501  `)
  1502  	th.WriteF("base/test/elasticsearch-test-service.yml", `
  1503  apiVersion: apps/v1
  1504  kind: StatefulSet
  1505  metadata:
  1506    name: elasticsearch
  1507  spec:
  1508    template:
  1509      spec:
  1510        containers:
  1511          - name: elasticsearch
  1512            env:
  1513              - name: DISCOVERY_SERVICE
  1514                value: "$(elasticsearch-test-service-name).monitoring.svc.cluster.local"
  1515  ---
  1516  apiVersion: v1
  1517  kind: Service
  1518  metadata:
  1519    name: elasticsearch
  1520  spec:
  1521    ports:
  1522      - name: transport
  1523        port: 9300
  1524        protocol: TCP
  1525    clusterIP: None
  1526  `)
  1527  
  1528  	m := th.Run("base", th.MakeDefaultOptions())
  1529  	th.AssertActualEqualsExpected(m, `
  1530  apiVersion: apps/v1
  1531  kind: StatefulSet
  1532  metadata:
  1533    name: base-dev-elasticsearch
  1534  spec:
  1535    template:
  1536      spec:
  1537        containers:
  1538        - env:
  1539          - name: DISCOVERY_SERVICE
  1540            value: base-dev-elasticsearch.monitoring.svc.cluster.local
  1541          name: elasticsearch
  1542  ---
  1543  apiVersion: v1
  1544  kind: Service
  1545  metadata:
  1546    name: base-dev-elasticsearch
  1547  spec:
  1548    clusterIP: None
  1549    ports:
  1550    - name: transport
  1551      port: 9300
  1552      protocol: TCP
  1553  ---
  1554  apiVersion: apps/v1
  1555  kind: StatefulSet
  1556  metadata:
  1557    name: base-test-elasticsearch
  1558  spec:
  1559    template:
  1560      spec:
  1561        containers:
  1562        - env:
  1563          - name: DISCOVERY_SERVICE
  1564            value: base-test-elasticsearch.monitoring.svc.cluster.local
  1565          name: elasticsearch
  1566  ---
  1567  apiVersion: v1
  1568  kind: Service
  1569  metadata:
  1570    name: base-test-elasticsearch
  1571  spec:
  1572    clusterIP: None
  1573    ports:
  1574    - name: transport
  1575      port: 9300
  1576      protocol: TCP
  1577  `)
  1578  }
  1579  
  1580  func TestVariableRefNFSServer(t *testing.T) {
  1581  	th := kusttest_test.MakeHarness(t)
  1582  	th.WriteK("base", `
  1583  resources:
  1584  - pv_pvc.yaml
  1585  - nfs_deployment.yaml
  1586  - nfs_service.yaml
  1587  - Deployment.yaml
  1588  - CronJob.yaml
  1589  - DaemonSet.yaml
  1590  - ReplicaSet.yaml
  1591  - StatefulSet.yaml
  1592  - Pod.yaml
  1593  - Job.yaml
  1594  - nfs_pv.yaml
  1595  
  1596  vars:
  1597  - name: NFS_SERVER_SERVICE_NAME
  1598    objref:
  1599      kind: Service
  1600      name: nfs-server-service
  1601      apiVersion: v1
  1602    fieldref:
  1603      fieldpath: metadata.name
  1604  `)
  1605  	th.WriteF("base/pv_pvc.yaml", `
  1606  apiVersion: v1
  1607  kind: PersistentVolumeClaim
  1608  metadata:
  1609    name: shared-volume-claim
  1610  spec:
  1611    accessModes:
  1612      - ReadWriteOnce
  1613    resources:
  1614      requests:
  1615        storage: 10Gi
  1616  `)
  1617  	th.WriteF("base/nfs_deployment.yaml", `
  1618  apiVersion: extensions/v1beta1
  1619  kind: Deployment
  1620  metadata:
  1621    name: nfs-server
  1622  spec:
  1623    replicas: 1
  1624    template:
  1625      spec:
  1626        metadata:
  1627          labels:
  1628            role: nfs-server
  1629        containers:
  1630          - name: nfs-server
  1631            image: gcr.io/google_containers/volume-nfs:0.8
  1632            ports:
  1633              - name: nfs
  1634                containerPort: 2049
  1635              - name: mountd
  1636                containerPort: 20048
  1637              - name: rpcbind
  1638                containerPort: 111
  1639            securityContext:
  1640              privileged: true
  1641            volumeMounts:
  1642              - mountPath: /exports
  1643                name: shared-files
  1644        volumes:
  1645          - name: shared-files
  1646            persistentVolumeClaim:
  1647              claimName: shared-volume-claim
  1648  `)
  1649  	th.WriteF("base/nfs_service.yaml", `
  1650  apiVersion: v1
  1651  kind: Service
  1652  metadata:
  1653    name: nfs-server-service
  1654  spec:
  1655    ports:
  1656      - name: nfs
  1657        port: 2049
  1658      - name: mountd
  1659        port: 20048
  1660      - name: rpcbind
  1661        port: 111
  1662    selector:
  1663      role: nfs-server
  1664  `)
  1665  	th.WriteF("base/Deployment.yaml", `
  1666  apiVersion: apps/v1
  1667  kind: Deployment
  1668  metadata:
  1669    name: nginx
  1670    labels:
  1671      app.kubernetes.io/component: nginx
  1672  spec:
  1673    selector:
  1674      matchLabels:
  1675        app.kubernetes.io/component: nginx
  1676    template:
  1677      metadata:
  1678        labels:
  1679          app.kubernetes.io/component: nginx
  1680      spec:
  1681        containers:
  1682        - name: nginx
  1683          image: nginx:1.15.7-alpine
  1684          ports:
  1685          - name: http
  1686            containerPort: 80
  1687          volumeMounts:
  1688            - mountPath: shared-files
  1689              name: nfs-files-vol
  1690        volumes:
  1691          - name: nfs-files-vol
  1692            nfs:
  1693              server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1694              path: /
  1695              readOnly: false
  1696  `)
  1697  	th.WriteF("base/CronJob.yaml", `
  1698  apiVersion: batch/v1beta1
  1699  kind: CronJob
  1700  metadata:
  1701    name: hello
  1702  spec:
  1703    schedule: "*/1 * * * *"
  1704    jobTemplate:
  1705      spec:
  1706        template:
  1707          spec:
  1708            containers:
  1709            - name: hello
  1710              image: busybox
  1711              args:
  1712              - /bin/sh
  1713              - -c
  1714              - date; echo Hello from the Kubernetes cluster
  1715            restartPolicy: OnFailure
  1716            volumeMounts:
  1717            - mountPath: shared-files
  1718              name: nfs-files-vol
  1719          volumes:
  1720          - name: nfs-files-vol
  1721            nfs:
  1722              server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1723              path: /
  1724              readOnly: false
  1725  `)
  1726  	th.WriteF("base/DaemonSet.yaml", `
  1727  apiVersion: apps/v1
  1728  kind: DaemonSet
  1729  metadata:
  1730    name: fluentd-elasticsearch
  1731    namespace: kube-system
  1732    labels:
  1733      k8s-app: fluentd-logging
  1734  spec:
  1735    selector:
  1736      matchLabels:
  1737        name: fluentd-elasticsearch
  1738    template:
  1739      metadata:
  1740        labels:
  1741          name: fluentd-elasticsearch
  1742      spec:
  1743        tolerations:
  1744        - key: node-role.kubernetes.io/master
  1745          effect: NoSchedule
  1746        containers:
  1747        - name: fluentd-elasticsearch
  1748          image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
  1749          resources:
  1750            limits:
  1751              memory: 200Mi
  1752            requests:
  1753              cpu: 100m
  1754              memory: 200Mi
  1755          volumeMounts:
  1756          - name: varlog
  1757            mountPath: /var/log
  1758          - name: varlibdockercontainers
  1759            mountPath: /var/lib/docker/containers
  1760            readOnly: true
  1761          - mountPath: shared-files
  1762            name: nfs-files-vol
  1763        terminationGracePeriodSeconds: 30
  1764        volumes:
  1765        - name: varlog
  1766          hostPath:
  1767            path: /var/log
  1768        - name: varlibdockercontainers
  1769          hostPath:
  1770            path: /var/lib/docker/containers
  1771        - name: nfs-files-vol
  1772          nfs:
  1773            server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1774            path: /
  1775            readOnly: false
  1776  `)
  1777  	th.WriteF("base/ReplicaSet.yaml", `
  1778  apiVersion: apps/v1
  1779  kind: ReplicaSet
  1780  metadata:
  1781    name: frontend
  1782    labels:
  1783      app: guestbook
  1784      tier: frontend
  1785  spec:
  1786    # modify replicas according to your case
  1787    replicas: 3
  1788    selector:
  1789      matchLabels:
  1790        tier: frontend
  1791    template:
  1792      metadata:
  1793        labels:
  1794          tier: frontend
  1795      spec:
  1796        containers:
  1797        - name: php-redis
  1798          image: gcr.io/google_samples/gb-frontend:v3
  1799          volumeMounts:
  1800          - mountPath: shared-files
  1801            name: nfs-files-vol
  1802        volumes:
  1803        - name: nfs-files-vol
  1804          nfs:
  1805            server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1806            path: /
  1807            readOnly: false
  1808  `)
  1809  
  1810  	th.WriteF("base/Job.yaml", `
  1811  apiVersion: batch/v1
  1812  kind: Job
  1813  metadata:
  1814    name: pi
  1815  spec:
  1816    template:
  1817      spec:
  1818        containers:
  1819        - name: pi
  1820          image: perl
  1821          command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
  1822          volumeMounts:
  1823          - mountPath: shared-files
  1824            name: nfs-files-vol
  1825        restartPolicy: Never
  1826        volumes:
  1827        - name: nfs-files-vol
  1828          nfs:
  1829            server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1830            path: /
  1831            readOnly: false
  1832    backoffLimit: 4
  1833  `)
  1834  	th.WriteF("base/StatefulSet.yaml", `
  1835  apiVersion: apps/v1
  1836  kind: StatefulSet
  1837  metadata:
  1838    name: web
  1839  spec:
  1840    selector:
  1841      matchLabels:
  1842        app: nginx # has to match .spec.template.metadata.labels
  1843    serviceName: "nginx"
  1844    replicas: 3 # by default is 1
  1845    template:
  1846      metadata:
  1847        labels:
  1848          app: nginx # has to match .spec.selector.matchLabels
  1849      spec:
  1850        terminationGracePeriodSeconds: 10
  1851        containers:
  1852        - name: nginx
  1853          image: registry.k8s.io/nginx-slim:0.8
  1854          ports:
  1855          - containerPort: 80
  1856            name: web
  1857          volumeMounts:
  1858          - name: www
  1859            mountPath: /usr/share/nginx/html
  1860    volumeClaimTemplates:
  1861    - metadata:
  1862        name: www
  1863      spec:
  1864        accessModes: [ "ReadWriteMany" ]
  1865        nfs:
  1866          server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1867          path: /
  1868          readOnly: false
  1869  `)
  1870  	th.WriteF("base/Pod.yaml", `
  1871  apiVersion: v1
  1872  kind: Pod
  1873  metadata:
  1874    name: myapp-pod
  1875    labels:
  1876      app: myapp
  1877  spec:
  1878    containers:
  1879    - name: nginx
  1880      image: nginx:1.15.7-alpine
  1881      ports:
  1882      - name: http
  1883        containerPort: 80
  1884    volumeMounts:
  1885    - name: nfs-files-vol
  1886      mountPath: shared-files
  1887    volumes:
  1888    - name: nfs-files-vol
  1889      nfs:
  1890        server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1891        path: /
  1892        readOnly: false
  1893  `)
  1894  	th.WriteF("base/nfs_pv.yaml", `
  1895  apiVersion: v1
  1896  kind: PersistentVolume
  1897  metadata:
  1898    name: nfs-files-pv
  1899  spec:
  1900    capacity:
  1901      storage: 10Gi
  1902    accessModes:
  1903      - ReadWriteMany
  1904    nfs:
  1905      server: $(NFS_SERVER_SERVICE_NAME).default.srv.cluster.local
  1906      path: /
  1907      readOnly: false
  1908  `)
  1909  	th.WriteK("overlay", `
  1910  nameprefix: kustomized-
  1911  resources:
  1912  - ../base
  1913  `)
  1914  	m := th.Run("overlay", th.MakeDefaultOptions())
  1915  	th.AssertActualEqualsExpected(m, `
  1916  apiVersion: v1
  1917  kind: PersistentVolumeClaim
  1918  metadata:
  1919    name: kustomized-shared-volume-claim
  1920  spec:
  1921    accessModes:
  1922    - ReadWriteOnce
  1923    resources:
  1924      requests:
  1925        storage: 10Gi
  1926  ---
  1927  apiVersion: extensions/v1beta1
  1928  kind: Deployment
  1929  metadata:
  1930    name: kustomized-nfs-server
  1931  spec:
  1932    replicas: 1
  1933    template:
  1934      spec:
  1935        containers:
  1936        - image: gcr.io/google_containers/volume-nfs:0.8
  1937          name: nfs-server
  1938          ports:
  1939          - containerPort: 2049
  1940            name: nfs
  1941          - containerPort: 20048
  1942            name: mountd
  1943          - containerPort: 111
  1944            name: rpcbind
  1945          securityContext:
  1946            privileged: true
  1947          volumeMounts:
  1948          - mountPath: /exports
  1949            name: shared-files
  1950        metadata:
  1951          labels:
  1952            role: nfs-server
  1953        volumes:
  1954        - name: shared-files
  1955          persistentVolumeClaim:
  1956            claimName: kustomized-shared-volume-claim
  1957  ---
  1958  apiVersion: v1
  1959  kind: Service
  1960  metadata:
  1961    name: kustomized-nfs-server-service
  1962  spec:
  1963    ports:
  1964    - name: nfs
  1965      port: 2049
  1966    - name: mountd
  1967      port: 20048
  1968    - name: rpcbind
  1969      port: 111
  1970    selector:
  1971      role: nfs-server
  1972  ---
  1973  apiVersion: apps/v1
  1974  kind: Deployment
  1975  metadata:
  1976    labels:
  1977      app.kubernetes.io/component: nginx
  1978    name: kustomized-nginx
  1979  spec:
  1980    selector:
  1981      matchLabels:
  1982        app.kubernetes.io/component: nginx
  1983    template:
  1984      metadata:
  1985        labels:
  1986          app.kubernetes.io/component: nginx
  1987      spec:
  1988        containers:
  1989        - image: nginx:1.15.7-alpine
  1990          name: nginx
  1991          ports:
  1992          - containerPort: 80
  1993            name: http
  1994          volumeMounts:
  1995          - mountPath: shared-files
  1996            name: nfs-files-vol
  1997        volumes:
  1998        - name: nfs-files-vol
  1999          nfs:
  2000            path: /
  2001            readOnly: false
  2002            server: kustomized-nfs-server-service.default.srv.cluster.local
  2003  ---
  2004  apiVersion: batch/v1beta1
  2005  kind: CronJob
  2006  metadata:
  2007    name: kustomized-hello
  2008  spec:
  2009    jobTemplate:
  2010      spec:
  2011        template:
  2012          spec:
  2013            containers:
  2014            - args:
  2015              - /bin/sh
  2016              - -c
  2017              - date; echo Hello from the Kubernetes cluster
  2018              image: busybox
  2019              name: hello
  2020            restartPolicy: OnFailure
  2021            volumeMounts:
  2022            - mountPath: shared-files
  2023              name: nfs-files-vol
  2024          volumes:
  2025          - name: nfs-files-vol
  2026            nfs:
  2027              path: /
  2028              readOnly: false
  2029              server: kustomized-nfs-server-service.default.srv.cluster.local
  2030    schedule: '*/1 * * * *'
  2031  ---
  2032  apiVersion: apps/v1
  2033  kind: DaemonSet
  2034  metadata:
  2035    labels:
  2036      k8s-app: fluentd-logging
  2037    name: kustomized-fluentd-elasticsearch
  2038    namespace: kube-system
  2039  spec:
  2040    selector:
  2041      matchLabels:
  2042        name: fluentd-elasticsearch
  2043    template:
  2044      metadata:
  2045        labels:
  2046          name: fluentd-elasticsearch
  2047      spec:
  2048        containers:
  2049        - image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
  2050          name: fluentd-elasticsearch
  2051          resources:
  2052            limits:
  2053              memory: 200Mi
  2054            requests:
  2055              cpu: 100m
  2056              memory: 200Mi
  2057          volumeMounts:
  2058          - mountPath: /var/log
  2059            name: varlog
  2060          - mountPath: /var/lib/docker/containers
  2061            name: varlibdockercontainers
  2062            readOnly: true
  2063          - mountPath: shared-files
  2064            name: nfs-files-vol
  2065        terminationGracePeriodSeconds: 30
  2066        tolerations:
  2067        - effect: NoSchedule
  2068          key: node-role.kubernetes.io/master
  2069        volumes:
  2070        - hostPath:
  2071            path: /var/log
  2072          name: varlog
  2073        - hostPath:
  2074            path: /var/lib/docker/containers
  2075          name: varlibdockercontainers
  2076        - name: nfs-files-vol
  2077          nfs:
  2078            path: /
  2079            readOnly: false
  2080            server: kustomized-nfs-server-service.default.srv.cluster.local
  2081  ---
  2082  apiVersion: apps/v1
  2083  kind: ReplicaSet
  2084  metadata:
  2085    labels:
  2086      app: guestbook
  2087      tier: frontend
  2088    name: kustomized-frontend
  2089  spec:
  2090    replicas: 3
  2091    selector:
  2092      matchLabels:
  2093        tier: frontend
  2094    template:
  2095      metadata:
  2096        labels:
  2097          tier: frontend
  2098      spec:
  2099        containers:
  2100        - image: gcr.io/google_samples/gb-frontend:v3
  2101          name: php-redis
  2102          volumeMounts:
  2103          - mountPath: shared-files
  2104            name: nfs-files-vol
  2105        volumes:
  2106        - name: nfs-files-vol
  2107          nfs:
  2108            path: /
  2109            readOnly: false
  2110            server: kustomized-nfs-server-service.default.srv.cluster.local
  2111  ---
  2112  apiVersion: apps/v1
  2113  kind: StatefulSet
  2114  metadata:
  2115    name: kustomized-web
  2116  spec:
  2117    replicas: 3
  2118    selector:
  2119      matchLabels:
  2120        app: nginx
  2121    serviceName: nginx
  2122    template:
  2123      metadata:
  2124        labels:
  2125          app: nginx
  2126      spec:
  2127        containers:
  2128        - image: registry.k8s.io/nginx-slim:0.8
  2129          name: nginx
  2130          ports:
  2131          - containerPort: 80
  2132            name: web
  2133          volumeMounts:
  2134          - mountPath: /usr/share/nginx/html
  2135            name: www
  2136        terminationGracePeriodSeconds: 10
  2137    volumeClaimTemplates:
  2138    - metadata:
  2139        name: www
  2140      spec:
  2141        accessModes:
  2142        - ReadWriteMany
  2143        nfs:
  2144          path: /
  2145          readOnly: false
  2146          server: kustomized-nfs-server-service.default.srv.cluster.local
  2147  ---
  2148  apiVersion: v1
  2149  kind: Pod
  2150  metadata:
  2151    labels:
  2152      app: myapp
  2153    name: kustomized-myapp-pod
  2154  spec:
  2155    containers:
  2156    - image: nginx:1.15.7-alpine
  2157      name: nginx
  2158      ports:
  2159      - containerPort: 80
  2160        name: http
  2161    volumeMounts:
  2162    - mountPath: shared-files
  2163      name: nfs-files-vol
  2164    volumes:
  2165    - name: nfs-files-vol
  2166      nfs:
  2167        path: /
  2168        readOnly: false
  2169        server: kustomized-nfs-server-service.default.srv.cluster.local
  2170  ---
  2171  apiVersion: batch/v1
  2172  kind: Job
  2173  metadata:
  2174    name: kustomized-pi
  2175  spec:
  2176    backoffLimit: 4
  2177    template:
  2178      spec:
  2179        containers:
  2180        - command:
  2181          - perl
  2182          - -Mbignum=bpi
  2183          - -wle
  2184          - print bpi(2000)
  2185          image: perl
  2186          name: pi
  2187          volumeMounts:
  2188          - mountPath: shared-files
  2189            name: nfs-files-vol
  2190        restartPolicy: Never
  2191        volumes:
  2192        - name: nfs-files-vol
  2193          nfs:
  2194            path: /
  2195            readOnly: false
  2196            server: kustomized-nfs-server-service.default.srv.cluster.local
  2197  ---
  2198  apiVersion: v1
  2199  kind: PersistentVolume
  2200  metadata:
  2201    name: kustomized-nfs-files-pv
  2202  spec:
  2203    accessModes:
  2204    - ReadWriteMany
  2205    capacity:
  2206      storage: 10Gi
  2207    nfs:
  2208      path: /
  2209      readOnly: false
  2210      server: kustomized-nfs-server-service.default.srv.cluster.local
  2211  `)
  2212  }
  2213  
  2214  func TestDeploymentAnnotations(t *testing.T) {
  2215  	th := kusttest_test.MakeHarness(t)
  2216  	th.WriteK(".", `
  2217  configMapGenerator:
  2218  - name: theConfigMap
  2219    envs:
  2220    - test.properties
  2221  
  2222  vars:
  2223  - name: SOMERIVER
  2224    objref:
  2225      kind: ConfigMap
  2226      name: theConfigMap
  2227      apiVersion: v1
  2228    fieldref:
  2229      fieldpath: data.waterway
  2230  
  2231  commonAnnotations:
  2232    river: $(SOMERIVER)
  2233  
  2234  resources:
  2235  - deployment.yaml
  2236  `)
  2237  
  2238  	th.WriteF("deployment.yaml", `
  2239  apiVersion: apps/v1
  2240  kind: Deployment
  2241  metadata:
  2242    name: theDeployment
  2243  spec:
  2244    template:
  2245      spec:
  2246        containers:
  2247        - name: test
  2248  `)
  2249  	th.WriteF("test.properties", `waterway=mississippi`)
  2250  	m := th.Run(".", th.MakeDefaultOptions())
  2251  	th.AssertActualEqualsExpected(m, `
  2252  apiVersion: apps/v1
  2253  kind: Deployment
  2254  metadata:
  2255    annotations:
  2256      river: mississippi
  2257    name: theDeployment
  2258  spec:
  2259    template:
  2260      metadata:
  2261        annotations:
  2262          river: mississippi
  2263      spec:
  2264        containers:
  2265        - name: test
  2266  ---
  2267  apiVersion: v1
  2268  data:
  2269    waterway: mississippi
  2270  kind: ConfigMap
  2271  metadata:
  2272    annotations:
  2273      river: mississippi
  2274    name: theConfigMap-hdd8h8cgdt
  2275  `)
  2276  }
  2277  

View as plain text