2019-12-12 18:20:11 +00:00
|
|
|
package run
|
|
|
|
|
|
|
|
import (
|
2020-01-16 23:32:40 +00:00
|
|
|
"fmt"
|
2020-01-16 21:50:04 +00:00
|
|
|
"github.com/pelotech/drone-helm3/internal/env"
|
2019-12-25 18:10:30 +00:00
|
|
|
"github.com/stretchr/testify/suite"
|
2019-12-26 20:53:36 +00:00
|
|
|
yaml "gopkg.in/yaml.v2"
|
2019-12-12 18:20:11 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2020-01-16 23:30:21 +00:00
|
|
|
"strings"
|
2019-12-12 18:20:11 +00:00
|
|
|
"testing"
|
2019-12-25 18:10:30 +00:00
|
|
|
"text/template"
|
2019-12-12 18:20:11 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type InitKubeTestSuite struct {
|
|
|
|
suite.Suite
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInitKubeTestSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(InitKubeTestSuite))
|
|
|
|
}
|
|
|
|
|
2020-01-16 21:50:04 +00:00
|
|
|
func (suite *InitKubeTestSuite) TestNewInitKube() {
|
|
|
|
cfg := env.Config{
|
|
|
|
SkipTLSVerify: true,
|
|
|
|
Certificate: "cHJvY2xhaW1zIHdvbmRlcmZ1bCBmcmllbmRzaGlw",
|
|
|
|
APIServer: "98.765.43.21",
|
|
|
|
ServiceAccount: "greathelm",
|
|
|
|
KubeToken: "b2YgbXkgYWZmZWN0aW9u",
|
2020-01-16 23:30:21 +00:00
|
|
|
Stderr: &strings.Builder{},
|
|
|
|
Debug: true,
|
2020-01-16 21:50:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
init := NewInitKube(cfg, "conf.tpl", "conf.yml")
|
2020-01-17 18:13:53 +00:00
|
|
|
suite.Equal(kubeValues{
|
|
|
|
SkipTLSVerify: true,
|
|
|
|
Certificate: "cHJvY2xhaW1zIHdvbmRlcmZ1bCBmcmllbmRzaGlw",
|
|
|
|
APIServer: "98.765.43.21",
|
|
|
|
ServiceAccount: "greathelm",
|
|
|
|
Token: "b2YgbXkgYWZmZWN0aW9u",
|
|
|
|
}, init.values)
|
|
|
|
suite.Equal("conf.tpl", init.templateFilename)
|
|
|
|
suite.Equal("conf.yml", init.configFilename)
|
|
|
|
suite.NotNil(init.config)
|
2020-01-16 21:50:04 +00:00
|
|
|
}
|
|
|
|
|
2019-12-12 18:20:11 +00:00
|
|
|
func (suite *InitKubeTestSuite) TestPrepareExecute() {
|
|
|
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", `
|
|
|
|
certificate: {{ .Certificate }}
|
|
|
|
namespace: {{ .Namespace }}
|
|
|
|
`)
|
|
|
|
defer os.Remove(templateFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
configFile, err := tempfile("kubeconfig********.yml", "")
|
|
|
|
defer os.Remove(configFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "Sysadmin",
|
|
|
|
Certificate: "CCNA",
|
|
|
|
KubeToken: "Aspire virtual currency",
|
|
|
|
Namespace: "Cisco",
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
2020-01-17 18:13:53 +00:00
|
|
|
init := NewInitKube(cfg, templateFile.Name(), configFile.Name())
|
|
|
|
err = init.Prepare()
|
2019-12-12 18:20:11 +00:00
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
suite.IsType(&template.Template{}, init.template)
|
|
|
|
suite.NotNil(init.configFile)
|
|
|
|
|
2020-01-16 23:30:21 +00:00
|
|
|
err = init.Execute()
|
2019-12-12 18:20:11 +00:00
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
conf, err := ioutil.ReadFile(configFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
want := `
|
|
|
|
certificate: CCNA
|
|
|
|
namespace: Cisco
|
|
|
|
`
|
|
|
|
suite.Equal(want, string(conf))
|
|
|
|
}
|
|
|
|
|
2019-12-25 18:10:30 +00:00
|
|
|
func (suite *InitKubeTestSuite) TestExecuteGeneratesConfig() {
|
|
|
|
configFile, err := tempfile("kubeconfig********.yml", "")
|
|
|
|
defer os.Remove(configFile.Name())
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "https://kube.cluster/peanut",
|
|
|
|
ServiceAccount: "chef",
|
|
|
|
KubeToken: "eWVhaCB3ZSB0b2tpbic=",
|
|
|
|
Certificate: "d293LCB5b3UgYXJlIHNvIGNvb2wgZm9yIHNtb2tpbmcgd2VlZCDwn5mE",
|
|
|
|
Namespace: "marshmallow",
|
2019-12-25 18:10:30 +00:00
|
|
|
}
|
2020-01-17 18:13:53 +00:00
|
|
|
init := NewInitKube(cfg, "../../assets/kubeconfig.tpl", configFile.Name()) // the actual kubeconfig template
|
|
|
|
suite.Require().NoError(init.Prepare())
|
2020-01-16 23:30:21 +00:00
|
|
|
suite.Require().NoError(init.Execute())
|
2019-12-25 18:10:30 +00:00
|
|
|
|
|
|
|
contents, err := ioutil.ReadFile(configFile.Name())
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
|
|
|
|
// each setting should be reflected in the generated file
|
|
|
|
expectations := []string{
|
|
|
|
"namespace: marshmallow",
|
|
|
|
"server: https://kube.cluster/peanut",
|
|
|
|
"user: chef",
|
|
|
|
"name: chef",
|
|
|
|
"token: eWVhaCB3ZSB0b2tpbic",
|
|
|
|
"certificate-authority-data: d293LCB5b3UgYXJlIHNvIGNvb2wgZm9yIHNtb2tpbmcgd2VlZCDwn5mE",
|
|
|
|
}
|
|
|
|
for _, expected := range expectations {
|
|
|
|
suite.Contains(string(contents), expected)
|
|
|
|
}
|
|
|
|
|
2019-12-26 20:53:36 +00:00
|
|
|
// the generated config should be valid yaml, with no repeated keys
|
|
|
|
conf := map[string]interface{}{}
|
|
|
|
suite.NoError(yaml.UnmarshalStrict(contents, &conf))
|
|
|
|
|
2019-12-25 18:10:30 +00:00
|
|
|
// test the other branch of the certificate/SkipTLSVerify conditional
|
2020-01-16 23:11:42 +00:00
|
|
|
init.values.SkipTLSVerify = true
|
|
|
|
init.values.Certificate = ""
|
2019-12-25 18:10:30 +00:00
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
suite.Require().NoError(init.Prepare())
|
2020-01-16 23:30:21 +00:00
|
|
|
suite.Require().NoError(init.Execute())
|
2019-12-25 18:10:30 +00:00
|
|
|
contents, err = ioutil.ReadFile(configFile.Name())
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
suite.Contains(string(contents), "insecure-skip-tls-verify: true")
|
2019-12-26 20:53:36 +00:00
|
|
|
|
|
|
|
conf = map[string]interface{}{}
|
|
|
|
suite.NoError(yaml.UnmarshalStrict(contents, &conf))
|
2019-12-25 18:10:30 +00:00
|
|
|
}
|
|
|
|
|
2019-12-12 18:20:11 +00:00
|
|
|
func (suite *InitKubeTestSuite) TestPrepareParseError() {
|
|
|
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", `{{ NonexistentFunction }}`)
|
|
|
|
defer os.Remove(templateFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "Sysadmin",
|
|
|
|
Certificate: "CCNA",
|
|
|
|
KubeToken: "Aspire virtual currency",
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
2020-01-17 18:13:53 +00:00
|
|
|
init := NewInitKube(cfg, templateFile.Name(), "")
|
|
|
|
err = init.Prepare()
|
2019-12-12 18:20:11 +00:00
|
|
|
suite.Error(err)
|
|
|
|
suite.Regexp("could not load kubeconfig .* function .* not defined", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *InitKubeTestSuite) TestPrepareNonexistentTemplateFile() {
|
2020-01-17 18:13:53 +00:00
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "Sysadmin",
|
|
|
|
Certificate: "CCNA",
|
|
|
|
KubeToken: "Aspire virtual currency",
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
2020-01-17 18:13:53 +00:00
|
|
|
init := NewInitKube(cfg, "/usr/foreign/exclude/kubeprofig.tpl", "")
|
|
|
|
err := init.Prepare()
|
2019-12-12 18:20:11 +00:00
|
|
|
suite.Error(err)
|
|
|
|
suite.Regexp("could not load kubeconfig .* no such file or directory", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *InitKubeTestSuite) TestPrepareCannotOpenDestinationFile() {
|
|
|
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", "hurgity burgity")
|
|
|
|
defer os.Remove(templateFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
2020-01-17 18:13:53 +00:00
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "Sysadmin",
|
|
|
|
Certificate: "CCNA",
|
|
|
|
KubeToken: "Aspire virtual currency",
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
2020-01-17 18:13:53 +00:00
|
|
|
init := NewInitKube(cfg, templateFile.Name(), "/usr/foreign/exclude/kubeprofig")
|
2019-12-12 18:20:11 +00:00
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
err = init.Prepare()
|
2019-12-12 18:20:11 +00:00
|
|
|
suite.Error(err)
|
|
|
|
suite.Regexp("could not open .* for writing: .* no such file or directory", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *InitKubeTestSuite) TestPrepareRequiredConfig() {
|
|
|
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", "hurgity burgity")
|
|
|
|
defer os.Remove(templateFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
configFile, err := tempfile("kubeconfig********.yml", "")
|
|
|
|
defer os.Remove(configFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
// initial config with all required fields present
|
2020-01-17 18:13:53 +00:00
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "Sysadmin",
|
|
|
|
Certificate: "CCNA",
|
|
|
|
KubeToken: "Aspire virtual currency",
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
init := NewInitKube(cfg, templateFile.Name(), configFile.Name())
|
|
|
|
suite.NoError(init.Prepare()) // consistency check; we should be starting in a happy state
|
2019-12-12 18:20:11 +00:00
|
|
|
|
2020-01-16 23:11:42 +00:00
|
|
|
init.values.APIServer = ""
|
2020-01-17 18:13:53 +00:00
|
|
|
suite.Error(init.Prepare(), "APIServer should be required.")
|
2019-12-12 18:20:11 +00:00
|
|
|
|
2020-01-16 23:11:42 +00:00
|
|
|
init.values.APIServer = "Sysadmin"
|
|
|
|
init.values.Token = ""
|
2020-01-17 18:13:53 +00:00
|
|
|
suite.Error(init.Prepare(), "Token should be required.")
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *InitKubeTestSuite) TestPrepareDefaultsServiceAccount() {
|
|
|
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", "hurgity burgity")
|
|
|
|
defer os.Remove(templateFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
configFile, err := tempfile("kubeconfig********.yml", "")
|
|
|
|
defer os.Remove(configFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "Sysadmin",
|
|
|
|
Certificate: "CCNA",
|
|
|
|
KubeToken: "Aspire virtual currency",
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
2020-01-17 18:13:53 +00:00
|
|
|
init := NewInitKube(cfg, templateFile.Name(), configFile.Name())
|
2019-12-12 18:20:11 +00:00
|
|
|
|
2020-01-17 18:13:53 +00:00
|
|
|
init.Prepare()
|
2020-01-16 23:11:42 +00:00
|
|
|
suite.Equal("helm", init.values.ServiceAccount)
|
2019-12-12 18:20:11 +00:00
|
|
|
}
|
|
|
|
|
2020-01-16 23:32:40 +00:00
|
|
|
func (suite *InitKubeTestSuite) TestDebugOutput() {
|
|
|
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", "hurgity burgity")
|
|
|
|
defer os.Remove(templateFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
configFile, err := tempfile("kubeconfig********.yml", "")
|
|
|
|
defer os.Remove(configFile.Name())
|
|
|
|
suite.Require().Nil(err)
|
|
|
|
|
|
|
|
stdout := &strings.Builder{}
|
|
|
|
stderr := &strings.Builder{}
|
|
|
|
cfg := env.Config{
|
|
|
|
APIServer: "http://my.kube.server/",
|
|
|
|
KubeToken: "QSBzaW5nbGUgcm9zZQ==",
|
|
|
|
Debug: true,
|
|
|
|
Stdout: stdout,
|
|
|
|
Stderr: stderr,
|
|
|
|
}
|
|
|
|
init := NewInitKube(cfg, templateFile.Name(), configFile.Name())
|
2020-01-17 18:13:53 +00:00
|
|
|
suite.NoError(init.Prepare())
|
2020-01-16 23:32:40 +00:00
|
|
|
|
|
|
|
suite.Contains(stderr.String(), fmt.Sprintf("loading kubeconfig template from %s\n", templateFile.Name()))
|
|
|
|
suite.Contains(stderr.String(), fmt.Sprintf("truncating kubeconfig file at %s\n", configFile.Name()))
|
|
|
|
|
|
|
|
suite.NoError(init.Execute())
|
|
|
|
suite.Contains(stderr.String(), fmt.Sprintf("writing kubeconfig file to %s\n", configFile.Name()))
|
|
|
|
}
|
|
|
|
|
2019-12-12 18:20:11 +00:00
|
|
|
func tempfile(name, contents string) (*os.File, error) {
|
|
|
|
file, err := ioutil.TempFile("", name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
_, err = file.Write([]byte(contents))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = file.Close()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return file, nil
|
|
|
|
}
|