Skip to content

Commit

Permalink
Tiller proxy basic functionality (#357)
Browse files Browse the repository at this point in the history
* Vendor update

* Docs, make tasks and dockerfiles

* Copy chart logic from helm-crd

* Proxy logic to communicate with tiller

* Proxy HTTP wrapper

* Main function

* Minor review

* CMD update

* Add auth functionality

* Chart utils update

* Update proxy pkg

* Review

* Fix typo
  • Loading branch information
andresmgot authored Jun 21, 2018
1 parent fa5ad1f commit 2c70d7f
Show file tree
Hide file tree
Showing 421 changed files with 67,197 additions and 22,178 deletions.
161 changes: 99 additions & 62 deletions Gopkg.lock

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
name = "github.com/ghodss/yaml"
version = "1.0.0"

[[constraint]]
name = "github.com/go-ini/ini"
version = "1.32.0"

[[constraint]]
branch = "master"
name = "github.com/gosuri/uitable"
Expand All @@ -25,6 +21,10 @@
name = "github.com/ksonnet/kubecfg"
revision = "8634737e0b22b01bb93ffeb09a195d0a6d71a6e5"

[[constraint]]
name = "google.golang.org/grpc"
version = "1.7.2"

[[constraint]]
name = "k8s.io/client-go"
version = "5.0.1"
Expand All @@ -39,6 +39,10 @@
name = "k8s.io/api"
revision = "6c6dac0277229b9e9578c5ca3f74a4345d35cdc2"

[[constraint]]
name = "k8s.io/helm"
version = "2.9.1"

[[override]]
name = "github.com/Azure/go-autorest"
revision = "58f6f26e200fa5dfb40c9cd1c83f3e2c860d779d"
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ kubeapps/%:
kubeapps/dashboard:
docker build -t kubeapps/dashboard:$(VERSION) -f dashboard/Dockerfile dashboard/

tiller-proxy:
docker build -t kubeapps/tiller-proxy -f ./cmd/tiller-proxy/Dockerfile .

test: $(EMBEDDED_STATIC)
$(GO) test $(GO_PACKAGES)

Expand Down
4 changes: 3 additions & 1 deletion cmd/kubeapps/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"

yamlUtils "github.com/kubeapps/kubeapps/pkg/yaml"
)

