woodpecker-helm3/internal/run/initkube_test.go
Erin Call 231138563c
Remove the cfg argument from Step.Execute [#67]
This is the first step toward removing run.Config entirely. InitKube was
the only Step that even used cfg in its Execute function; the rest just
discarded it.
2020-01-16 15:30:40 -08:00

269 lines
7.1 KiB
Go

package run
import (
"github.com/pelotech/drone-helm3/internal/env"
"github.com/stretchr/testify/suite"
yaml "gopkg.in/yaml.v2"
"io/ioutil"
"os"
"strings"
"testing"
"text/template"
)
type InitKubeTestSuite struct {
suite.Suite
}
func TestInitKubeTestSuite(t *testing.T) {
suite.Run(t, new(InitKubeTestSuite))
}
func (suite *InitKubeTestSuite) TestNewInitKube() {
cfg := env.Config{
SkipTLSVerify: true,
Certificate: "cHJvY2xhaW1zIHdvbmRlcmZ1bCBmcmllbmRzaGlw",
APIServer: "98.765.43.21",
ServiceAccount: "greathelm",
KubeToken: "b2YgbXkgYWZmZWN0aW9u",
Stderr: &strings.Builder{},
Debug: true,
}
init := NewInitKube(cfg, "conf.tpl", "conf.yml")
suite.Equal(&InitKube{
values: kubeValues{
SkipTLSVerify: true,
Certificate: "cHJvY2xhaW1zIHdvbmRlcmZ1bCBmcmllbmRzaGlw",
APIServer: "98.765.43.21",
ServiceAccount: "greathelm",
Token: "b2YgbXkgYWZmZWN0aW9u",
},
templateFilename: "conf.tpl",
configFilename: "conf.yml",
debug: true,
stderr: cfg.Stderr,
}, init)
}
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)
init := InitKube{
values: kubeValues{
APIServer: "Sysadmin",
Certificate: "CCNA",
Token: "Aspire virtual currency",
Namespace: "Cisco",
},
templateFilename: templateFile.Name(),
configFilename: configFile.Name(),
}
cfg := Config{}
err = init.Prepare(cfg)
suite.Require().Nil(err)
suite.IsType(&template.Template{}, init.template)
suite.NotNil(init.configFile)
err = init.Execute()
suite.Require().Nil(err)
conf, err := ioutil.ReadFile(configFile.Name())
suite.Require().Nil(err)
want := `
certificate: CCNA
namespace: Cisco
`
suite.Equal(want, string(conf))
}
func (suite *InitKubeTestSuite) TestExecuteGeneratesConfig() {
configFile, err := tempfile("kubeconfig********.yml", "")
defer os.Remove(configFile.Name())
suite.Require().NoError(err)
cfg := Config{}
init := InitKube{
configFilename: configFile.Name(),
templateFilename: "../../assets/kubeconfig.tpl", // the actual kubeconfig template
values: kubeValues{
APIServer: "https://kube.cluster/peanut",
ServiceAccount: "chef",
Token: "eWVhaCB3ZSB0b2tpbic=",
Certificate: "d293LCB5b3UgYXJlIHNvIGNvb2wgZm9yIHNtb2tpbmcgd2VlZCDwn5mE",
Namespace: "marshmallow",
},
}
suite.Require().NoError(init.Prepare(cfg))
suite.Require().NoError(init.Execute())
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)
}
// the generated config should be valid yaml, with no repeated keys
conf := map[string]interface{}{}
suite.NoError(yaml.UnmarshalStrict(contents, &conf))
// test the other branch of the certificate/SkipTLSVerify conditional
init.values.SkipTLSVerify = true
init.values.Certificate = ""
suite.Require().NoError(init.Prepare(cfg))
suite.Require().NoError(init.Execute())
contents, err = ioutil.ReadFile(configFile.Name())
suite.Require().NoError(err)
suite.Contains(string(contents), "insecure-skip-tls-verify: true")
conf = map[string]interface{}{}
suite.NoError(yaml.UnmarshalStrict(contents, &conf))
}
func (suite *InitKubeTestSuite) TestPrepareParseError() {
templateFile, err := tempfile("kubeconfig********.yml.tpl", `{{ NonexistentFunction }}`)
defer os.Remove(templateFile.Name())
suite.Require().Nil(err)
init := InitKube{
values: kubeValues{
APIServer: "Sysadmin",
Certificate: "CCNA",
Token: "Aspire virtual currency",
},
templateFilename: templateFile.Name(),
}
err = init.Prepare(Config{})
suite.Error(err)
suite.Regexp("could not load kubeconfig .* function .* not defined", err)
}
func (suite *InitKubeTestSuite) TestPrepareNonexistentTemplateFile() {
init := InitKube{
values: kubeValues{
APIServer: "Sysadmin",
Certificate: "CCNA",
Token: "Aspire virtual currency",
},
templateFilename: "/usr/foreign/exclude/kubeprofig.tpl",
}
err := init.Prepare(Config{})
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)
init := InitKube{
values: kubeValues{
APIServer: "Sysadmin",
Certificate: "CCNA",
Token: "Aspire virtual currency",
},
templateFilename: templateFile.Name(),
configFilename: "/usr/foreign/exclude/kubeprofig",
}
cfg := Config{}
err = init.Prepare(cfg)
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
init := InitKube{
values: kubeValues{
APIServer: "Sysadmin",
Certificate: "CCNA",
Token: "Aspire virtual currency",
},
templateFilename: templateFile.Name(),
configFilename: configFile.Name(),
}
cfg := Config{}
suite.NoError(init.Prepare(cfg)) // consistency check; we should be starting in a happy state
init.values.APIServer = ""
suite.Error(init.Prepare(cfg), "APIServer should be required.")
init.values.APIServer = "Sysadmin"
init.values.Token = ""
suite.Error(init.Prepare(cfg), "Token should be required.")
}
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)
init := InitKube{
values: kubeValues{
APIServer: "Sysadmin",
Certificate: "CCNA",
Token: "Aspire virtual currency",
},
templateFilename: templateFile.Name(),
configFilename: configFile.Name(),
}
cfg := Config{}
init.Prepare(cfg)
suite.Equal("helm", init.values.ServiceAccount)
}
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
}