-
Notifications
You must be signed in to change notification settings - Fork 705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tiller proxy basic functionality #357
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mostly LGTM, nice work.
Now that this is in this repo, there may be certain helpers we want to share with other services (e.g. chart-repo has helpers to deal with repo URLs and appending tarball URLs, downloading tarballs, etc.)
In addition to that, we should probably start putting packages in pkg
directory and leave the cmd
directory for main packages that import packages from pkg
.
These are globally-scoped things that I don't want to scope-creep into this issue, so I'm okay with merging this without doing all that, but it would be good to tackle this at some point (or ideally at least some of it now before this gets merged).
@@ -0,0 +1,4 @@ | |||
FROM alpine:3.6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we not run the binary directly, or with telepresence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true, I'm just not that used to telepresence :)
cmd/tiller-proxy/main.go
Outdated
|
||
var ( | ||
settings environment.EnvSettings | ||
p *proxy.Proxy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is a global var, can we call it proxy
to make it more obvious what it is?
cmd/tiller-proxy/main.go
Outdated
|
||
config, err := rest.InClusterConfig() | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably use log.Fatalf or similar instead of panic
.
cmd/tiller-proxy/proxy/proxy.go
Outdated
|
||
// GetRelease returns the info of a release | ||
func (p *Proxy) GetRelease(name, namespace string) (*release.Release, error) { | ||
lock(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is read-only, do we need the lock? I think we only care about e.g. deleting a release whilst it's still being created?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not critical but it's something nice to have. We could be returning the wrong version or a missing release.
cmd/tiller-proxy/proxy/proxy_test.go
Outdated
return &chart.Chart{}, nil | ||
} | ||
|
||
func prepareTestProxy(hrs []helmRelease, existingTillerReleases []AppOverview) *Proxy { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would name this newTestProxy
or newFakeProxy
- prepare
doesn't sound like something that returns a *Proxy
to me.
I agree with that, I just followed the existing pattern but it's true. I will move at least the current extra packages to the |
Yeah that's a side effect of when we merged together the different repos, we didn't also move packages to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move the packages from pkg/utils/proxy|chart to just pkg/proxy|chart?
Otherwise LGTM
@prydonius I have updated this PR to include the authorization feature (creating a new PR would be confusing since I needed to reorder the code of this PR). From the last bunch of commits the interesting ones for review are 6d2dc61 which contains all the auth related code and |
cmd/tiller-proxy/README.md
Outdated
|
||
# Enabling authorization | ||
|
||
It is possible to enable authorization for helm releases setting the env var `ENABLE_AUTH`. If enabled, the client should have permissions to: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps ENABLE_RBAC
is more clear? Also, IMO this should be enabled by default. I also thing this should be a command line flag rather than an env var.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I planned to do that the default when doing kubeapps up
but it's true, a flag will be better. Also this will work (in theory) with any authorization system not just RBAC (e.g. ABAC): https://kubernetes.io/docs/reference/access-authn-authz/authorization/#authorization-modules
cmd/tiller-proxy/README.md
Outdated
@@ -35,3 +29,14 @@ This proxy provides 6 different routes: | |||
- `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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a caveat that we only support bearer token auth and not other methods atm.
cmd/tiller-proxy/handler.go
Outdated
// WithParams can be used to wrap handlers to take an extra arg for path params | ||
type WithParams func(http.ResponseWriter, *http.Request, Params) | ||
// WithAuth can be used to wrap handlers to take an extra arg for path params | ||
type WithAuth func(http.ResponseWriter, *http.Request, Params, *auth.UserAuth) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO a more clean and modular way to implement this is to write middleware for Negroni and store the auth in the request context. The current approach ties together the auth and params. It's possible that WithParams could also be implemented as a middleware, but that's out of scope.
This is the middleware from Monocular: https://github.com/kubernetes-helm/monocular/blob/master/src/api/middleware/authgate.go, and this is an example of who it can be wrapped in a route: https://github.com/kubernetes-helm/monocular/blob/master/src/api/main.go#L102. The request context will need a key that can be used to read/set the auth data (https://github.com/kubernetes-helm/monocular/blob/master/src/api/models/user.go#L27), we may need a new package to share this.
cmd/tiller-proxy/handler.go
Outdated
return | ||
} | ||
action := "create" | ||
if req.Method == "PUT" && params["releaseName"] != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use a different handler for PUT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it has just a couple of lines different but I guess it's better to have different handlers for readability
cmd/tiller-proxy/handler.go
Outdated
proxy.LogReleaseStatus(rel.Name) | ||
status, err := proxy.GetReleaseStatus(rel.Name) | ||
if err != nil { | ||
log.Printf("Unable to fecth release status of %s: %v", rel.Name, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/fecth/fetch
pkg/auth/auth.go
Outdated
Namespace string | ||
} | ||
|
||
// NewAuth creates a auth agent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/a/an
pkg/auth/auth.go
Outdated
if err != nil { | ||
return err | ||
} | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just have the default be err := u.isAllowed(action, resources
and remove all other cases apart from upgrade
. The SelfSubjectAccessReview will fail for unknown verbs anyway.
if !strings.Contains(err.Error(), "Unauthorized to create v1/pods in the bar namespace") { | ||
t.Errorf("Unexpected error: %v", err) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any way to test a successful request?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find a way of doing so without modify the functional code in a weird way. For being able to return a "success" we need to add to the fake
client a SelfSubjectAccessReviews
object but since the functional code does a Create
(because a Get
doesn't make sense in the real scenario) it returns an error "already exists".
@andresmgot added some comments, some of which are hidden as "outdated" (although they aren't really) |
@prydonius reviewed/replied |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
cmd/tiller-proxy/handler.go
Outdated
func logStatus(name string) { | ||
status, err := proxy.GetReleaseStatus(name) | ||
if err != nil { | ||
log.Printf("Unable to fecth release status of %s: %v", name, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/fecth/fetch
Closes #351
Closes #352
Closes #353
This PR implements the basic functionality for the Tiller proxy discussed in #337. The proxy currently redirect requests to Tiller to list, create, get, update and delete releases. The commits has been split for an easier review. There is no need to review 3f0d6e7 since the code there has been already reviewed in the helm-crd project. Part of 22d2777 has been extracted from that project as well.
The proxy uses the same packages to serve the API than the chart service:
gorilla/mux
for the router andurfave/negroni
as a middleware.