Пример #1
0
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
}
Пример #2
0
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)
}
Пример #3
0
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
}
Пример #4
0
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)
		}
	}
}
Пример #5
0
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)
}
Пример #6
0
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)
}
Пример #7
0
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)
	}
}
Пример #8
0
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")
	}
}
Пример #9
0
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)
}
Пример #10
0
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)
			}
		})
	}
}
Пример #11
0
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)
}
Пример #12
0
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)
}
Пример #13
0
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)
			}
		})
	}
}
Пример #14
0
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)
			}
		})
	}
}