github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/render/azureaks/render_test.go (about)

     1  package azureaks
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/go-kit/kit/log"
     9  	"github.com/golang/mock/gomock"
    10  	"github.com/replicatedhq/libyaml"
    11  	"github.com/replicatedhq/ship/pkg/api"
    12  	"github.com/replicatedhq/ship/pkg/lifecycle/render/root"
    13  	"github.com/replicatedhq/ship/pkg/templates"
    14  	"github.com/replicatedhq/ship/pkg/test-mocks/inline"
    15  	"github.com/replicatedhq/ship/pkg/test-mocks/state"
    16  	"github.com/replicatedhq/ship/pkg/testing/logger"
    17  	"github.com/replicatedhq/ship/pkg/testing/matchers"
    18  	"github.com/spf13/afero"
    19  	"github.com/spf13/viper"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestRenderer(t *testing.T) {
    24  	tests := []struct {
    25  		name       string
    26  		asset      api.AKSAsset
    27  		kubeconfig string
    28  	}{
    29  		{
    30  			name:       "empty",
    31  			asset:      api.AKSAsset{},
    32  			kubeconfig: "kubeconfig_",
    33  		},
    34  		{
    35  			name: "named",
    36  			asset: api.AKSAsset{
    37  				ClusterName: "aClusterName",
    38  			},
    39  			kubeconfig: "kubeconfig_aClusterName",
    40  		},
    41  		{
    42  			name: "named, custom path",
    43  			asset: api.AKSAsset{
    44  				ClusterName: "aClusterName",
    45  				AssetShared: api.AssetShared{
    46  					Dest: "aks.tf",
    47  				},
    48  			},
    49  			kubeconfig: "kubeconfig_aClusterName",
    50  		},
    51  		{
    52  			name: "named, in a directory",
    53  			asset: api.AKSAsset{
    54  				ClusterName: "aClusterName",
    55  				AssetShared: api.AssetShared{
    56  					Dest: "k8s/aks.tf",
    57  				},
    58  			},
    59  			kubeconfig: "k8s/kubeconfig_aClusterName",
    60  		},
    61  	}
    62  	for _, test := range tests {
    63  		t.Run(test.name, func(t *testing.T) {
    64  			req := require.New(t)
    65  			mc := gomock.NewController(t)
    66  			mockInline := inline.NewMockRenderer(mc)
    67  			testLogger := &logger.TestLogger{T: t}
    68  			v := viper.New()
    69  			bb := templates.NewBuilderBuilder(testLogger, v, &state.MockManager{})
    70  			renderer := &LocalRenderer{
    71  				Logger:         testLogger,
    72  				BuilderBuilder: bb,
    73  				Inline:         mockInline,
    74  			}
    75  
    76  			assetMatcher := &matchers.Is{
    77  				Describe: "inline asset",
    78  				Test: func(v interface{}) bool {
    79  					_, ok := v.(api.InlineAsset)
    80  					return ok
    81  				},
    82  			}
    83  
    84  			rootFs := root.Fs{
    85  				Afero:    afero.Afero{Fs: afero.NewMemMapFs()},
    86  				RootPath: "",
    87  			}
    88  			metadata := api.ReleaseMetadata{}
    89  			groups := []libyaml.ConfigGroup{}
    90  			templateContext := map[string]interface{}{}
    91  
    92  			mockInline.EXPECT().Execute(
    93  				rootFs,
    94  				assetMatcher,
    95  				metadata,
    96  				templateContext,
    97  				groups,
    98  			).Return(func(ctx context.Context) error { return nil })
    99  
   100  			err := renderer.Execute(
   101  				rootFs,
   102  				test.asset,
   103  				metadata,
   104  				templateContext,
   105  				groups,
   106  			)(context.Background())
   107  
   108  			req.NoError(err)
   109  
   110  			// test that the template function returns the correct kubeconfig path
   111  			builder := templates.
   112  				NewBuilderBuilder(log.NewNopLogger(), viper.New(), &state.MockManager{}).
   113  				NewBuilder(
   114  					&templates.ShipContext{},
   115  				)
   116  
   117  			aksTemplateFunc := `{{repl AzureAKS "%s" }}`
   118  			kubeconfig, err := builder.String(fmt.Sprintf(aksTemplateFunc, test.asset.ClusterName))
   119  			req.NoError(err)
   120  
   121  			req.Equal(test.kubeconfig, kubeconfig, "Did not get expected kubeconfig path")
   122  
   123  			otherKubeconfig, err := builder.String(fmt.Sprintf(aksTemplateFunc, "doesnotexist"))
   124  			req.NoError(err)
   125  			req.Empty(otherKubeconfig, "Expected path to nonexistent kubeconfig to be empty")
   126  		})
   127  	}
   128  }
   129  
   130  func TestRenderTerraformContents(t *testing.T) {
   131  	var tests = []struct {
   132  		name           string
   133  		asset          api.AKSAsset
   134  		kubeConfigPath string
   135  		answer         string
   136  	}{
   137  		{
   138  			name:           "With all optional values",
   139  			kubeConfigPath: "kubeConfig_app",
   140  			asset: api.AKSAsset{
   141  				Azure: api.Azure{
   142  					TenantID:               "tenant1",
   143  					SubscriptionID:         "subscription1",
   144  					ServicePrincipalID:     "serviceprincipal1",
   145  					ServicePrincipalSecret: "serviceprincipalsecret",
   146  					ResourceGroupName:      "ship",
   147  					Location:               "US East",
   148  				},
   149  				ClusterName:       "app",
   150  				KubernetesVersion: "v1.11.2",
   151  				PublicKey:         "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDdEcdAqClaNZdHAGHhiSBobJo5ZUL3sDfrZbBQinLvx3HN/9UaXp5mimlzhUkUQwX4jPqJ78w52idmXItd55HVboSQ8uKaRicgLLaNhSqrNpb+W3k2RToRPsjuaCi6a8XET0kcma6NaIbae9n0+nKzTtadX/hkrPEMS56BYpnHjQ== user@example.com",
   152  				NodeCount:         "2",
   153  				NodeType:          "Standard_D1_v2",
   154  				DiskGB:            "50",
   155  			},
   156  			answer: `
   157  provider "azurerm" {
   158    tenant_id       = "tenant1"
   159    subscription_id = "subscription1"
   160    client_id       = "serviceprincipal1"
   161    client_secret   = "serviceprincipalsecret"
   162    version         = "~> 1.14"
   163  }
   164  
   165  resource "azurerm_resource_group" "ship" {
   166    name     = "ship"
   167    location = "US East"
   168  }
   169  
   170  resource "azurerm_kubernetes_cluster" "app" {
   171    name                = "app"
   172    location            = "US East"
   173    resource_group_name = "ship"
   174    dns_prefix          = "app"
   175    kubernetes_version  = "v1.11.2"
   176  
   177    linux_profile {
   178      admin_username = "admin"
   179  
   180      ssh_key {
   181        key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDdEcdAqClaNZdHAGHhiSBobJo5ZUL3sDfrZbBQinLvx3HN/9UaXp5mimlzhUkUQwX4jPqJ78w52idmXItd55HVboSQ8uKaRicgLLaNhSqrNpb+W3k2RToRPsjuaCi6a8XET0kcma6NaIbae9n0+nKzTtadX/hkrPEMS56BYpnHjQ== user@example.com"
   182      }
   183    }
   184  
   185    agent_pool_profile {
   186      name            = "app"
   187      count           = 2
   188      vm_size         = "Standard_D1_v2"
   189      os_disk_size_gb = 50
   190    }
   191  
   192    service_principal {
   193      client_id     = "serviceprincipal1"
   194      client_secret = "serviceprincipalsecret"
   195    }
   196  }
   197  
   198  resource "local_file" "kubeconfig" {
   199    content = "${azurerm_kubernetes_cluster.app.kube_config_raw}"
   200    filename = "kubeConfig_app"
   201  }
   202  `,
   203  		},
   204  		{
   205  			name:           "Without any optional values",
   206  			kubeConfigPath: "kubeConfig_app",
   207  			asset: api.AKSAsset{
   208  				Azure: api.Azure{
   209  					TenantID:               "tenant1",
   210  					SubscriptionID:         "subscription1",
   211  					ServicePrincipalID:     "serviceprincipal1",
   212  					ServicePrincipalSecret: "serviceprincipalsecret",
   213  					ResourceGroupName:      "ship",
   214  					Location:               "US East",
   215  				},
   216  				ClusterName: "app",
   217  				NodeCount:   "2",
   218  				NodeType:    "Standard_D1_v2",
   219  			},
   220  			answer: `
   221  provider "azurerm" {
   222    tenant_id       = "tenant1"
   223    subscription_id = "subscription1"
   224    client_id       = "serviceprincipal1"
   225    client_secret   = "serviceprincipalsecret"
   226    version         = "~> 1.14"
   227  }
   228  
   229  resource "azurerm_resource_group" "ship" {
   230    name     = "ship"
   231    location = "US East"
   232  }
   233  
   234  resource "azurerm_kubernetes_cluster" "app" {
   235    name                = "app"
   236    location            = "US East"
   237    resource_group_name = "ship"
   238    dns_prefix          = "app"
   239  
   240    agent_pool_profile {
   241      name            = "app"
   242      count           = 2
   243      vm_size         = "Standard_D1_v2"
   244    }
   245  
   246    service_principal {
   247      client_id     = "serviceprincipal1"
   248      client_secret = "serviceprincipalsecret"
   249    }
   250  }
   251  
   252  resource "local_file" "kubeconfig" {
   253    content = "${azurerm_kubernetes_cluster.app.kube_config_raw}"
   254    filename = "kubeConfig_app"
   255  }
   256  `,
   257  		},
   258  	}
   259  
   260  	for _, test := range tests {
   261  		t.Run(test.name, func(t *testing.T) {
   262  			output, err := renderTerraformContents(test.asset, test.kubeConfigPath)
   263  			if err != nil {
   264  				t.Fatal(err)
   265  			}
   266  			if output != test.answer {
   267  				t.Errorf("%s", output)
   268  			}
   269  		})
   270  	}
   271  }
   272  
   273  func TestSafeClusterName(t *testing.T) {
   274  	var tests = []struct {
   275  		input  string
   276  		answer string
   277  	}{
   278  		{
   279  			input:  "My Cluster",
   280  			answer: "mycluster",
   281  		},
   282  		{
   283  			input:  "1 Cluster",
   284  			answer: "cluster",
   285  		},
   286  		{
   287  			input: "$$777	",
   288  			answer: "y2x1c3rlciqk",
   289  		},
   290  		{
   291  			input:  "!Apps",
   292  			answer: "apps",
   293  		},
   294  	}
   295  	for _, test := range tests {
   296  		t.Run(test.input, func(t *testing.T) {
   297  			output := safeClusterName(test.input)
   298  			if output != test.answer {
   299  				t.Errorf("got %q, want %q", output, test.answer)
   300  			}
   301  		})
   302  	}
   303  }