Skip to content

Commit

Permalink
Merge pull request #2 from hypnoglow/develop
Browse files Browse the repository at this point in the history
helm s3 command unleashed
  • Loading branch information
hypnoglow authored Oct 3, 2017
2 parents f1b92b9 + 09ae5fc commit 7d4bf1b
Show file tree
Hide file tree
Showing 150 changed files with 21,337 additions and 1,946 deletions.
16 changes: 13 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,18 @@ jobs:
working_directory: /go/src/github.com/hypnoglow/helm-s3
steps:
- checkout
- run: go get -u -v github.com/golang/dep/cmd/dep
- run: dep ensure -v
# - run: go get -u -v github.com/golang/dep/cmd/dep
# - run: dep ensure -v
- run: ./.circleci/testcover.sh
- run: bash <(curl -s https://codecov.io/bash)
- run: go build ./cmd/...
- run: go build -o bin/helms3 ./cmd/helms3
- deploy:
name: goreleaser
command: |
if [ -n "$CIRCLE_TAG" ]; then
curl -sL https://git.io/goreleaser | bash
fi
deployment:
trigger_tag:
tag: /.*/
21 changes: 21 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Contributing to helm s3 plugin

## Development

On regular plugin installation, helm triggers post-install hook
that downloads prebuilt versioned release of the plugin binary and installs it.
To disable this behavior, you need to pass `HELM_S3_PLUGIN_NO_INSTALL_HOOK=true`
to the installer:

$ HELM_S3_PLUGIN_NO_INSTALL_HOOK=true helm plugin install https://github.com/hypnoglow/helm-s3.git
Development mode: not downloading versioned release.
Installed plugin: s3

Next, you may want to ensure if you have all prerequisites to build
the plugin from source:

cd ~/.helm/plugins/helm-s3
make build

If you see no messages - build was successful. Try to run some helm commands
that involve the plugin, or jump straight into plugin development.
9 changes: 5 additions & 4 deletions .github/TODO.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# TODO

- [x] ~~The code is currently super dirty, need to refactor heavily.~~
- [ ] Get rid of Golang dependency. Plugin "install" hook should download
prebuilt **helms3** binary file from github releases.
- [ ] Make `helm s3` command able to upload the charts to the repo. Remember
- [x] ~~Get rid of Golang dependency. Plugin "install" hook should download
prebuilt **helms3** binary file from github releases.~~
- [x] ~~Make `helm s3` command able to upload the charts to the repo. Remember
that helm has no build-in command like `push` or `publish`, so we need to provide
easy way to push charts to the repository.
easy way to push charts to the repository.~~
- [ ] On `helm s3 push` need to check that the file is a valid Helm chart.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
bin/*
tmp
releases

.env
coverage.txt
14 changes: 14 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
builds:
- main: ./cmd/helms3
binary: ./bin/helms3
goos:
- darwin
- linux
goarch:
- amd64

archive:
format: tar.gz
files:
- LICENSE
- plugin.yaml
24 changes: 21 additions & 3 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"

[[constraint]]
name = "gopkg.in/alecthomas/kingpin.v2"
version = "2.2.5"
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
pkg := github.com/hypnoglow/helm-s3

build:
@./sh/build.sh $(CURDIR) $(pkg)
@./sh/build.sh $(CURDIR) $(pkg)

install:
@./sh/install.sh
46 changes: 40 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@

[![CircleCI](https://circleci.com/gh/hypnoglow/helm-s3.svg?style=shield)](https://circleci.com/gh/hypnoglow/helm-s3)
[![License MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
[![GitHub release](https://img.shields.io/github/release/hypnoglow/helm-s3.svg)](https://github.com/hypnoglow/helm-s3/releases)

The Helm plugin that provides s3 protocol support.

This allows you to have private Helm chart repositories hosted on Amazon S3.

## Install

Installation itself is simple as:
The installation itself is simple as:

$ helm plugin install https://github.com/hypnoglow/helm-s3.git

Plugin requires Golang to be installed to build the binary file from source.
It will happen implicitly on plugin installation, nothing needs to be done manually.
You can install a specific release version:

$ helm plugin install https://github.com/hypnoglow/helm-s3.git --version 0.2.0

To use the plugin, you do not need any special dependencies. The installer will
download versioned release with prebuilt binary from [github releases](https://github.com/hypnoglow/helm-s3/releases).
However, if you want to build the plugin from source, or you want to contribute
to the plugin, please see [these instructions](.github/CONTRIBUTING.md).

#### Note on AWS authentication

Expand All @@ -30,11 +37,10 @@ on specific bucket.

## Usage

Let's omit the process of uploading repository index and charts to s3 and assume
For now let's omit the process of uploading repository index and charts to s3 and assume
you already have your repository `index.yaml` file on s3 under path `s3://bucket-name/charts/index.yaml`
and a chart archive `epicservice-0.5.1.tgz` under path `s3://bucket-name/charts/epicservice-0.5.1.tgz`.


Add your repository:

$ helm repo add coolcharts s3://bucket-name/charts
Expand All @@ -52,13 +58,41 @@ Fetching also works:

$ helm fetch s3://bucket-name/charts/epicservice-0.5.1.tgz

### Init & Push

To create a new repository, use **init**:

$ helm s3 init s3://bucket-name/charts

This command generates an empty **index.yaml** and uploads it to the S3 bucket
under `/charts` key.

To push to this repo by it's name, you need to add it first:

$ helm repo add mynewrepo s3://bucket-name/charts

Now you can push your chart to this repo:

$ helm s3 push ./epicservice-0.7.2.tgz mynewrepo

On push, remote repo index is automatically updated. To sync your local index, run:

$ helm repo update

Now your pushed chart is available:

$ helm search mynewrepo
NAME VERSION DESCRIPTION
mynewrepo/epicservice 0.7.2 A Helm chart.

## Uninstall

$ helm plugin remove s3

## Contributing

Contributions are welcome.
Contributions are welcome. Please see [these instructions](.github/CONTRIBUTING.md)
that will help you to develop the plugin.

## License

Expand Down
46 changes: 46 additions & 0 deletions cmd/helms3/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"bytes"
"context"
"fmt"
"log"
"text/template"
"time"

"github.com/hypnoglow/helm-s3/pkg/awss3"
"github.com/hypnoglow/helm-s3/pkg/awsutil"
)

const (
indexTemplate = `apiVersion: v1
entries: {}
generated: {{ .Date }}`
)

func runInit(uri string) {
tpl := template.New("index")
tpl, err := tpl.Parse(indexTemplate)
if err != nil {
log.Fatalf("failed to parse index.yaml template: %s", err)
}

buf := &bytes.Buffer{}
if err := tpl.Execute(buf, map[string]interface{}{"Date": time.Now().Format(time.RFC3339Nano)}); err != nil {
log.Fatalf("failed to execute index.yaml temlate: %s", err)
}

awsConfig, err := awsutil.Config()
if err != nil {
log.Fatalf("failed to get aws config: %s", err)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()

if _, err := awss3.Upload(ctx, uri+"/index.yaml", buf, awsConfig); err != nil {
log.Fatalf("failed to upload chart to s3: %s", err)
}

fmt.Printf("Initialized empty repository at %s\n", uri)
}
67 changes: 34 additions & 33 deletions cmd/helms3/main.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,57 @@
package main

import (
"context"
"fmt"
"log"
"os"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"gopkg.in/alecthomas/kingpin.v2"
)

"github.com/hypnoglow/helm-s3/pkg/awss3"
"github.com/hypnoglow/helm-s3/pkg/dotaws"
var (
version = "master"
)

const (
envAwsAccessKeyID = "AWS_ACCESS_KEY_ID"
envAwsSecretAccessKey = "AWS_SECRET_ACCESS_KEY"
envAWsDefaultRegion = "AWS_DEFAULT_REGION"
actionPush = "push"
actionInit = "init"

defaultTimeout = time.Second * 5
)

func main() {
if len(os.Args) < 5 {
fmt.Print("The direct use of \"helm s3\" command is currently not supported.")
if len(os.Args) == 5 {
runProxy(os.Args[4])
return
}

if err := dotaws.ParseCredentials(); err != nil {
log.Fatalf("failed to parse aws credentials file: %s", err)
}
if err := dotaws.ParseConfig(); err != nil {
log.Fatalf("failed to parse aws config file: %s", err)
cli := kingpin.New("helm s3", "")
cli.Version(version)
initCmd := cli.Command(actionInit, "Initialize empty repository on AWS S3.")
initURI := initCmd.Arg("uri", "URI of repository, e.g. s3://awesome-bucket/charts").
Required().
String()
pushCmd := cli.Command(actionPush, "Push chart to repository.")
pushChartPath := pushCmd.Arg("chartPath", "Path to a chart, e.g. ./epicservice-0.5.1.tgz").
Required().
String()
pushTargetRepository := pushCmd.Arg("repo", "Target repository to runPush").
Required().
String()
action := kingpin.MustParse(cli.Parse(os.Args[1:]))
if action == "" {
cli.Usage(os.Args[1:])
os.Exit(0)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
uri := os.Args[4]
awsConfig := &aws.Config{
Credentials: credentials.NewStaticCredentials(
os.Getenv(envAwsAccessKeyID),
os.Getenv(envAwsSecretAccessKey),
"",
),
Region: aws.String(os.Getenv(envAWsDefaultRegion)),
}
switch action {

b, err := awss3.FetchRaw(ctx, uri, awsConfig)
if err != nil {
log.Fatalf("failed to fetch from s3: %s", err)
}
case actionInit:
runInit(*initURI)
return

case actionPush:
runPush(*pushChartPath, *pushTargetRepository)
return

fmt.Print(string(b))
}
}
27 changes: 27 additions & 0 deletions cmd/helms3/proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"context"
"fmt"
"log"

"github.com/hypnoglow/helm-s3/pkg/awss3"
"github.com/hypnoglow/helm-s3/pkg/awsutil"
)

func runProxy(uri string) {
awsConfig, err := awsutil.Config()
if err != nil {
log.Fatalf("failed to get aws config: %s", err)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()

b, err := awss3.FetchRaw(ctx, uri, awsConfig)
if err != nil {
log.Fatalf("failed to fetch from s3: %s", err)
}

fmt.Print(string(b))
}
Loading

0 comments on commit 7d4bf1b

Please sign in to comment.