github.com/pluralsh/plural-cli@v0.9.5/pkg/scaffold/template/lua_test.go (about)

     1  package template_test
     2  
     3  import (
     4  	"os"
     5  	"path"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"gopkg.in/yaml.v2"
    10  
    11  	"github.com/pluralsh/plural-cli/pkg/config"
    12  	"github.com/pluralsh/plural-cli/pkg/scaffold/template"
    13  	pluraltest "github.com/pluralsh/plural-cli/pkg/test"
    14  	"github.com/pluralsh/plural-cli/pkg/utils/git"
    15  )
    16  
    17  func TestFromLuaTemplateComplex(t *testing.T) {
    18  	tests := []struct {
    19  		name             string
    20  		vals             map[string]interface{}
    21  		script           string
    22  		keyContent       string
    23  		expectedResponse string
    24  		expectedError    string
    25  	}{
    26  		{
    27  			name:       `test complex azure`,
    28  			keyContent: `key: "gKNJBnflqQA6lfUKLWMwl7CMJk4j+qqG9jnGYdTvwTk="`,
    29  			vals: map[string]interface{}{
    30  				"Values":        map[string]interface{}{"console_dns": "https://onplural.sh"},
    31  				"Configuration": "",
    32  				"License":       "abc",
    33  				"Region":        "US",
    34  				"Project":       "test",
    35  				"Cluster":       "test",
    36  				"Provider":      "azure",
    37  				"Config":        map[string]interface{}{"Email": "test@plural.sh"},
    38  				"Context":       map[string]interface{}{"SubscriptionId": "abc", "TenantId": "bca"},
    39  				"console":       map[string]interface{}{"secrets": map[string]interface{}{"admin_password": "abc", "jwt": "abc", "admin_email": "", "erlang": "abc"}},
    40  			},
    41  			script: func() string {
    42  				io, err := os.ReadFile("../../test/lua/values.yaml.lua")
    43  				if err != nil {
    44  					t.Fatal(err)
    45  				}
    46  				return string(io)
    47  			}(),
    48  
    49  			expectedResponse: `global:
    50    application:
    51      links:
    52      - description: console web ui
    53        url: https://onplural.sh
    54  test:
    55    consoleIdentityClientId: '{{ .Import.Terraform.console_msi_client_id }}'
    56    consoleIdentityId: '{{ .Import.Terraform.console_msi_id }}'
    57    enabled: true
    58    extraEnv:
    59    - name: ARM_USE_MSI
    60      value: true
    61    - name: ARM_SUBSCRIPTION_ID
    62      value: abc
    63    - name: ARM_TENANT_ID
    64      value: bca
    65    ingress:
    66      annotations:
    67        kubernetes.io/tls-acme: "true"
    68      console_dns: https://onplural.sh
    69      ingressClass: nginx
    70    license: abc
    71    podLabels:
    72      aadpodidbinding: console
    73    provider: azure
    74    replicaCount: 2
    75    secrets:
    76      admin_email: ""
    77      admin_password: abc
    78      branch_name: master
    79      cluster_name: test
    80      config: |
    81        apiVersion: platform.plural.sh/v1alpha1
    82        kind: Config
    83        metadata: null
    84        spec:
    85          email: test@plural.sh
    86          token: abc
    87          consoleToken: ""
    88          namespacePrefix: test
    89          endpoint: http://example.com
    90          lockProfile: abc
    91          reportErrors: false
    92      erlang: abc
    93      git_access_token: ""
    94      git_email: console@plural.sh
    95      git_url: git@git.test.com:portfolio/space.space_name.git
    96      git_user: console
    97      id_rsa: ""
    98      id_rsa_pub: ""
    99      jwt: abc
   100      key: |
   101        key: "gKNJBnflqQA6lfUKLWMwl7CMJk4j+qqG9jnGYdTvwTk="
   102      repo_root: ""
   103      ssh_passphrase: ""
   104    serviceAccount:
   105      annotations:
   106        eks.amazonaws.com/role-arn: arn:aws:iam::test:role/test-console
   107      create: true
   108  `,
   109  		},
   110  		{
   111  			name:       `test complex aws`,
   112  			keyContent: `key: "gKNJBnflqQA6lfUKLWMwl7CMJk4j+qqG9jnGYdTvwTk="`,
   113  			vals: map[string]interface{}{
   114  				"Values":        map[string]interface{}{"console_dns": "https://onplural.sh"},
   115  				"Configuration": "",
   116  				"License":       "abc",
   117  				"Region":        "US",
   118  				"Project":       "test",
   119  				"Cluster":       "test",
   120  				"Provider":      "aws",
   121  				"Config":        map[string]interface{}{"Email": "test@plural.sh"},
   122  				"Context":       map[string]interface{}{"SubscriptionId": "abc", "TenantId": "bca"},
   123  				"console":       map[string]interface{}{"secrets": map[string]interface{}{"admin_password": "abc", "jwt": "abc", "admin_email": "", "erlang": "abc"}},
   124  			},
   125  			script: func() string {
   126  				io, err := os.ReadFile("../../test/lua/values.yaml.lua")
   127  				if err != nil {
   128  					t.Fatal(err)
   129  				}
   130  				return string(io)
   131  			}(),
   132  
   133  			expectedResponse: `global:
   134    application:
   135      links:
   136      - description: console web ui
   137        url: https://onplural.sh
   138  test:
   139    enabled: true
   140    ingress:
   141      annotations:
   142        kubernetes.io/tls-acme: "true"
   143      console_dns: https://onplural.sh
   144      ingressClass: nginx
   145    license: abc
   146    provider: aws
   147    replicaCount: 2
   148    secrets:
   149      admin_email: ""
   150      admin_password: abc
   151      branch_name: master
   152      cluster_name: test
   153      config: |
   154        apiVersion: platform.plural.sh/v1alpha1
   155        kind: Config
   156        metadata: null
   157        spec:
   158          email: test@plural.sh
   159          token: abc
   160          consoleToken: ""
   161          namespacePrefix: test
   162          endpoint: http://example.com
   163          lockProfile: abc
   164          reportErrors: false
   165      erlang: abc
   166      git_access_token: ""
   167      git_email: console@plural.sh
   168      git_url: git@git.test.com:portfolio/space.space_name.git
   169      git_user: console
   170      id_rsa: ""
   171      id_rsa_pub: ""
   172      jwt: abc
   173      key: |
   174        key: "gKNJBnflqQA6lfUKLWMwl7CMJk4j+qqG9jnGYdTvwTk="
   175      repo_root: ""
   176      ssh_passphrase: ""
   177    serviceAccount:
   178      annotations:
   179        eks.amazonaws.com/role-arn: arn:aws:iam::test:role/test-console
   180      create: true
   181  `,
   182  		},
   183  	}
   184  	for _, test := range tests {
   185  		t.Run(test.name, func(t *testing.T) {
   186  			dir, err := os.MkdirTemp("", "config")
   187  			assert.NoError(t, err)
   188  			defer os.RemoveAll(dir)
   189  
   190  			os.Setenv("HOME", dir)
   191  			defer os.Unsetenv("HOME")
   192  
   193  			err = os.Chdir(dir)
   194  			assert.NoError(t, err)
   195  			defaultConfig := pluraltest.GenDefaultConfig()
   196  			err = defaultConfig.Save(config.ConfigName)
   197  			assert.NoError(t, err)
   198  
   199  			_, err = git.Init()
   200  			assert.NoError(t, err)
   201  			_, err = git.GitRaw("config", "--global", "user.email", "test@plural.com")
   202  			assert.NoError(t, err)
   203  			_, err = git.GitRaw("config", "--global", "user.name", "test")
   204  			assert.NoError(t, err)
   205  			_, err = git.GitRaw("add", "-A")
   206  			assert.NoError(t, err)
   207  			_, err = git.GitRaw("commit", "-m", "init")
   208  			assert.NoError(t, err)
   209  			_, err = git.GitRaw("remote", "add", "origin", "git@git.test.com:portfolio/space.space_name.git")
   210  			assert.NoError(t, err)
   211  
   212  			err = os.MkdirAll(path.Join(dir, ".plural"), os.ModePerm)
   213  			assert.NoError(t, err)
   214  			err = os.WriteFile(path.Join(dir, ".plural", "key"), []byte(test.keyContent), 0644)
   215  			assert.NoError(t, err)
   216  
   217  			globals := map[string]interface{}{}
   218  			values := make(map[string]map[string]interface{})
   219  
   220  			err = template.FromLuaTemplate(test.vals, globals, values, "test", test.script)
   221  			if test.expectedError != "" {
   222  				assert.Equal(t, test.expectedError, err.Error())
   223  			} else {
   224  				assert.NoError(t, err)
   225  			}
   226  			values["global"] = globals
   227  			res, err := yaml.Marshal(values)
   228  			assert.NoError(t, err)
   229  			response := string(res)
   230  			assert.Equal(t, test.expectedResponse, response)
   231  		})
   232  	}
   233  }
   234  
   235  func TestFromLuaTemplate(t *testing.T) {
   236  	tests := []struct {
   237  		name             string
   238  		vals             map[string]interface{}
   239  		script           string
   240  		expectedResponse string
   241  		expectedError    string
   242  	}{
   243  		{
   244  			name: `test globals`,
   245  			vals: map[string]interface{}{
   246  				"Values": map[string]interface{}{"console_dns": "https://onplural.sh"},
   247  			},
   248  			script: `output = {
   249      global={
   250          application={
   251              links={
   252                  {	description= "console web ui",
   253                       url=Var.Values.console_dns
   254                  }
   255              }
   256          }
   257      }
   258  }`,
   259  			expectedResponse: `global:
   260    application:
   261      links:
   262      - description: console web ui
   263        url: https://onplural.sh
   264  test: {}
   265  `,
   266  		},
   267  		{
   268  			name: `test env var`,
   269  			vals: map[string]interface{}{
   270  				"Context": map[string]interface{}{"SubscriptionId": "abc", "TenantId": "cda"},
   271  			},
   272  			script: `output = {
   273  		extraEnv={
   274  			{
   275  				name="ARM_USE_MSI",
   276  				value = 'true'
   277  	
   278  			},
   279  			{
   280  				name="ARM_SUBSCRIPTION_ID",
   281  				value=Var.Context.SubscriptionId
   282  			},
   283  			{
   284  				name="ARM_TENANT_ID",
   285  				value= Var.Context.TenantId
   286  			}
   287      	}
   288  }`,
   289  			expectedResponse: `global: {}
   290  test:
   291    extraEnv:
   292    - name: ARM_USE_MSI
   293      value: "true"
   294    - name: ARM_SUBSCRIPTION_ID
   295      value: abc
   296    - name: ARM_TENANT_ID
   297      value: cda
   298  `,
   299  		},
   300  		{
   301  			name: `test annotations`,
   302  			vals: map[string]interface{}{
   303  				"Context": map[string]interface{}{"SubscriptionId": "abc", "TenantId": "cda"},
   304  			},
   305  			script: `output = {
   306  					ingress={
   307  						annotations={
   308  							['kubernetes.io/tls-acme']='true',
   309  						}
   310  					}
   311  }`,
   312  			expectedResponse: `global: {}
   313  test:
   314    ingress:
   315      annotations:
   316        kubernetes.io/tls-acme: "true"
   317  `,
   318  		},
   319  		{
   320  			name: `test importValue`,
   321  			vals: map[string]interface{}{
   322  				"Values": map[string]interface{}{"console_dns": "https://onplural.sh"},
   323  			},
   324  			script: `output = {}
   325      output.consoleIdentityId=importValue("Terraform", "console_msi_id")
   326      output.consoleIdentityClientId=importValue("Terraform", "console_msi_client_id")
   327  `,
   328  			expectedResponse: `global: {}
   329  test:
   330    consoleIdentityClientId: '{{ .Import.Terraform.console_msi_client_id }}'
   331    consoleIdentityId: '{{ .Import.Terraform.console_msi_id }}'
   332  `,
   333  		},
   334  		{
   335  			name: `test when output doesn't exist`,
   336  			vals: map[string]interface{}{
   337  				"Values": map[string]interface{}{"console_dns": "https://onplural.sh"},
   338  			},
   339  			script: `
   340  			somethingElse={}
   341  `,
   342  			expectedError: `the output variable is missing in the lua script`,
   343  		},
   344  		{
   345  			name: `test encryption key`,
   346  			vals: map[string]interface{}{},
   347  			script: `
   348  			output={
   349  				secrets={
   350  					key=''
   351                  }
   352  			}
   353  			output.secrets.key=dedupe(Var, "console.secrets.key", readFile(pathJoin(homeDir(), ".plural", "key"))) .. "\n"
   354  `,
   355  			expectedResponse: `global: {}
   356  test:
   357    secrets:
   358      key: |
   359        key: 3fWQQvTe5w9Gu6uoJzw1C5SxnARtNT/QOvvISRFoxRs=
   360  `,
   361  		},
   362  		{
   363  			name: `test encryption key when already exists`,
   364  			vals: map[string]interface{}{
   365  				"console": map[string]interface{}{"secrets": map[string]interface{}{
   366  					"key": "key: abc",
   367  				}},
   368  			},
   369  			script: `
   370  			output={
   371  				secrets={
   372  					key=''
   373                  }
   374  			}
   375  			output.secrets.key=dedupe(Var, "console.secrets.key", readFile(pathJoin(homeDir(), ".plural", "key"))) .. "\n"
   376  `,
   377  			expectedResponse: `global: {}
   378  test:
   379    secrets:
   380      key: |
   381        key: abc
   382  `,
   383  		},
   384  		{
   385  			name: `test kebab case`,
   386  			vals: map[string]interface{}{
   387  				"Values": map[string]interface{}{
   388  					"console_dns": "console.onplural.sh",
   389  					"testBase": map[string]interface{}{
   390  						"cypressEmail":    "test@plural.sh",
   391  						"cypressPassword": "xyz",
   392  					},
   393  				},
   394  			},
   395  			script: `
   396  			output={
   397  				
   398  			}
   399  			output["test-base"]={
   400  				enabled=true,
   401  				secret={
   402  					CYPRESS_EMAIL=Var.Values.testBase.cypressEmail,
   403  					CYPRESS_PASSWORD=Var.Values.testBase.cypressPassword,
   404  					CYPRESS_BASE_URL= "https://" .. Var.Values.console_dns .. "/",
   405  				}
   406  			}
   407  `,
   408  			expectedResponse: `global: {}
   409  test:
   410    test-base:
   411      enabled: true
   412      secret:
   413        CYPRESS_BASE_URL: https://console.onplural.sh/
   414        CYPRESS_EMAIL: test@plural.sh
   415        CYPRESS_PASSWORD: xyz
   416  `,
   417  		},
   418  	}
   419  	for _, test := range tests {
   420  		t.Run(test.name, func(t *testing.T) {
   421  			dir, err := os.MkdirTemp("", "config")
   422  			assert.NoError(t, err)
   423  			defer os.RemoveAll(dir)
   424  
   425  			os.Setenv("HOME", dir)
   426  			defer os.Unsetenv("HOME")
   427  
   428  			err = os.Chdir(dir)
   429  			assert.NoError(t, err)
   430  			err = os.MkdirAll(path.Join(dir, ".plural"), os.ModePerm)
   431  			assert.NoError(t, err)
   432  			err = os.WriteFile(path.Join(dir, ".plural", "key"), []byte("key: 3fWQQvTe5w9Gu6uoJzw1C5SxnARtNT/QOvvISRFoxRs="), 0644)
   433  			assert.NoError(t, err)
   434  
   435  			globals := map[string]interface{}{}
   436  			values := make(map[string]map[string]interface{})
   437  			err = template.FromLuaTemplate(test.vals, globals, values, "test", test.script)
   438  			if test.expectedError != "" {
   439  				assert.Equal(t, test.expectedError, err.Error())
   440  			} else {
   441  				assert.NoError(t, err)
   442  
   443  				values["global"] = globals
   444  				res, err := yaml.Marshal(values)
   445  				assert.NoError(t, err)
   446  				response := string(res)
   447  				assert.Equal(t, test.expectedResponse, response)
   448  			}
   449  		})
   450  	}
   451  }