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 }