func newBaseStack(template string) (*provider.BaseStack, error) { t, err := provider.ParseTemplate(template, nil) if err != nil { return nil, err } s := &provider.BaseStack{ Provider: softlayer.Provider, Req: &kite.Request{ Username: "******", }, Session: &session.Session{ Userdata: &userdata.Userdata{ KlientURL: "https://test.com/klient.gz", Keycreator: &keycreator.Key{ KontrolURL: "https://test.com/kontrol/kite", KontrolPrivateKey: testkeys.Private, KontrolPublicKey: testkeys.Public, }, }, }, Keys: &publickeys.Keys{ PublicKey: "random-publickey", }, Builder: &provider.Builder{ Template: t, }, KlientIDs: make(stack.KiteMap), } return s, nil }
func TestTerraformTemplate_ShadowVariables(t *testing.T) { userTestTemplate := `{ "provider": { "aws": { "access_key": "${var.aws_access_key}", "secret_key": "${var.aws_secret_key}", "region": "${var.aws_region}" } }, "resource": { "aws_instance": { "example": { "bar": "${var.aws_access_key}", "instance_type": "t2.micro", "user_data": "Echo ${var.aws_secret_key}" } } } }` template, err := provider.ParseTemplate(userTestTemplate, log) if err != nil { t.Fatal(err) } err = template.ShadowVariables("FORBIDDEN", "aws_access_key", "aws_secret_key") if err != nil { t.Fatal(err) } fmt.Println(template) }
func newDoBaseStack() (*provider.BaseStack, error) { log := logging.NewCustom("test", true) testTemplate := `{ "variable": { "username": { "default": "testuser" } }, "provider": { "digitalocean": { "token": "${var.digitalocean_access_token}" } }, "resource": { "digitalocean_droplet": { "example": { "name": "web-1", "image": "ubuntu-14-04-x64", "region": "nyc2", "size": "512mb", "user_data": "sudo apt-get install sl -y\ntouch /tmp/${var.username}.txt" } } } }` template, err := provider.ParseTemplate(testTemplate, log) if err != nil { return nil, err } return &provider.BaseStack{ Provider: doProvider, Req: &kite.Request{ Username: "******", }, Arg: &stack.BootstrapRequest{ Provider: "digitalocean", GroupName: "testgroup", }, Keys: &publickeys.Keys{ PublicKey: "random-publickey", }, Builder: &provider.Builder{ Template: template, }, Session: &session.Session{ Userdata: &userdata.Userdata{ KlientURL: "https://example-klient.com", Keycreator: &keycreator.Key{ KontrolURL: "https://example-kontrol.com", KontrolPrivateKey: testkeys.Private, KontrolPublicKey: testkeys.Public, }, }, }, KlientIDs: stack.KiteMap(map[string]string{}), }, nil }
func TestTerraformTemplate_DetectUserVariables(t *testing.T) { userTestTemplate := `{ "variable": { "username": { "default": "fatih" } }, "provider": { "aws": { "access_key": "${var.aws_access_key}", "secret_key": "${var.aws_secret_key}", "region": "${var.aws_region}" } }, "resource": { "aws_instance": { "example": { "count": "${var.userInput_count}", "instance_type": "t2.micro", "user_data": "sudo apt-get install ${var.userInput_foo} -y\ntouch /tmp/${var.username}.txt" } } } }` template, err := provider.ParseTemplate(userTestTemplate, log) if err != nil { t.Fatal(err) } vars, err := template.DetectUserVariables("") if err != nil { t.Fatal(err) } has := func(v string) bool { mustHave := []string{ "aws_access_key", "aws_secret_key", "aws_region", "userInput_foo", "userInput_count", "username", } for _, m := range mustHave { if m == v { return true } } return false } for key := range vars { if !has(key) { t.Errorf("Variable '%s' should exist in the template", key) } } }
func TestTerraformTemplate_SetAWSRegion(t *testing.T) { missingRegionTemplate := `{ "variable": { "username": { "default": "fatih" } }, "provider": { "aws": { "access_key": "${var.aws_access_key}", "secret_key": "${var.aws_secret_key}" } }, "resource": { "aws_instance": { "example": { "count": "${var.userInput_count}", "instance_type": "t2.micro", "user_data": "sudo apt-get install ${var.userInput_foo} -y\ntouch /tmp/${var.username}.txt" } } } }` template, err := provider.ParseTemplate(missingRegionTemplate, log) if err != nil { t.Fatal(err) } // TODO(rjeczalik): move the test to provider/aws s := &aws.Stack{BaseStack: &provider.BaseStack{Builder: &provider.Builder{Template: template}}} if err := s.SetAwsRegion("us-east-1"); err != nil { t.Fatal(err) } var provider struct { Aws struct { Region string `hcl:"region"` AccessKey string `hcl:"access_key"` SecretKey string `hcl:"secret_key"` } } if err := template.DecodeProvider(&provider); err != nil { t.Fatal(err) } equals(t, "${var.aws_access_key}", provider.Aws.AccessKey) equals(t, "${var.aws_secret_key}", provider.Aws.SecretKey) equals(t, "us-east-1", provider.Aws.Region) }
func TestTerraformTemplate_FillVariables(t *testing.T) { userTestTemplate := `{ "variable": { "username": { "default": "fatih" } }, "provider": { "aws": { "access_key": "${var.aws_access_key}", "secret_key": "${var.aws_secret_key}", "region": "${var.aws_region}" } }, "resource": { "aws_instance": { "example": { "count": "${var.userInput_count}", "instance_type": "t2.micro", "user_data": "sudo apt-get install ${var.userInput_foo} -y\ntouch /tmp/${var.username}.txt" } } } }` template, err := provider.ParseTemplate(userTestTemplate, log) if err != nil { t.Fatal(err) } if err := template.FillVariables("userInput"); err != nil { t.Fatal(err) } var variable struct { UserInputCount struct { Default string } `hcl:"userInput_count"` UserInputFoo struct { Default string } `hcl:"userInput_foo"` } if err := template.DecodeVariable(&variable); err != nil { t.Fatal(err) } // these should be empty equals(t, "", variable.UserInputCount.Default) equals(t, "", variable.UserInputFoo.Default) }
func TestTerraformTemplate_Encoding(t *testing.T) { userTestTemplate := `{ "variable": { "username": { "default": "fatih" } }, "provider": { "aws": { "access_key": "${var.aws_access_key}", "secret_key": "${var.aws_secret_key}", "region": "${var.aws_region}" } }, "resource": { "aws_instance": { "example": { "instance_type": "t2.micro", "user_data": "echo 'fatih' > /tmp/hello.txt\necho 'arslan' > /tmp/${var.username}.txt" } } } }` template, err := provider.ParseTemplate(userTestTemplate, log) if err != nil { t.Fatal(err) } var resource struct { AwsInstance struct { Example struct { UserData string `hcl:"user_data"` } `hcl:"example"` } `hcl:"aws_instance"` } if err := template.DecodeResource(&resource); err != nil { t.Fatal(err) } if !strings.Contains(resource.AwsInstance.Example.UserData, `>`) { t.Errorf("Brackets should be encoded\n\tOutput: %s\n", resource.AwsInstance.Example.UserData) } }
func TestTerraformTemplate_NewNil(t *testing.T) { template, err := provider.ParseTemplate(testTemplate, log) if err != nil { t.Fatal(err) } if template.Variable == nil { t.Error("Variable field should be not nil") } if template.Output == nil { t.Error("Output field should be not nil") } if template.Provider == nil { t.Error("Provider field should be not nil") } if template.Resource == nil { t.Error("Resource field should be not nil") } }
func TestTerraformTemplate_DecodeProvider(t *testing.T) { template, err := provider.ParseTemplate(testTemplate, log) if err != nil { t.Fatal(err) } var provider struct { Aws struct { Region string AccessKey string `hcl:"access_key"` SecretKey string `hcl:"secret_key"` } } if err := template.DecodeProvider(&provider); err != nil { t.Fatal(err) } equals(t, "${var.aws_access_key}", provider.Aws.AccessKey) equals(t, "${var.aws_secret_key}", provider.Aws.SecretKey) equals(t, "${var.aws_region}", provider.Aws.Region) }
func TestAzure_ApplyTemplate(t *testing.T) { log := logging.NewCustom("test", true) cred := &stack.Credential{ Credential: &azure.Cred{ PublishSettings: "publish_settings", SSHKeyThumbprint: "12:23:45:56:67:89:90", }, Bootstrap: &azure.Bootstrap{ AddressSpace: "10.10.10.10/16", StorageServiceID: "storage-serice", HostedServiceID: "hosted-service", SecurityGroupID: "security-group", VirtualNetworkID: "virtual-network", SubnetName: "subnet", }, } cases := map[string]struct { stackFile string wantFile string }{ "basic stack": { "testdata/basic-stack.json", "testdata/basic-stack.json.golden", }, "basic stack with count=3": { "testdata/basic-stack-count-3.json", "testdata/basic-stack-count-3.json.golden", }, "custom endpoint": { "testdata/custom-endpoint.json", "testdata/custom-endpoint.json.golden", }, } for name, cas := range cases { t.Run(name, func(t *testing.T) { content, err := ioutil.ReadFile(cas.stackFile) if err != nil { t.Fatalf("ReadFile(%s)=%s", cas.stackFile, err) } want, err := ioutil.ReadFile(cas.wantFile) if err != nil { t.Fatalf("ReadFile(%s)=%s", cas.wantFile, err) } template, err := provider.ParseTemplate(string(content), log) if err != nil { t.Fatalf("ParseTemplate()=%s", err) } s := &azure.Stack{ BaseStack: &provider.BaseStack{ Session: &session.Session{ Userdata: &userdata.Userdata{ KlientURL: "http://127.0.0.1/klient.gz", Keycreator: &keycreator.Key{ KontrolURL: "http://127.0.0.1/kontrol/kite", KontrolPublicKey: testkeys.Public, KontrolPrivateKey: testkeys.Private, }, }, }, Builder: &provider.Builder{ Template: template, }, Req: &kite.Request{ Username: "******", }, KlientIDs: make(stack.KiteMap), }, } stack, err := s.ApplyTemplate(cred) if err != nil { t.Fatalf("ApplyTemplate()=%s", err) } if err := equal(stack.Content, string(want)); err != nil { t.Fatal(err) } }) } }
func TestTerraformTemplate_InjectKodingData(t *testing.T) { template, err := provider.ParseTemplate(testTemplate, log) if err != nil { t.Fatal(err) } data := &provider.KodingMeta{ Username: "******", Email: "*****@*****.**", Nickname: "fatih", Firstname: "Fatih", Lastname: "Arslan", Hash: "124", Title: "MyGroup", Slug: "my_group", } if err := template.InjectVariables("koding", data); err != nil { t.Fatal(err) } var variable struct { KodingAccountProfileFirstName struct { Default string } `hcl:"koding_account_profile_firstName"` KodingAccountProfileHash struct { Default string } `hcl:"koding_account_profile_hash"` KodingAccountProfileLastName struct { Default string } `hcl:"koding_account_profile_lastName"` KodingAccountProfileNickname struct { Default string } `hcl:"koding_account_profile_nickname"` KodingGroupSlug struct { Default string } `hcl:"koding_group_slug"` KodingGroupTitle struct { Default string } `hcl:"koding_group_title"` KodingUserEmail struct { Default string } `hcl:"koding_user_email"` KodingUserUsername struct { Default string } `hcl:"koding_user_username"` } if err := template.DecodeVariable(&variable); err != nil { t.Fatal(err) } equals(t, "Fatih", variable.KodingAccountProfileFirstName.Default) equals(t, "124", variable.KodingAccountProfileHash.Default) equals(t, "Arslan", variable.KodingAccountProfileLastName.Default) equals(t, "fatih", variable.KodingAccountProfileNickname.Default) equals(t, "my_group", variable.KodingGroupSlug.Default) equals(t, "MyGroup", variable.KodingGroupTitle.Default) equals(t, "Fatih", variable.KodingUserUsername.Default) equals(t, "*****@*****.**", variable.KodingUserEmail.Default) }
func TestTerraformTemplate_InjectCustomVariable(t *testing.T) { template, err := provider.ParseTemplate(testTemplate, log) if err != nil { t.Fatal(err) } prefix := "custom" data := provider.CustomMeta{ "foo": "1", "bar": "*****@*****.**", "qaz": "hello", "_notHidden": "notHidden", "__hidden": "${var.value}", "__rawContent": "${var.custom___otherHidden}", "__otherHidden": "${var.value}", } if err := template.InjectVariables(prefix, data); err != nil { t.Fatal(err) } var variable struct { CustomBar struct { Default string } `hcl:"custom_bar"` CustomFoo struct { Default string } `hcl:"custom_foo"` CustomQaz struct { Default string } `hcl:"custom_qaz"` Username struct { Default string } `hcl:"username"` NotHidden struct { Default string } `hcl:"custom__notHidden"` Hidden struct { Default string } `hcl:"custom___hidden"` RawContent struct { Default string } `hcl:"custom___rawContent"` OtherHidden struct { Default string } `hcl:"custom___otherHidden"` } if err := template.DecodeVariable(&variable); err != nil { t.Fatal(err) } equals(t, "*****@*****.**", variable.CustomBar.Default) equals(t, "1", variable.CustomFoo.Default) equals(t, "hello", variable.CustomQaz.Default) equals(t, "fatih", variable.Username.Default) equals(t, "notHidden", variable.NotHidden.Default) equals(t, "", variable.Hidden.Default) equals(t, "", variable.RawContent.Default) equals(t, "", variable.OtherHidden.Default) }
func TestStack_ApplyTemplate(t *testing.T) { log := logging.NewCustom("test", true) cred := &stack.Credential{ Credential: &Credential{ AccessToken: "12345", }, Bootstrap: &Bootstrap{ KeyFingerprint: "aa:bb:cc", KeyID: "56789", }, } cases := map[string]struct { stackFile string wantFile string }{ "basic stack": { "testdata/basic-stack.json", "testdata/basic-stack.json.golden", }, "basic stack count 2": { "testdata/basic-stack-count-2.json", "testdata/basic-stack-count-2.json.golden", }, } for name, cas := range cases { t.Run(name, func(t *testing.T) { content, err := ioutil.ReadFile(cas.stackFile) if err != nil { t.Fatalf("ReadFile(%s)=%s", cas.stackFile, err) } want, err := ioutil.ReadFile(cas.wantFile) if err != nil { t.Fatalf("ReadFile(%s)=%s", cas.wantFile, err) } template, err := provider.ParseTemplate(string(content), log) if err != nil { t.Fatalf("ParseTemplate()=%s", err) } s := &Stack{ BaseStack: &provider.BaseStack{ Session: &session.Session{ Userdata: &userdata.Userdata{ KlientURL: "http://127.0.0.1/klient.gz", Keycreator: &keycreator.Key{ KontrolURL: "http://127.0.0.1/kontrol/kite", KontrolPublicKey: testkeys.Public, KontrolPrivateKey: testkeys.Private, }, }, }, Builder: &provider.Builder{ Template: template, }, Req: &kite.Request{ Username: "******", }, KlientIDs: make(stack.KiteMap), }, } stack, err := s.ApplyTemplate(cred) if err != nil { t.Fatalf("ApplyTemplate()=%s", err) } if err := equal(stack.Content, string(want)); err != nil { t.Fatal(err) } }) } }
func TestApplyTemplate(t *testing.T) { log := logging.NewCustom("test", true) cred := &stack.Credential{ Identifier: "ident", Credential: &marathon.Credential{URL: "http://127.0.0.1:8080"}, } cases := map[string]struct { stack string want string labels []marathon.Label }{ "single app stack": { "testdata/single-app.json", "testdata/single-app.json.golden", []marathon.Label{ {Label: "/app", AppID: "/app-user-ident"}, }, }, "multi app stack": { "testdata/multi-app.json", "testdata/multi-app.json.golden", []marathon.Label{ {Label: "/multi-app-1", AppID: "/multi-app/multi-app-user-ident-1"}, {Label: "/multi-app-2", AppID: "/multi-app/multi-app-user-ident-2"}, {Label: "/multi-app-3", AppID: "/multi-app/multi-app-user-ident-3"}, }, }, "multi container stack": { "testdata/multi-container.json", "testdata/multi-container.json.golden", []marathon.Label{ {Label: "/multi-app-1", AppID: "/multi-app-user-ident"}, {Label: "/multi-app-2", AppID: "/multi-app-user-ident"}, {Label: "/multi-app-3", AppID: "/multi-app-user-ident"}, }, }, "multi app multi container stack": { "testdata/multi-app-multi-container.json", "testdata/multi-app-multi-container.json.golden", []marathon.Label{ {Label: "/multi-app-1-1", AppID: "/multi-app/multi-app-user-ident-1"}, {Label: "/multi-app-1-2", AppID: "/multi-app/multi-app-user-ident-1"}, {Label: "/multi-app-1-3", AppID: "/multi-app/multi-app-user-ident-1"}, {Label: "/multi-app-2-1", AppID: "/multi-app/multi-app-user-ident-2"}, {Label: "/multi-app-2-2", AppID: "/multi-app/multi-app-user-ident-2"}, {Label: "/multi-app-2-3", AppID: "/multi-app/multi-app-user-ident-2"}, {Label: "/multi-app-3-1", AppID: "/multi-app/multi-app-user-ident-3"}, {Label: "/multi-app-3-2", AppID: "/multi-app/multi-app-user-ident-3"}, {Label: "/multi-app-3-3", AppID: "/multi-app/multi-app-user-ident-3"}, }, }, } for name, cas := range cases { t.Run(name, func(t *testing.T) { pStack, err := ioutil.ReadFile(cas.stack) if err != nil { t.Fatalf("ReadFile()=%s", err) } pWant, err := ioutil.ReadFile(cas.want) if err != nil { t.Fatalf("ReadFile()=%s", err) } template, err := provider.ParseTemplate(string(pStack), log) if err != nil { t.Fatalf("ParseTemplate()=%s", err) } s := &marathon.Stack{ BaseStack: &provider.BaseStack{ Arg: &stack.ApplyRequest{ GroupName: "foobar", }, Session: &session.Session{ Userdata: &userdata.Userdata{ KlientURL: "http://127.0.0.1/klient.gz", Keycreator: &keycreator.Key{ KontrolURL: "http://127.0.0.1/kontrol/kite", KontrolPublicKey: testkeys.Public, KontrolPrivateKey: testkeys.Private, }, }, }, Builder: &provider.Builder{ Template: template, }, Req: &kite.Request{ Username: "******", }, KlientIDs: make(stack.KiteMap), }, EntrypointBaseURL: "$ENTRYPOINT_URL", ScreenURL: "$SCREEN_URL", CertURL: "$CERT_URL", KlientURL: "$KLIENT_URL", } stack, err := s.ApplyTemplate(cred) if err != nil { t.Fatalf("ApplyTemplate()=%s", err) } if err := providertest.Equal(stack.Content, string(pWant), stripNondeterministicResources); err != nil { t.Fatal(err) } if !reflect.DeepEqual(s.Labels, cas.labels) { t.Fatalf("got %#v, want %#v", s.Labels, cas.labels) } }) } }