Skip to content
This repository has been archived by the owner on Oct 27, 2023. It is now read-only.

Commit

Permalink
Feature/support repos from helm settings (#2)
Browse files Browse the repository at this point in the history
* support repos added through CLI

* Fix readme
  • Loading branch information
miguel-santiago authored Jan 21, 2019
1 parent 88500cd commit 6dfccc5
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ endif
@dep ensure -v -vendor-only

.PHONY: dist
dist: clean
dist: clean build-cross
dist:
( \
cd _dist && \
Expand Down
85 changes: 69 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Based on the version in `plugin.yaml`, release binary will be downloaded from Gi

```
$ helm plugin install https://github.com/belitre/helm-push-artifactory-plugin
Downloading and installing helm-push-artifactory v0.1.0 ...
https://github.com/belitre/helm-push-artifactory-plugin/releases/download/v0.1.0/helm-push-artifactory_v0.1.0_darwin_amd64.tar.gz
Downloading and installing helm-push-artifactory v0.2.0 ...
https://github.com/belitre/helm-push-artifactory-plugin/releases/download/v0.2.0/helm-push-artifactory_v0.2.0_darwin_amd64.tar.gz
Installed plugin: push-artifactory
```

Expand All @@ -23,27 +23,80 @@ helm plugin remove push-artifactory
Removed plugin: push-artifactory
```

## Local and virtual repositories

Artifactory has two types of repositories: local and virtual. Local repositories are the ones where you push the charts, but to get a chart you'll need to use a virtual repository!

__This plugin works with local repositories__, you can add them through the Helm CLI like a virtual repository and use it later instead of the URL. But remember: __you won't be able to get charts from a local repository__

Example:

* We can add our local repository with helm CLI:

```bash
$ helm repo add --username myuser --password mypass my-local-repo https://artifactoryhost/my-local-repo
"my-local-repo" has been added to your repositories
```

* We can use this repository later to push charts:

```bash
$ helm push-artifactory mychart-0.3.2.tgz my-local-repo
Pushing mychart-0.3.2.tgz to https://artifactoryhost/my-local-repo/mychart/mychart-0.3.2.tgz...
Done.
Reindex helm repository my-local-repo...
Reindex of helm repo my-local-repo was scheduled to run.
```

* __We can't get the helm chart from a local repo:__
```bash
$ helm fetch my-local-repo/mychart
Error: Get local://mychart/mychart-0.3.2.tgz: unsupported protocol scheme "local"
```
* We can add the virtual repo and get the chart:
```bash
$ helm repo add --username myuser --password mypass my-virtual-repo https://artifactoryhost/my-virtual-repo
"my-virtual-repo" has been added to your repositories
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "my-local-repo" chart repository
...Successfully got an update from the "my-virtual-repo" chart repository
Update Complete. ⎈ Happy Helming!⎈
$ helm fetch my-virtual-repo/mychart
$ ls
mychart-0.3.2.tgz
```
## Usage
__This plugin doesn't use repositories added through Helm CLI, in Artifactory those are virtual repositories. To push a chart we need to use a local repository URL__
Example
```
Example using URL:
```bash
$ helm push-artifactory /my/chart/folder https://my-artifactory/my-local-repo --username username --password password
```
For all available plugin options, please run
Example using helm repo added through CLI:
```bash
$ helm push-artifactory /my/chart/folder my-local-repo
```
For all available plugin options, please run:
```bash
$ helm push-artifactory --help
```
### Pushing a directory
Point to a directory containing a valid `Chart.yaml` and the chart will be packaged and uploaded:
```
```bash
$ cat mychart/Chart.yaml
name: mychart
version: 0.3.2
```
```
```bash
$ helm push-artifactory mychart/ https://my-artifactory/my-local-repo
Pushing mychart-0.3.2.tgz to https://my-artifactory/my-local-repo/mychart/mychart-0.3.2.tgz...
Done.
Expand All @@ -55,7 +108,7 @@ Reindex of helm repo my-local-repo was scheduled to run.
The `--version` flag can be provided, which will push the package with a custom version.
Here is an example using the last git commit id as the version:
```
```bash
$ helm push-artifactory mychart/ --version="$(git log -1 --pretty=format:%h)" https://my-artifactory/my-local-repo
Pushing mychart-5abbbf28.tgz to https://my-artifactory/my-local-repo/mychart/mychart-5abbbf28.tgz...
Done.
Expand All @@ -65,8 +118,8 @@ Reindex of helm repo my-local-repo was scheduled to run.
### Push .tgz package
This workflow does not require the use of `helm package`, but pushing .tgz is still supported:
```
$ helm push mychart-0.3.2.tgz https://my-artifactory/my-local-repo
```bash
$ helm push-artifactory mychart-0.3.2.tgz https://my-artifactory/my-local-repo
Pushing mychart-0.3.2.tgz to https://my-artifactory/my-local-repo/mychart/mychart-0.3.2.tgz...
Done.
Reindex helm repository my-local-repo...
Expand All @@ -75,7 +128,7 @@ Reindex of helm repo my-local-repo was scheduled to run.
### Push with path
You can set a path to push your chart in your Artifactory local repository:
```
```bash
$ helm push-artifactory mychart/ https://my-artifactory/my-local-repo --path organization
Pushing mychart-0.3.2.tgz to https://my-artifactory/my-local-repo/organization/mychart/mychart-0.3.2.tgz...
Done.
Expand All @@ -85,7 +138,7 @@ Reindex of helm repo my-local-repo was scheduled to run.
### Skip repository reindex
You can skip triggering the repository reindex:
```
```bash
$ helm push-artifactory mychart/ https://my-artifactory/my-local-repo --skip-reindex
Pushing mychart-0.3.2.tgz to https://my-artifactory/my-local-repo/mychart/mychart-0.3.2.tgz...
Done.
Expand All @@ -96,14 +149,14 @@ Done.
__The plugin will not use the auth info located in `~/.helm/repository/repositories.yaml` in order to authenticate.__
You can provide username and password through commmand line with `--username username --password password` or use the following environment variables for basic auth on push operations:
```
```bash
$ export HELM_REPO_USERNAME="myuser"
$ export HELM_REPO_PASSWORD="mypass"
```
### Access Token
You can provide an access token through command line with `--access-token my-token` or use the following env var:
```
```bash
$ export HELM_REPO_ACCESS_TOKEN="<token>"
```
Expand All @@ -116,7 +169,7 @@ If a username is supplied with an access token, the plugin will use basic authen
### Api Key
You can provide an api key through command line with `--api-key my-key` or use the following env var:
```
```bash
$ export HELM_REPO_API_KEY="<api-key>"
```
Expand Down
38 changes: 35 additions & 3 deletions cmd/push/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"net/url"
"os"
"regexp"
"strconv"
"strings"

Expand Down Expand Up @@ -44,6 +45,7 @@ Examples:
$ helm push-artifactory mychart-0.1.0.tgz https://artifactory/repo # push mychart-0.1.0.tgz from "helm package"
$ helm push-artifactory . https://artifactory/repo # package and push chart directory
$ helm push-artifactory . --version="7c4d121" https://artifactory/repo # override version in Chart.yaml
$ helm push-artifactory mychart-0.1.0.tgz my-helm-repo # push mychart-0.1.0.tgz to a "my-helm-repo" repository
`
)

Expand Down Expand Up @@ -119,13 +121,24 @@ func (p *pushCmd) setFieldsFromEnv() {
}

func (p *pushCmd) push() error {
chart, err := helm.GetChartByName(p.chartName)
var repo *helm.Repo
var err error

// If the argument looks like a URL, just create a temp repo object
// instead of looking for the entry in the local repository list
if regexp.MustCompile(`^https?://`).MatchString(p.repository) {
// Check valid URL
_, err = url.ParseRequestURI(p.repository)
} else {
repo, err = helm.GetRepoByName(p.repository)
}

if err != nil {
return err
}

// Check valid URL
if _, err = url.ParseRequestURI(p.repository); err != nil {
chart, err := helm.GetChartByName(p.chartName)
if err != nil {
return err
}

Expand All @@ -134,6 +147,25 @@ func (p *pushCmd) push() error {
chart.SetVersion(p.chartVersion)
}

if repo != nil {
p.repository = repo.URL
if p.username == "" {
p.username = repo.Username
}
if p.password == "" {
p.password = repo.Password
}
if p.caFile == "" {
p.caFile = repo.CAFile
}
if p.certFile == "" {
p.certFile = repo.CertFile
}
if p.keyFile == "" {
p.keyFile = repo.KeyFile
}
}

client, err := artifactory.NewClient(
artifactory.URL(p.repository),
artifactory.Path(p.path),
Expand Down
70 changes: 65 additions & 5 deletions cmd/push/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ package main
import (
"crypto/rand"
"crypto/tls"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/stretchr/testify/assert"

"k8s.io/helm/pkg/getter"
helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/tlsutil"
)

Expand Down Expand Up @@ -42,34 +46,66 @@ func TestPushCmd(t *testing.T) {
}))
defer ts.Close()

// Create new Helm home w/ test repo
tmp, err := ioutil.TempDir("", "helm-push-test")
if err != nil {
t.Error("unexpected error creating temp test dir", err)
}
defer os.RemoveAll(tmp)

home := helmpath.Home(tmp)
f := repo.NewRepoFile()

entry := repo.Entry{}
entry.Name = "helm-push-test"
entry.URL = ts.URL

_, err = repo.NewChartRepository(&entry, getter.All(settings))
if err != nil {
t.Error("unexpected error created test repository", err)
}

f.Update(&entry)
os.MkdirAll(home.Repository(), 0777)
f.WriteFile(home.RepositoryFile(), 0644)

os.Setenv("HELM_HOME", home.String())
os.Setenv("HELM_REPO_USERNAME", "myuser")
os.Setenv("HELM_REPO_PASSWORD", "mypass")

// Not enough args
args := []string{}
cmd := newPushCmd(args)
err := cmd.RunE(cmd, args)
err = cmd.RunE(cmd, args)
if err == nil {
t.Error("expecting error with missing args, instead got nil")
}

// Bad chart path
args = []string{"/this/this/not/a/chart", ts.URL}
args = []string{"/this/this/not/a/chart", "helm-push-test"}
cmd = newPushCmd(args)
err = cmd.RunE(cmd, args)
if err == nil {
t.Error("expecting error with bad chart path, instead got nil")
}

// Bad repo URL
// Bad repo name
args = []string{testTarballPath, "wkerjbnkwejrnkj"}
cmd = newPushCmd(args)
err = cmd.RunE(cmd, args)
if err == nil {
t.Error("expecting error with bad repo URL, instead got nil")
t.Error("expecting error with bad repo name, instead got nil")
}

// Happy path
args = []string{testTarballPath, "helm-push-test"}
cmd = newPushCmd(args)
err = cmd.RunE(cmd, args)
if err != nil {
t.Error("unexpecting error uploading tarball", err)
}

// Happy path by repo URL
args = []string{testTarballPath, ts.URL}
cmd = newPushCmd(args)
err = cmd.RunE(cmd, args)
Expand Down Expand Up @@ -145,11 +181,35 @@ func TestPushCmdWithTlsEnabledServer(t *testing.T) {
ts.StartTLS()
defer ts.Close()

// Create new Helm home w/ test repo
tmp, err := ioutil.TempDir("", "helm-push-test")
if err != nil {
t.Error("unexpected error creating temp test dir", err)
}
defer os.RemoveAll(tmp)

home := helmpath.Home(tmp)
f := repo.NewRepoFile()

entry := repo.Entry{}
entry.Name = "helm-push-test"
entry.URL = ts.URL

_, err = repo.NewChartRepository(&entry, getter.All(settings))
if err != nil {
t.Error("unexpected error created test repository", err)
}

f.Update(&entry)
os.MkdirAll(home.Repository(), 0777)
f.WriteFile(home.RepositoryFile(), 0644)

os.Setenv("HELM_HOME", home.String())
os.Setenv("HELM_REPO_USERNAME", "myuser")
os.Setenv("HELM_REPO_PASSWORD", "mypass")

//no certificate options
args := []string{testTarballPath, ts.URL}
args := []string{testTarballPath, "helm-push-test"}
cmd := newPushCmd(args)
err = cmd.RunE(cmd, args)
if err == nil {
Expand Down
2 changes: 1 addition & 1 deletion plugin.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "push-artifactory"
version: "0.1.0"
version: "0.2.0"
usage: "Please see https://github.com/belitre/helm-push-artifactory-plugin for usage"
description: "Push helm charts to artifactory"
ignoreFlags: false
Expand Down

0 comments on commit 6dfccc5

Please sign in to comment.