var downCmd = &cobra.Command{
Expand Down Expand Up @@ -65,7 +67,7 @@ var downCmd = &cobra.Command{
if err != nil {
return fmt.Errorf("can't read kubeapps manifest: %v", err)
}
objs, err := parseObjects(manifest)
objs, err := yamlUtils.ParseObjects(manifest)
if err != nil {
return fmt.Errorf("can't parse kubeapps manifest: %v", err)
}
Expand Down
34 changes: 0 additions & 34 deletions cmd/kubeapps/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,18 @@ limitations under the License.
package kubeapps

import (
"bufio"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"

"github.com/ksonnet/kubecfg/utils"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -92,34 +86,6 @@ func logLevel(verbosity string) logrus.Level {
}
}

func parseObjects(manifest string) ([]*unstructured.Unstructured, error) {
r := strings.NewReader(manifest)
decoder := yaml.NewYAMLReader(bufio.NewReader(r))
ret := []runtime.Object{}
for {
bytes, err := decoder.Read()
if err == io.EOF {
break
} else if err != nil {
return nil, err
}
if len(bytes) == 0 {
continue
}
jsondata, err := yaml.ToJSON(bytes)
if err != nil {
return nil, err
}
obj, _, err := unstructured.UnstructuredJSONScheme.Decode(jsondata, nil, nil)
if err != nil {
return nil, err
}
ret = append(ret, obj)
}

return utils.FlattenToV1(ret), nil
}

func restClientPool() (dynamic.ClientPool, discovery.DiscoveryInterface, error) {
conf, err := buildOutOfClusterConfig()
if err != nil {
Expand Down
39 changes: 0 additions & 39 deletions cmd/kubeapps/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,45 +22,6 @@ import (
"testing"
)

func TestParseObjectsSuccess(t *testing.T) {
m1 := `apiVersion: v1
kind: Namespace
metadata:
annotations: {}
labels:
name: kubeless
name: kubeless`
rs, err := parseObjects(m1)
if err != nil {
t.Error(err)
}
if len(rs) != 1 {
t.Errorf("Expected 1 yaml element, got %v", len(rs))
}

// validate some fields of the parsed object
if rs[0].GetAPIVersion() != "v1" {
t.Errorf("Expected apiversion=v1, go %s", rs[0].GetAPIVersion())
}
if rs[0].GetKind() != "Namespace" {
t.Errorf("Expected kind = Namespace, go %s", rs[0].GetKind())
}
}

func TestParseObjectFailure(t *testing.T) {
m2 := `apiVersion: v1
kind: Namespace
metadata:
annotations: {}
labels:
name: kubeless
name: kubeless`
_, err := parseObjects(m2)
if err == nil {
t.Error("Expected parse fail, got success")
}
}

func TestGenerateEncodedRandomPassword(t *testing.T) {
got, err := generateEncodedRandomPassword(12)
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions cmd/kubeapps/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/gosuri/uitable"
"github.com/ksonnet/kubecfg/pkg/kubecfg"
"github.com/ksonnet/kubecfg/utils"
"github.com/kubeapps/kubeapps/pkg/gke"
"github.com/spf13/cobra"
"k8s.io/api/apps/v1beta1"
"k8s.io/api/core/v1"
Expand All @@ -40,6 +39,9 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes"

"github.com/kubeapps/kubeapps/pkg/gke"
yamlUtils "github.com/kubeapps/kubeapps/pkg/yaml"
)

const (
Expand Down Expand Up @@ -113,7 +115,7 @@ List of components that kubeapps up installs:
return fmt.Errorf("can't read kubeapps manifest: %v", err)
}

objs, err := parseObjects(manifest)
objs, err := yamlUtils.ParseObjects(manifest)
if err != nil {
return fmt.Errorf("can't parse kubeapps manifest: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions cmd/tiller-proxy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
proxy-static
9 changes: 9 additions & 0 deletions cmd/tiller-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM quay.io/deis/go-dev:v1.8.2 as builder
COPY . /go/src/github.com/kubeapps/kubeapps
WORKDIR /go/src/github.com/kubeapps/kubeapps
RUN CGO_ENABLED=0 go build -a -installsuffix cgo ./cmd/tiller-proxy

FROM scratch
COPY --from=builder /go/src/github.com/kubeapps/kubeapps/tiller-proxy /proxy
EXPOSE 8080
CMD ["/proxy"]
4 changes: 4 additions & 0 deletions cmd/tiller-proxy/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM alpine:3.6
RUN apk --no-cache add ca-certificates
COPY ./proxy-static /proxy
CMD ["/proxy"]
44 changes: 44 additions & 0 deletions cmd/tiller-proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Tiller Proxy

This proxy is a service for Kubeapps that connects the Dashboard with Tiller. The goal of this Proxy is to provide a secure proxy for authenticated users to deploy, upgrade and delete charts in different namespaces.

Part of the logic of this tool has been extracted from [helm-CRD](https://github.com/bitnami-labs/helm-crd). That tool has been deprecated in Kubeapps to avoid having to synchronize the state of a release in two different places (Tiller and the CRD object).

The client should provide the header `Authorization: Bearer TOKEN` being TOKEN the Kubernetes API Token in order to perform any action.

# Configuration

It is possible to configure this proxy with the following flags:

```
--debug enable verbose output
--home string location of your Helm config. Overrides $HELM_HOME (default "/Users/andresmartinez/.helm")
--host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system")
```

# Routes

This proxy provides 6 different routes:

- `GET` `/v1/releases`: List all the releases of the Tiller
- `GET` `/namespaces/{namespace}/releases`: List all the releases within a namespace
- `POST` `/namespaces/{namespace}/releases`: Create a new release
- `GET` `/namespaces/{namespace}/releases/{release}`: Get release info
- `PUT` `/namespaces/{namespace}/releases/{release}`: Update release info
- `DELETE` `/namespaces/{namespace}/releases/{release}`: Delete a release

# Enabling authorization

By default, authorization for any request is enabled (it can be disabled using the flag --disable-auth). If enabled, the client should have permissions to:

- "Read" access to all the release resources in a release when doing a HTTP GET over a specific release.
- "Create" access to all the release resources in a release when doing a when doing an HTTP POST.
- "Create", "Update" and "Delete" permissions to all the release resources when doing an HTTP PUT to upgrade a release.
- "Delete" permissions to all the release resources when doing an HTTP PUT.

Note that the user only needs a valid token in order to list releases.

Right now, the only supported method for authentication is using a bearer token.
Loading

0 comments on commit 2c70d7f

Please sign in to comment.