Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

Commit

Permalink
Merge pull request #61 from MChorfa/enhancement-issue#60
Browse files Browse the repository at this point in the history
Enhancement issue#60
  • Loading branch information
vdice authored Mar 24, 2020
2 parents d9b6603 + d5cce77 commit 99a54aa
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 4 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,24 @@ appropriate helm command based on which action it is included within: `install`,

### Install or Upgrade

```
```shell
porter mixin install helm
```

### Configure mixin repositories

```yaml
- helm:
repositories:
stable:
url: "https://kubernetes-charts.storage.googleapis.com"
cafile: "path/to/cafile"
certfile: "path/to/certfile"
keyfile: "path/to/keyfile"
username: "username"
password: "password"
```
### Mixin Syntax
Install
Expand Down
82 changes: 82 additions & 0 deletions pkg/helm/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package helm

import (
"fmt"
"strings"

"get.porter.sh/porter/pkg/exec/builder"
yaml "gopkg.in/yaml.v2"
)

// These values may be referenced elsewhere (init.go), hence consts
Expand Down Expand Up @@ -29,8 +33,86 @@ const getKubectl string = `RUN apt-get update && \
mv kubectl /usr/local/bin && \
chmod a+x /usr/local/bin/kubectl`

// BuildInput represents stdin passed to the mixin for the build command.
type BuildInput struct {
Config MixinConfig
}

// MixinConfig represents configuration that can be set on the helm mixin in porter.yaml
// mixins:
// - helm:
// repositories:
// stable:
// url: "https://kubernetes-charts.storage.googleapis.com"
// cafile: "path/to/cafile"
// certfile: "path/to/certfile"
// keyfile: "path/to/keyfile"
// username: "username"
// password: "password"
type MixinConfig struct {
Repositories map[string]Repository
}

type Repository struct {
URL string `yaml:"url,omitempty"`
Cafile string `yaml:"cafile,omitempty"`
Certfile string `yaml:"certfile,omitempty"`
Keyfile string `yaml:"keyfile,omitempty"`
Username string `yaml:"username,omitempty"`
Password string `yaml:"password,omitempty"`
}

func (m *Mixin) Build() error {

// Create new Builder.
var input BuildInput
err := builder.LoadAction(m.Context, "", func(contents []byte) (interface{}, error) {
err := yaml.Unmarshal(contents, &input)
return &input, err
})
if err != nil {
return err
}

// Define helm
fmt.Fprintf(m.Out, getHelm, helmDownloadURL)

// Define kubectl
fmt.Fprintf(m.Out, getKubectl, kubeVersion)

// Go through repositories
for name, repo := range input.Config.Repositories {

commandValue, err := GetAddRepositoryCommand(name, repo.URL, repo.Cafile, repo.Certfile, repo.Keyfile, repo.Username, repo.Password)
if err != nil && m.Debug {
fmt.Fprintf(m.Err, "DEBUG: addition of repository failed: %s\n", err.Error())
} else {
fmt.Fprintf(m.Out, strings.Join(commandValue, " "))
}
}

return nil
}

func GetAddRepositoryCommand(name, url, cafile, certfile, keyfile, username, password string) (commandValue []string, err error) {

var commandBuilder []string

if url == "" {
return commandBuilder, fmt.Errorf("repository url must be supplied")
}

commandBuilder = append(commandBuilder, "\nRUN", "helm", "repo", "add", name, url)

if certfile != "" && keyfile != "" {
commandBuilder = append(commandBuilder, "--cert-file", certfile, "--key-file", keyfile)
}
if cafile != "" {
commandBuilder = append(commandBuilder, "--ca-file", cafile)
}
if username != "" && password != "" {
commandBuilder = append(commandBuilder, "--username", username, "--password", password)
}

return commandBuilder, nil
}
36 changes: 33 additions & 3 deletions pkg/helm/build_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package helm

import (
"bytes"
"io/ioutil"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -13,7 +15,7 @@ func TestMixin_Build(t *testing.T) {
err := m.Build()
require.NoError(t, err)

wantOutput := `RUN apt-get update && \
buildOutput := `RUN apt-get update && \
apt-get install -y curl && \
curl -o helm.tgz https://get.helm.sh/helm-v2.15.2-linux-amd64.tar.gz && \
tar -xzf helm.tgz && \
Expand All @@ -26,6 +28,34 @@ RUN apt-get update && \
mv kubectl /usr/local/bin && \
chmod a+x /usr/local/bin/kubectl`

gotOutput := m.TestContext.GetOutput()
assert.Equal(t, wantOutput, gotOutput)
t.Run("build with a valid config", func(t *testing.T) {
b, err := ioutil.ReadFile("testdata/build-input-with-valid-config.yaml")
require.NoError(t, err)

m := NewTestMixin(t)
m.Debug = false
m.In = bytes.NewReader(b)

err = m.Build()
require.NoError(t, err, "build failed")

wantOutput := buildOutput + "\nRUN helm repo add stable kubernetes-charts --username username --password password"

gotOutput := m.TestContext.GetOutput()
assert.Equal(t, wantOutput, gotOutput)
})

t.Run("build with invalid config", func(t *testing.T) {
b, err := ioutil.ReadFile("testdata/build-input-with-invalid-config.yaml")
require.NoError(t, err)

m := NewTestMixin(t)
m.Debug = false
m.In = bytes.NewReader(b)

err = m.Build()
require.NoError(t, err, "build failed")
gotOutput := m.TestContext.GetOutput()
assert.Equal(t, buildOutput, gotOutput)
})
}
9 changes: 9 additions & 0 deletions pkg/helm/testdata/build-input-with-invalid-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config:
repositories:
stable:
install:
- helm:
description: "Install MySQL"
name: porter-ci-mysql
chart: stable/mysql
version: 0.10.2
12 changes: 12 additions & 0 deletions pkg/helm/testdata/build-input-with-valid-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
config:
repositories:
stable:
url: "kubernetes-charts"
username: "username"
password: "password"
install:
- helm:
description: "Install MySQL"
name: porter-ci-mysql
chart: stable/mysql
version: 0.10.2

0 comments on commit 99a54aa

Please sign in to comment.