...

Source file src/sigs.k8s.io/kustomize/api/krusty/transformerannotation_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  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"sigs.k8s.io/kustomize/api/internal/utils"
    14  	"sigs.k8s.io/kustomize/api/krusty"
    15  	kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
    16  	"sigs.k8s.io/kustomize/kyaml/filesys"
    17  )
    18  
    19  const generateDeploymentWithOriginDotSh = `#!/bin/sh
    20  
    21  cat <<EOF
    22  apiVersion: apps/v1
    23  kind: Deployment
    24  metadata:
    25    name: nginx
    26    labels:
    27      app: nginx
    28    annotations:
    29      tshirt-size: small # this injects the resource reservations
    30      config.kubernetes.io/origin: |
    31        path: somefile.yaml
    32  spec:
    33    selector:
    34      matchLabels:
    35        app: nginx
    36    template:
    37      metadata:
    38        labels:
    39          app: nginx
    40      spec:
    41        containers:
    42        - name: nginx
    43          image: nginx
    44  EOF
    45  `
    46  
    47  func TestAnnoTransformerBuiltinLocal(t *testing.T) {
    48  	th := kusttest_test.MakeHarness(t)
    49  	th.WriteF("service.yaml", `
    50  apiVersion: v1
    51  kind: Service
    52  metadata:
    53    name: myService
    54  spec:
    55    ports:
    56    - port: 7002
    57  `)
    58  	th.WriteK(".", `
    59  resources:
    60  - service.yaml
    61  buildMetadata: [transformerAnnotations]
    62  namePrefix: foo-
    63  `)
    64  	options := th.MakeDefaultOptions()
    65  	m := th.Run(".", options)
    66  	th.AssertActualEqualsExpected(m, `
    67  apiVersion: v1
    68  kind: Service
    69  metadata:
    70    annotations:
    71      alpha.config.kubernetes.io/transformations: |
    72        - configuredIn: kustomization.yaml
    73          configuredBy:
    74            apiVersion: builtin
    75            kind: PrefixTransformer
    76    name: foo-myService
    77  spec:
    78    ports:
    79    - port: 7002
    80  `)
    81  }
    82  
    83  func TestAnnoOriginAndTransformerBuiltinLocal(t *testing.T) {
    84  	th := kusttest_test.MakeHarness(t)
    85  	th.WriteF("service.yaml", `
    86  apiVersion: v1
    87  kind: Service
    88  metadata:
    89    name: myService
    90  spec:
    91    ports:
    92    - port: 7002
    93  `)
    94  	th.WriteK(".", `
    95  resources:
    96  - service.yaml
    97  buildMetadata: [originAnnotations, transformerAnnotations]
    98  namePrefix: foo-
    99  `)
   100  	options := th.MakeDefaultOptions()
   101  	m := th.Run(".", options)
   102  	th.AssertActualEqualsExpected(m, `
   103  apiVersion: v1
   104  kind: Service
   105  metadata:
   106    annotations:
   107      alpha.config.kubernetes.io/transformations: |
   108        - configuredIn: kustomization.yaml
   109          configuredBy:
   110            apiVersion: builtin
   111            kind: PrefixTransformer
   112      config.kubernetes.io/origin: |
   113        path: service.yaml
   114    name: foo-myService
   115  spec:
   116    ports:
   117    - port: 7002
   118  `)
   119  }
   120  
   121  func TestAnnoTransformerLocalFilesWithOverlay(t *testing.T) {
   122  	th := kusttest_test.MakeHarness(t)
   123  	th.WriteK("base", `
   124  namePrefix: b-
   125  resources:
   126  - namespace.yaml
   127  - role.yaml
   128  - service.yaml
   129  - deployment.yaml
   130  `)
   131  	th.WriteF("base/service.yaml", `
   132  apiVersion: v1
   133  kind: Service
   134  metadata:
   135    name: myService
   136  `)
   137  	th.WriteF("base/namespace.yaml", `
   138  apiVersion: v1
   139  kind: Namespace
   140  metadata:
   141    name: myNs
   142  `)
   143  	th.WriteF("base/role.yaml", `
   144  apiVersion: v1
   145  kind: Role
   146  metadata:
   147    name: myRole
   148  `)
   149  	th.WriteF("base/deployment.yaml", `
   150  apiVersion: v1
   151  kind: Deployment
   152  metadata:
   153    name: myDep
   154  `)
   155  	th.WriteK("prod", `
   156  namePrefix: p-
   157  resources:
   158  - ../base
   159  - service.yaml
   160  - namespace.yaml
   161  buildMetadata: [transformerAnnotations]
   162  `)
   163  	th.WriteF("prod/service.yaml", `
   164  apiVersion: v1
   165  kind: Service
   166  metadata:
   167    name: myService2
   168  `)
   169  	th.WriteF("prod/namespace.yaml", `
   170  apiVersion: v1
   171  kind: Namespace
   172  metadata:
   173    name: myNs2
   174  `)
   175  	m := th.Run("prod", th.MakeDefaultOptions())
   176  	th.AssertActualEqualsExpected(m, `
   177  apiVersion: v1
   178  kind: Namespace
   179  metadata:
   180    annotations:
   181      alpha.config.kubernetes.io/transformations: |
   182        - configuredIn: ../base/kustomization.yaml
   183          configuredBy:
   184            apiVersion: builtin
   185            kind: PrefixTransformer
   186        - configuredIn: kustomization.yaml
   187          configuredBy:
   188            apiVersion: builtin
   189            kind: PrefixTransformer
   190    name: myNs
   191  ---
   192  apiVersion: v1
   193  kind: Role
   194  metadata:
   195    annotations:
   196      alpha.config.kubernetes.io/transformations: |
   197        - configuredIn: ../base/kustomization.yaml
   198          configuredBy:
   199            apiVersion: builtin
   200            kind: PrefixTransformer
   201        - configuredIn: kustomization.yaml
   202          configuredBy:
   203            apiVersion: builtin
   204            kind: PrefixTransformer
   205    name: p-b-myRole
   206  ---
   207  apiVersion: v1
   208  kind: Service
   209  metadata:
   210    annotations:
   211      alpha.config.kubernetes.io/transformations: |
   212        - configuredIn: ../base/kustomization.yaml
   213          configuredBy:
   214            apiVersion: builtin
   215            kind: PrefixTransformer
   216        - configuredIn: kustomization.yaml
   217          configuredBy:
   218            apiVersion: builtin
   219            kind: PrefixTransformer
   220    name: p-b-myService
   221  ---
   222  apiVersion: v1
   223  kind: Deployment
   224  metadata:
   225    annotations:
   226      alpha.config.kubernetes.io/transformations: |
   227        - configuredIn: ../base/kustomization.yaml
   228          configuredBy:
   229            apiVersion: builtin
   230            kind: PrefixTransformer
   231        - configuredIn: kustomization.yaml
   232          configuredBy:
   233            apiVersion: builtin
   234            kind: PrefixTransformer
   235    name: p-b-myDep
   236  ---
   237  apiVersion: v1
   238  kind: Service
   239  metadata:
   240    annotations:
   241      alpha.config.kubernetes.io/transformations: |
   242        - configuredIn: kustomization.yaml
   243          configuredBy:
   244            apiVersion: builtin
   245            kind: PrefixTransformer
   246    name: p-myService2
   247  ---
   248  apiVersion: v1
   249  kind: Namespace
   250  metadata:
   251    annotations:
   252      alpha.config.kubernetes.io/transformations: |
   253        - configuredIn: kustomization.yaml
   254          configuredBy:
   255            apiVersion: builtin
   256            kind: PrefixTransformer
   257    name: myNs2
   258  `)
   259  }
   260  
   261  func TestAnnoOriginRemoteBuiltinTransformer(t *testing.T) {
   262  	fSys := filesys.MakeFsOnDisk()
   263  	b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
   264  	tmpDir, err := filesys.NewTmpConfirmedDir()
   265  	require.NoError(t, err)
   266  	require.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
   267  resources:
   268  - github.com/kubernetes-sigs/kustomize/examples/multibases/production/?ref=v1.0.6
   269  buildMetadata: [transformerAnnotations]
   270  `)))
   271  	m, err := b.Run(
   272  		fSys,
   273  		tmpDir.String())
   274  	if utils.IsErrTimeout(err) {
   275  		// Don't fail on timeouts.
   276  		t.SkipNow()
   277  	}
   278  	if !assert.NoError(t, err) {
   279  		t.FailNow()
   280  	}
   281  	yml, err := m.AsYaml()
   282  	require.NoError(t, err)
   283  	assert.Equal(t, `apiVersion: v1
   284  kind: Pod
   285  metadata:
   286    annotations:
   287      alpha.config.kubernetes.io/transformations: |
   288        - repo: https://github.com/kubernetes-sigs/kustomize
   289          ref: v1.0.6
   290          configuredIn: examples/multibases/production/kustomization.yaml
   291          configuredBy:
   292            apiVersion: builtin
   293            kind: PrefixTransformer
   294    labels:
   295      app: myapp
   296    name: prod-myapp-pod
   297  spec:
   298    containers:
   299    - image: nginx:1.7.9
   300      name: nginx
   301  `, string(yml))
   302  	require.NoError(t, fSys.RemoveAll(tmpDir.String()))
   303  }
   304  
   305  func TestAnnoTransformerBuiltinInline(t *testing.T) {
   306  	th := kusttest_test.MakeEnhancedHarness(t)
   307  	defer th.Reset()
   308  
   309  	th.WriteF("resource.yaml", `
   310  apiVersion: apps/v1
   311  kind: ConfigMap
   312  metadata:
   313    name: whatever
   314  data: {}
   315  `)
   316  	th.WriteK(".", `
   317  resources:
   318  - resource.yaml
   319  transformers:
   320  - |-
   321    apiVersion: builtin
   322    kind: NamespaceTransformer
   323    metadata:
   324      name: not-important-to-example
   325      namespace: test
   326    fieldSpecs:
   327    - path: metadata/namespace
   328      create: true
   329  buildMetadata: [transformerAnnotations]
   330  `)
   331  
   332  	expected := `
   333  apiVersion: apps/v1
   334  data: {}
   335  kind: ConfigMap
   336  metadata:
   337    annotations:
   338      alpha.config.kubernetes.io/transformations: |
   339        - configuredIn: kustomization.yaml
   340          configuredBy:
   341            apiVersion: builtin
   342            kind: NamespaceTransformer
   343            name: not-important-to-example
   344            namespace: test
   345    name: whatever
   346    namespace: test
   347  `
   348  	m := th.Run(".", th.MakeDefaultOptions())
   349  	th.AssertActualEqualsExpected(m, expected)
   350  }
   351  
   352  func TestAnnoOriginCustomInlineTransformer(t *testing.T) {
   353  	fSys := filesys.MakeFsOnDisk()
   354  
   355  	th := kusttest_test.MakeHarnessWithFs(t, fSys)
   356  	o := th.MakeOptionsPluginsEnabled()
   357  	o.PluginConfig.FnpLoadingOptions.EnableExec = true
   358  
   359  	tmpDir, err := filesys.NewTmpConfirmedDir()
   360  	require.NoError(t, err)
   361  	th.WriteK(tmpDir.String(), `
   362  transformers:
   363  - |-
   364    kind: executable
   365    metadata:
   366      name: demo
   367      annotations:
   368        config.kubernetes.io/function: |
   369          exec:
   370            path: ./generateDeployment.sh
   371    spec:
   372  buildMetadata: [transformerAnnotations]
   373  `)
   374  
   375  	// generateDeploymentWithOriginDotSh creates a resource that already has an origin annotation,
   376  	// which will cause kustomize to record the plugin origin data as a transformation
   377  	th.WriteF(filepath.Join(tmpDir.String(), "generateDeployment.sh"), generateDeploymentWithOriginDotSh)
   378  
   379  	require.NoError(t, os.Chmod(filepath.Join(tmpDir.String(), "generateDeployment.sh"), 0777))
   380  	th.WriteF(filepath.Join(tmpDir.String(), "gener.yaml"), `
   381  kind: executable
   382  metadata:
   383    name: demo
   384    annotations:
   385      config.kubernetes.io/function: |
   386        exec:
   387          path: ./generateDeployment.sh
   388  spec:
   389  `)
   390  
   391  	m := th.Run(tmpDir.String(), o)
   392  	require.NoError(t, err)
   393  	yml, err := m.AsYaml()
   394  	require.NoError(t, err)
   395  	assert.Equal(t, `apiVersion: apps/v1
   396  kind: Deployment
   397  metadata:
   398    annotations:
   399      alpha.config.kubernetes.io/transformations: |
   400        - configuredIn: kustomization.yaml
   401          configuredBy:
   402            kind: executable
   403            name: demo
   404      tshirt-size: small
   405    labels:
   406      app: nginx
   407    name: nginx
   408  spec:
   409    selector:
   410      matchLabels:
   411        app: nginx
   412    template:
   413      metadata:
   414        labels:
   415          app: nginx
   416      spec:
   417        containers:
   418        - image: nginx
   419          name: nginx
   420  `, string(yml))
   421  	require.NoError(t, fSys.RemoveAll(tmpDir.String()))
   422  }
   423  
   424  func TestAnnoOriginCustomExecTransformerWithOverlay(t *testing.T) {
   425  	fSys := filesys.MakeFsOnDisk()
   426  
   427  	th := kusttest_test.MakeHarnessWithFs(t, fSys)
   428  	o := th.MakeOptionsPluginsEnabled()
   429  	o.PluginConfig.FnpLoadingOptions.EnableExec = true
   430  
   431  	tmpDir, err := filesys.NewTmpConfirmedDir()
   432  	require.NoError(t, err)
   433  	base := filepath.Join(tmpDir.String(), "base")
   434  	prod := filepath.Join(tmpDir.String(), "prod")
   435  	require.NoError(t, fSys.Mkdir(base))
   436  	require.NoError(t, fSys.Mkdir(prod))
   437  	th.WriteK(base, `
   438  transformers:
   439  - gener.yaml
   440  `)
   441  	th.WriteK(prod, `
   442  resources:
   443  - ../base
   444  buildMetadata: [transformerAnnotations]
   445  `)
   446  	th.WriteF(filepath.Join(base, "gener.yaml"), `
   447  kind: executable
   448  metadata:
   449    name: demo
   450    annotations:
   451      config.kubernetes.io/function: |
   452        exec:
   453          path: ./generateDeployment.sh
   454  spec:
   455  `)
   456  	// generateDeploymentWithOriginDotSh creates a resource that already has an origin annotation,
   457  	// which will cause kustomize to record the plugin origin data as a transformation
   458  	th.WriteF(filepath.Join(base, "generateDeployment.sh"), generateDeploymentWithOriginDotSh)
   459  	require.NoError(t, os.Chmod(filepath.Join(base, "generateDeployment.sh"), 0777))
   460  
   461  	m := th.Run(prod, o)
   462  	require.NoError(t, err)
   463  	yml, err := m.AsYaml()
   464  	require.NoError(t, err)
   465  	assert.Equal(t, `apiVersion: apps/v1
   466  kind: Deployment
   467  metadata:
   468    annotations:
   469      alpha.config.kubernetes.io/transformations: |
   470        - configuredIn: ../base/gener.yaml
   471          configuredBy:
   472            kind: executable
   473            name: demo
   474      tshirt-size: small
   475    labels:
   476      app: nginx
   477    name: nginx
   478  spec:
   479    selector:
   480      matchLabels:
   481        app: nginx
   482    template:
   483      metadata:
   484        labels:
   485          app: nginx
   486      spec:
   487        containers:
   488        - image: nginx
   489          name: nginx
   490  `, string(yml))
   491  	require.NoError(t, fSys.RemoveAll(tmpDir.String()))
   492  }
   493  

View as plain text