Compare commits
11 Commits
v0.5.0
...
eks-suppor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c1ed849ab | ||
|
|
d8d2e33b20 | ||
|
|
3b78f01b45 | ||
|
|
24060c18fc | ||
|
|
232bb5eb96 | ||
|
|
c0964ae178 | ||
|
|
a71bba71fd | ||
|
|
f00f6a6329 | ||
|
|
1a70a626ea | ||
|
|
4f549ddf2a | ||
|
|
4cd369b051 |
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* @erincall @grinnellian @kav @josmo
|
||||||
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Unexpected or broken behavior
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**What I tried to do:**
|
||||||
|
<!-- e.g. run a helm installation -->
|
||||||
|
|
||||||
|
**What happened:**
|
||||||
|
<!-- describe the faulty behavior -->
|
||||||
|
|
||||||
|
**More info:**
|
||||||
|
<!-- contents of .drone.yml, etc. -->
|
||||||
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest a new feature
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**The problem I'm trying to solve:**
|
||||||
|
<!-- describe what you'd like to be able to accomplish -->
|
||||||
|
|
||||||
|
**How I imagine it working:**
|
||||||
|
<!-- e.g. configuration that could go in .drone.yml -->
|
||||||
8
.github/pull_request_template.md
vendored
Normal file
8
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
**Please replace this line with "fixes #ISSUE_NUMBER" (or "relates to #ISSUE_NUMBER", if it is not a complete fix)**
|
||||||
|
|
||||||
|
Pre-merge checklist:
|
||||||
|
|
||||||
|
* [ ] Code changes have tests
|
||||||
|
* [ ] Any changes to the config are documented in `docs/parameter_reference.md`
|
||||||
|
* [ ] Any new _required_ config is documented in `README.md`
|
||||||
|
* [ ] Any large changes have been verified by running a Drone job
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,3 +13,5 @@
|
|||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
# vendor/
|
||||||
|
.env
|
||||||
|
.secrets
|
||||||
|
|||||||
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at [workwithus@pelo.tech](mailto:workwithus@pelo.tech). All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
||||||
48
docs/contributing.md
Normal file
48
docs/contributing.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Contributing to drone-helm3
|
||||||
|
|
||||||
|
We're glad you're interested in contributing! Here are some guidelines that will help make sure everyone has a good experience:
|
||||||
|
|
||||||
|
## Submitting a patch
|
||||||
|
|
||||||
|
Before you start working on a change, please make sure there's an associated issue. It doesn't need to be thoroughly scrutinized and dissected, but it needs to exist.
|
||||||
|
|
||||||
|
Please put the relevant issue number in the first line of your commit messages, e.g. `vorpalize the frabjulator [#42]`. Branch names do not need issue numbers, but feel free to include them if you like.
|
||||||
|
|
||||||
|
We encourage you to follow [the guidelines in Pro Git](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines) when making commits. In short:
|
||||||
|
|
||||||
|
* Commit early and commit often.
|
||||||
|
* Make the first line of the commit message concise--no more than 50 characters or so.
|
||||||
|
* Make the rest of the commit message verbose--information about _why_ you did what you did is particularly helpful.
|
||||||
|
|
||||||
|
Once you're satisfied with your work, send us a pull request. If you'd like, you can send the pull request _before_ you're satisfied with your work; just be sure to mark the PR a draft or put `[WIP]` in the title.
|
||||||
|
|
||||||
|
## How to run the tests
|
||||||
|
|
||||||
|
We use `go test`, `go vet`, and `golint`:
|
||||||
|
|
||||||
|
```
|
||||||
|
go test ./cmd/... ./internal/...
|
||||||
|
go vet ./cmd/... ./internal/...
|
||||||
|
golint -set_exit_status ./cmd/... ./internal/...
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have [the Drone cli tool](https://docs.drone.io/cli/install/) installed, you can also use `drone exec --include test --include lint`.
|
||||||
|
|
||||||
|
## Testing the plugin end-to-end
|
||||||
|
|
||||||
|
Although we aim to make the internal tests as thorough as possible, they can't test drone-helm3's integration with drone and helm themselves. However, you can test a change manually by building an image and running it with a fixture repository.
|
||||||
|
|
||||||
|
You will need:
|
||||||
|
|
||||||
|
* Access to a docker image registry. This document assumes you'll use [Docker Hub](https://hub.docker.com).
|
||||||
|
* [The Drone cli tool](https://docs.drone.io/cli/install/).
|
||||||
|
* A fixture repository--a directory with a `.drone.yml` and a helm chart. If you don't have one handy, try adding a `.drone.yml` to a chart from [Helm's "stable" repository](https://github.com/helm/charts/tree/master/stable/).
|
||||||
|
* Access to a kubernetes cluster (unless `lint` or `dry_run` is sufficient for your purposes).
|
||||||
|
|
||||||
|
Once you have what you need, you can publish and consume an image with your changes:
|
||||||
|
|
||||||
|
1. [Create a repository on Docker Hub](https://hub.docker.com/repository/create). This document assumes you've called it drone-helm3-testing.
|
||||||
|
1. Create a `.secrets` file with your docker credentials (see [example.secrets](./example.secrets) for an example). While you can use your Docker Hub password, it's better to [generate an access token](https://hub.docker.com/settings/security) and use that instead.
|
||||||
|
1. Use Drone to build and publish an image with your changes: `drone exec --secret-file ./secrets --event push`
|
||||||
|
1. In the `.drone.yml` of your fixture repository, set the `image` for each relevant stanza to `your_dockerhub_username/drone-helm3-testing`
|
||||||
|
1. Use `drone exec` in the fixture repo to verify your changes.
|
||||||
3
docs/example.secrets
Normal file
3
docs/example.secrets
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
DOCKER_PASSWORD=your_access_token
|
||||||
|
DOCKER_USERNAME=your_dockerhub_username
|
||||||
|
PLUGIN_REPO=your_dockerhub_username/drone-helm3-testing
|
||||||
@@ -30,7 +30,9 @@ Installations are triggered when the `helm_command` setting is "upgrade." They c
|
|||||||
| chart | string | yes | The chart to use for this installation. |
|
| chart | string | yes | The chart to use for this installation. |
|
||||||
| release | string | yes | The release name for helm to use. |
|
| release | string | yes | The release name for helm to use. |
|
||||||
| api_server | string | yes | API endpoint for the Kubernetes cluster. |
|
| api_server | string | yes | API endpoint for the Kubernetes cluster. |
|
||||||
| kubernetes_token | string | yes | Token for authenticating to Kubernetes. |
|
| kubernetes_token | string | yes, unless using EKS | Token for authenticating to Kubernetes. |
|
||||||
|
| eks_cluster | string | | AWS EKS cluster ID. |
|
||||||
|
| eks_role_arn | string | | AWS IAM role ARN for EKS authentication. |
|
||||||
| service_account | string | | Service account for authenticating to Kubernetes. Default is `helm`. |
|
| service_account | string | | Service account for authenticating to Kubernetes. Default is `helm`. |
|
||||||
| kubernetes_certificate | string | | Base64 encoded TLS certificate used by the Kubernetes cluster's certificate authority. |
|
| kubernetes_certificate | string | | Base64 encoded TLS certificate used by the Kubernetes cluster's certificate authority. |
|
||||||
| chart_version | string | | Specific chart version to install. |
|
| chart_version | string | | Specific chart version to install. |
|
||||||
@@ -52,7 +54,9 @@ Uninstallations are triggered when the `helm_command` setting is "uninstall" or
|
|||||||
|------------------------|----------|----------|---------|
|
|------------------------|----------|----------|---------|
|
||||||
| release | string | yes | The release name for helm to use. |
|
| release | string | yes | The release name for helm to use. |
|
||||||
| api_server | string | yes | API endpoint for the Kubernetes cluster. |
|
| api_server | string | yes | API endpoint for the Kubernetes cluster. |
|
||||||
| kubernetes_token | string | yes | Token for authenticating to Kubernetes. |
|
| kubernetes_token | string | yes, unless using EKS | Token for authenticating to Kubernetes. |
|
||||||
|
| eks_cluster | string | | AWS EKS cluster ID. |
|
||||||
|
| eks_role_arn | string | | AWS IAM role ARN for EKS authentication. |
|
||||||
| service_account | string | | Service account for authenticating to Kubernetes. Default is `helm`. |
|
| service_account | string | | Service account for authenticating to Kubernetes. Default is `helm`. |
|
||||||
| kubernetes_certificate | string | | Base64 encoded TLS certificate used by the Kubernetes cluster's certificate authority. |
|
| kubernetes_certificate | string | | Base64 encoded TLS certificate used by the Kubernetes cluster's certificate authority. |
|
||||||
| dry_run | boolean | | Pass `--dry-run` to `helm uninstall`. |
|
| dry_run | boolean | | Pass `--dry-run` to `helm uninstall`. |
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ type Config struct {
|
|||||||
ValuesFiles []string `split_words:"true"` // Arguments to pass to --values in applicable helm commands
|
ValuesFiles []string `split_words:"true"` // Arguments to pass to --values in applicable helm commands
|
||||||
Namespace string `` // Kubernetes namespace for all helm commands
|
Namespace string `` // Kubernetes namespace for all helm commands
|
||||||
KubeToken string `envconfig:"KUBERNETES_TOKEN"` // Kubernetes authentication token to put in .kube/config
|
KubeToken string `envconfig:"KUBERNETES_TOKEN"` // Kubernetes authentication token to put in .kube/config
|
||||||
|
EKSCluster string `envconfig:"EKS_CLUSTER"` // AWS EKS Cluster ID to put in .kube/config
|
||||||
|
EKSRoleARN string `envconfig:"EKS_ROLE_ARN"` // AWS IAM role resource name to put in .kube/config
|
||||||
SkipTLSVerify bool `envconfig:"SKIP_TLS_VERIFY"` // Put insecure-skip-tls-verify in .kube/config
|
SkipTLSVerify bool `envconfig:"SKIP_TLS_VERIFY"` // Put insecure-skip-tls-verify in .kube/config
|
||||||
Certificate string `envconfig:"KUBERNETES_CERTIFICATE"` // The Kubernetes cluster CA's self-signed certificate (must be base64-encoded)
|
Certificate string `envconfig:"KUBERNETES_CERTIFICATE"` // The Kubernetes cluster CA's self-signed certificate (must be base64-encoded)
|
||||||
APIServer string `envconfig:"API_SERVER"` // The Kubernetes cluster's API endpoint
|
APIServer string `envconfig:"API_SERVER"` // The Kubernetes cluster's API endpoint
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ func determineSteps(cfg Config) *func(Config) []Step {
|
|||||||
return &help
|
return &help
|
||||||
default:
|
default:
|
||||||
switch cfg.DroneEvent {
|
switch cfg.DroneEvent {
|
||||||
// Note: These events are documented in docs/upgrade_settings.yml. Any changes here should be reflected there.
|
|
||||||
case "push", "tag", "deployment", "pull_request", "promote", "rollback":
|
case "push", "tag", "deployment", "pull_request", "promote", "rollback":
|
||||||
return &upgrade
|
return &upgrade
|
||||||
case "delete":
|
case "delete":
|
||||||
@@ -143,6 +142,8 @@ func initKube(cfg Config) []Step {
|
|||||||
APIServer: cfg.APIServer,
|
APIServer: cfg.APIServer,
|
||||||
ServiceAccount: cfg.ServiceAccount,
|
ServiceAccount: cfg.ServiceAccount,
|
||||||
Token: cfg.KubeToken,
|
Token: cfg.KubeToken,
|
||||||
|
EKSCluster: cfg.EKSCluster,
|
||||||
|
EKSRoleARN: cfg.EKSRoleARN,
|
||||||
TemplateFile: kubeConfigTemplate,
|
TemplateFile: kubeConfigTemplate,
|
||||||
ConfigFile: kubeConfigFile,
|
ConfigFile: kubeConfigFile,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -212,6 +212,8 @@ func (suite *PlanTestSuite) TestInitKube() {
|
|||||||
Certificate: "b2Ygd29rZW5lc3MK",
|
Certificate: "b2Ygd29rZW5lc3MK",
|
||||||
APIServer: "123.456.78.9",
|
APIServer: "123.456.78.9",
|
||||||
ServiceAccount: "helmet",
|
ServiceAccount: "helmet",
|
||||||
|
EKSCluster: "eks_reader",
|
||||||
|
EKSRoleARN: "arn:aws:iam::9631085:role/eksSpangleRole",
|
||||||
}
|
}
|
||||||
|
|
||||||
steps := initKube(cfg)
|
steps := initKube(cfg)
|
||||||
@@ -225,6 +227,8 @@ func (suite *PlanTestSuite) TestInitKube() {
|
|||||||
APIServer: "123.456.78.9",
|
APIServer: "123.456.78.9",
|
||||||
ServiceAccount: "helmet",
|
ServiceAccount: "helmet",
|
||||||
Token: "cXVlZXIgY2hhcmFjdGVyCg==",
|
Token: "cXVlZXIgY2hhcmFjdGVyCg==",
|
||||||
|
EKSCluster: "eks_reader",
|
||||||
|
EKSRoleARN: "arn:aws:iam::9631085:role/eksSpangleRole",
|
||||||
TemplateFile: kubeConfigTemplate,
|
TemplateFile: kubeConfigTemplate,
|
||||||
ConfigFile: kubeConfigFile,
|
ConfigFile: kubeConfigFile,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ type InitKube struct {
|
|||||||
APIServer string
|
APIServer string
|
||||||
ServiceAccount string
|
ServiceAccount string
|
||||||
Token string
|
Token string
|
||||||
|
EKSCluster string
|
||||||
|
EKSRoleARN string
|
||||||
TemplateFile string
|
TemplateFile string
|
||||||
ConfigFile string
|
ConfigFile string
|
||||||
|
|
||||||
@@ -30,6 +32,8 @@ type kubeValues struct {
|
|||||||
Namespace string
|
Namespace string
|
||||||
ServiceAccount string
|
ServiceAccount string
|
||||||
Token string
|
Token string
|
||||||
|
EKSCluster string
|
||||||
|
EKSRoleARN string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute generates a kubernetes config file from drone-helm3's template.
|
// Execute generates a kubernetes config file from drone-helm3's template.
|
||||||
@@ -48,9 +52,12 @@ func (i *InitKube) Prepare(cfg Config) error {
|
|||||||
if i.APIServer == "" {
|
if i.APIServer == "" {
|
||||||
return errors.New("an API Server is needed to deploy")
|
return errors.New("an API Server is needed to deploy")
|
||||||
}
|
}
|
||||||
if i.Token == "" {
|
if i.Token == "" && i.EKSCluster == "" {
|
||||||
return errors.New("token is needed to deploy")
|
return errors.New("token is needed to deploy")
|
||||||
}
|
}
|
||||||
|
if i.Token != "" && i.EKSCluster != "" {
|
||||||
|
return errors.New("token cannot be used simultaneously with eksCluster")
|
||||||
|
}
|
||||||
|
|
||||||
if i.ServiceAccount == "" {
|
if i.ServiceAccount == "" {
|
||||||
i.ServiceAccount = "helm"
|
i.ServiceAccount = "helm"
|
||||||
@@ -70,6 +77,8 @@ func (i *InitKube) Prepare(cfg Config) error {
|
|||||||
APIServer: i.APIServer,
|
APIServer: i.APIServer,
|
||||||
ServiceAccount: i.ServiceAccount,
|
ServiceAccount: i.ServiceAccount,
|
||||||
Token: i.Token,
|
Token: i.Token,
|
||||||
|
EKSCluster: i.EKSCluster,
|
||||||
|
EKSRoleARN: i.EKSRoleARN,
|
||||||
Namespace: cfg.Namespace,
|
Namespace: cfg.Namespace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package run
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
yaml "gopkg.in/yaml.v2"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -58,59 +57,6 @@ namespace: Cisco
|
|||||||
suite.Equal(want, string(conf))
|
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{
|
|
||||||
Namespace: "marshmallow",
|
|
||||||
}
|
|
||||||
init := InitKube{
|
|
||||||
ConfigFile: configFile.Name(),
|
|
||||||
TemplateFile: "../../assets/kubeconfig.tpl", // the actual kubeconfig template
|
|
||||||
APIServer: "https://kube.cluster/peanut",
|
|
||||||
ServiceAccount: "chef",
|
|
||||||
Token: "eWVhaCB3ZSB0b2tpbic=",
|
|
||||||
Certificate: "d293LCB5b3UgYXJlIHNvIGNvb2wgZm9yIHNtb2tpbmcgd2VlZCDwn5mE",
|
|
||||||
}
|
|
||||||
suite.Require().NoError(init.Prepare(cfg))
|
|
||||||
suite.Require().NoError(init.Execute(cfg))
|
|
||||||
|
|
||||||
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.SkipTLSVerify = true
|
|
||||||
init.Certificate = ""
|
|
||||||
|
|
||||||
suite.Require().NoError(init.Prepare(cfg))
|
|
||||||
suite.Require().NoError(init.Execute(cfg))
|
|
||||||
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() {
|
func (suite *InitKubeTestSuite) TestPrepareParseError() {
|
||||||
templateFile, err := tempfile("kubeconfig********.yml.tpl", `{{ NonexistentFunction }}`)
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", `{{ NonexistentFunction }}`)
|
||||||
defer os.Remove(templateFile.Name())
|
defer os.Remove(templateFile.Name())
|
||||||
@@ -187,6 +133,33 @@ func (suite *InitKubeTestSuite) TestPrepareRequiredConfig() {
|
|||||||
suite.Error(init.Prepare(cfg), "Token should be required.")
|
suite.Error(init.Prepare(cfg), "Token should be required.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *InitKubeTestSuite) TestPrepareEKSConfig() {
|
||||||
|
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{
|
||||||
|
TemplateFile: templateFile.Name(),
|
||||||
|
ConfigFile: configFile.Name(),
|
||||||
|
APIServer: "eks.aws.amazonaws.com",
|
||||||
|
EKSCluster: "it-is-an-eks-parrot",
|
||||||
|
EKSRoleARN: "arn:aws:iam::19691207:role/mrPraline",
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := Config{}
|
||||||
|
|
||||||
|
suite.NoError(init.Prepare(cfg))
|
||||||
|
suite.Equal(init.values.EKSCluster, "it-is-an-eks-parrot")
|
||||||
|
suite.Equal(init.values.EKSRoleARN, "arn:aws:iam::19691207:role/mrPraline")
|
||||||
|
|
||||||
|
init.Token = "cGluaW5nIGZvciB0aGUgZmrDtnJkcw=="
|
||||||
|
suite.EqualError(init.Prepare(cfg), "token cannot be used simultaneously with eksCluster")
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *InitKubeTestSuite) TestPrepareDefaultsServiceAccount() {
|
func (suite *InitKubeTestSuite) TestPrepareDefaultsServiceAccount() {
|
||||||
templateFile, err := tempfile("kubeconfig********.yml.tpl", "hurgity burgity")
|
templateFile, err := tempfile("kubeconfig********.yml.tpl", "hurgity burgity")
|
||||||
defer os.Remove(templateFile.Name())
|
defer os.Remove(templateFile.Name())
|
||||||
|
|||||||
109
internal/run/kubeconfig_test.go
Normal file
109
internal/run/kubeconfig_test.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package run
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KubeconfigTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
configFile *os.File
|
||||||
|
initKube InitKube
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) BeforeTest(_, _ string) {
|
||||||
|
file, err := ioutil.TempFile("", "kubeconfig********.yml")
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
file.Close()
|
||||||
|
suite.configFile = file
|
||||||
|
|
||||||
|
// set up an InitKube with the bare minimum configuration
|
||||||
|
suite.initKube = InitKube{
|
||||||
|
ConfigFile: file.Name(),
|
||||||
|
TemplateFile: "../../assets/kubeconfig.tpl", // the actual kubeconfig template
|
||||||
|
APIServer: "a",
|
||||||
|
Token: "b",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) AfterTest(_, _ string) {
|
||||||
|
if suite.configFile != nil {
|
||||||
|
os.Remove(suite.configFile.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKubeconfigTestSuite(t *testing.T) {
|
||||||
|
suite.Run(t, new(KubeconfigTestSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsNamespace() {
|
||||||
|
cfg := Config{
|
||||||
|
Namespace: "marshmallow",
|
||||||
|
}
|
||||||
|
contents := suite.generateKubeconfig(cfg)
|
||||||
|
suite.Contains(contents, "namespace: marshmallow")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsAPIServer() {
|
||||||
|
suite.initKube.APIServer = "https://kube.cluster/peanut"
|
||||||
|
contents := suite.generateKubeconfig(Config{})
|
||||||
|
suite.Contains(contents, "server: https://kube.cluster/peanut")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsServiceAccount() {
|
||||||
|
suite.initKube.ServiceAccount = "chef"
|
||||||
|
contents := suite.generateKubeconfig(Config{})
|
||||||
|
suite.Contains(contents, "user: chef")
|
||||||
|
suite.Contains(contents, "name: chef")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsToken() {
|
||||||
|
suite.initKube.Token = "eWVhaCB3ZSB0b2tpbic"
|
||||||
|
contents := suite.generateKubeconfig(Config{})
|
||||||
|
suite.Contains(contents, "token: eWVhaCB3ZSB0b2tpbic")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsCertificate() {
|
||||||
|
suite.initKube.Certificate = "d293LCB5b3UgYXJlIHNvIGNvb2wgZm9yIHNtb2tpbmcgd2VlZCDwn5mE"
|
||||||
|
contents := suite.generateKubeconfig(Config{})
|
||||||
|
suite.Contains(contents, "certificate-authority-data: d293LCB5b3UgYXJlIHNvIGNvb2wgZm9yIHNtb2tpbmcgd2VlZCDwn5mE")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsSkipTLSVerify() {
|
||||||
|
suite.initKube.SkipTLSVerify = true
|
||||||
|
contents := suite.generateKubeconfig(Config{})
|
||||||
|
suite.Contains(contents, "insecure-skip-tls-verify: true")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsEKSCluster() {
|
||||||
|
suite.initKube.Token = ""
|
||||||
|
suite.initKube.EKSCluster = "it-is-an-eks-parrot"
|
||||||
|
contents := suite.generateKubeconfig(Config{})
|
||||||
|
suite.Contains(contents, "command: aws-iam-authenticator")
|
||||||
|
suite.Contains(contents, `- "it-is-an-eks-parrot"`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) TestSetsEKSRoleARN() {
|
||||||
|
suite.initKube.Token = ""
|
||||||
|
suite.initKube.EKSCluster = "it-is-an-eks-parrot"
|
||||||
|
suite.initKube.EKSRoleARN = "arn:aws:iam::19691207:role/mrPraline"
|
||||||
|
contents := suite.generateKubeconfig(Config{})
|
||||||
|
suite.Contains(contents, `- "-r"`)
|
||||||
|
suite.Contains(contents, `- "arn:aws:iam::19691207:role/mrPraline"`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KubeconfigTestSuite) generateKubeconfig(cfg Config) string {
|
||||||
|
suite.Require().NoError(suite.initKube.Prepare(cfg))
|
||||||
|
suite.Require().NoError(suite.initKube.Execute(cfg))
|
||||||
|
|
||||||
|
contents, err := ioutil.ReadFile(suite.configFile.Name())
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
conf := map[string]interface{}{}
|
||||||
|
suite.NoError(yaml.UnmarshalStrict(contents, &conf))
|
||||||
|
|
||||||
|
return string(contents)
|
||||||
|
}
|
||||||
@@ -16,8 +16,6 @@ func (l *Lint) Execute(_ Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare gets the Lint ready to execute.
|
// Prepare gets the Lint ready to execute.
|
||||||
// Note: mandatory settings are documented in README.md, and the full list of settings is in docs/lint_settings.yml.
|
|
||||||
// Any additions or deletions here should be reflected there.
|
|
||||||
func (l *Lint) Prepare(cfg Config) error {
|
func (l *Lint) Prepare(cfg Config) error {
|
||||||
if l.Chart == "" {
|
if l.Chart == "" {
|
||||||
return fmt.Errorf("chart is required")
|
return fmt.Errorf("chart is required")
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ func (u *Upgrade) Execute(_ Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare gets the Upgrade ready to execute.
|
// Prepare gets the Upgrade ready to execute.
|
||||||
// Note: mandatory settings are documented in README.md, and the full list of settings is in docs/upgrade_settings.yml.
|
|
||||||
// Any additions or deletions here should be reflected there.
|
|
||||||
func (u *Upgrade) Prepare(cfg Config) error {
|
func (u *Upgrade) Prepare(cfg Config) error {
|
||||||
if u.Chart == "" {
|
if u.Chart == "" {
|
||||||
return fmt.Errorf("chart is required")
|
return fmt.Errorf("chart is required")
|
||||||
|
|||||||
Reference in New Issue
Block a user