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

Enhancement issue#60 #61

Merged
merged 9 commits into from
Mar 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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