Skip to content

Commit

Permalink
Initial work for adding groups
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewstuart committed Sep 1, 2021
1 parent cf4a3dd commit 45cdb59
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 75 deletions.
10 changes: 10 additions & 0 deletions api/v1beta1/oauth2proxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ type OAuth2ProxySpec struct {

// Service instructs the controller to target a specific single service.
Service *v1.ObjectReference `json:"service,omitempty"`

AllowedGroups []string `json:"allowedGroups,omitempty"`

// All ProxyOpts that can be passed as environment variables can be specified
// here. See
// https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview
// (or the latest equivalent of
// https://github.com/oauth2-proxy/oauth2-proxy/blob/e6223383e5ff68709afe8e47d3e91b499e5802ad/docs/docs/configuration/overview.md)
// if the page is gone.
ProxyOpts map[string]string `json:"proxyOpts,omitempty"`
}

type SessionStore struct {
Expand Down
12 changes: 12 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

4 changes: 2 additions & 2 deletions config/crd/bases/microcumul.us_oauth2clientproviders.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ spec:
description: OAuth2ClientProviderSpec defines the desired state of OAuth2ClientProvider
properties:
keycloak:
description: Keycloak providers can provision oauth2 clients from
openid connect
description: Keycloak providers can provision oauth2 (oidc) clients
from keycloak instances
properties:
baseURL:
description: BaseURL is the externally-accessible base URL for
Expand Down
68 changes: 44 additions & 24 deletions config/crd/bases/microcumul.us_oauth2proxies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ spec:
spec:
description: OAuth2ProxySpec defines the desired state of OAuth2Proxy
properties:
allowedGroups:
items:
type: string
type: array
clientProvider:
type: string
clientType:
Expand Down Expand Up @@ -124,28 +128,13 @@ spec:
are ANDed.
type: object
type: object
redisHost:
type: string
redisPasswordRef:
description: RedisPasswordRef refers to the password to a redis instance,
to be used for session storage
properties:
key:
description: The key of the secret to select from. Must be a
valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
namespace:
type: string
optional:
description: Specify whether the Secret or its key must be defined
type: boolean
required:
- key
- namespace
proxyOpts:
additionalProperties:
type: string
description: All ProxyOpts that can be passed as environment variables
can be specified here. See https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview
(or the latest equivalent of https://github.com/oauth2-proxy/oauth2-proxy/blob/e6223383e5ff68709afe8e47d3e91b499e5802ad/docs/docs/configuration/overview.md)
if the page is gone.
type: object
service:
description: Service instructs the controller to target a specific
Expand Down Expand Up @@ -229,10 +218,41 @@ spec:
are ANDed.
type: object
type: object
sessionStore:
properties:
redis:
properties:
host:
type: string
passwordRef:
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
namespace:
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
- namespace
type: object
required:
- host
type: object
required:
- redis
type: object
required:
- ingress
- redisHost
- redisPasswordRef
- sessionStore
type: object
status:
description: OAuth2ProxyStatus defines the observed state of OAuth2Proxy
Expand Down
2 changes: 1 addition & 1 deletion config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ resources:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- digest: sha256:fc399d9e355c9aac00d45ab99ab0bbd497401009b7eafba9e1f3a7bbca786cb4
- digest: sha256:17a8a76a3de7bb04cc4653b518c5991b5093029daa656d87ede5247aea1c33eb
name: controller
newName: andrewstuart/oauth2controller
71 changes: 54 additions & 17 deletions controllers/oauth2proxy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ type OAuth2ProxyReconciler struct {
Scheme *runtime.Scheme
}

func (r *OAuth2ProxyReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&microcumulusv1beta1.OAuth2Proxy{}).
Complete(r)
}

// +kubebuilder:rbac:groups=microcumul.us,resources=oauth2proxies,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=microcumul.us,resources=oauth2proxies/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;update;patch;create;delete;list;watch
Expand Down Expand Up @@ -116,7 +122,6 @@ func (r *OAuth2ProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
// }
// svcs.Items = []corev1.Service{svc}
// }

// Check for oidc secrets values; create if not exist
var sec corev1.Secret
err = r.Get(ctx, req.NamespacedName, &sec)
Expand Down Expand Up @@ -164,13 +169,31 @@ func (r *OAuth2ProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, fmt.Errorf("error getting redis secret: %w", err)
}

err = replaceWithOauth2Proxy(ctx, r.Client, &ing, spec, string(sec.Data["id"]), string(sec.Data["secret"]), string(sec.Data["issuerURL"]), spec.Spec.SessionStore.Redis.Host, rSec)
groupClaim, err := r.getGroupClaim(ctx, spec)
if err != nil {
return ctrl.Result{}, fmt.Errorf("couldn't get jwt group claim key from provider: %w", err)
}

err = replaceWithOauth2Proxy(ctx, r.Client, &ing, spec, oa2ProxyOpts{
id: string(sec.Data["id"]),
secret: string(sec.Data["secret"]),
issuerURL: string(sec.Data["issuerURL"]),
redisHost: spec.Spec.SessionStore.Redis.Host,
redisPass: rSec,
groupClaim: groupClaim,
groups: spec.Spec.AllowedGroups,
optsMap: spec.Spec.ProxyOpts,
})
if err != nil {
return ctrl.Result{}, fmt.Errorf("error replacing ingress with proxy: %w", err)
}
return ctrl.Result{}, nil
}

func (r *OAuth2ProxyReconciler) getGroupClaim(ctx context.Context, spec microcumulusv1beta1.OAuth2Proxy) (string, error) {
return "groups", nil
}

func (r *OAuth2ProxyReconciler) handleDelete(ctx context.Context, spec microcumulusv1beta1.OAuth2Proxy, ing networkv1.Ingress) (ctrl.Result, error) {
if !containsString(spec.Finalizers, finalizerStringProx) { // Success case; nothing left to do
return ctrl.Result{}, nil
Expand Down Expand Up @@ -201,13 +224,18 @@ func (r *OAuth2ProxyReconciler) handleDelete(ctx context.Context, spec microcumu
return ctrl.Result{}, nil
}

func (r *OAuth2ProxyReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&microcumulusv1beta1.OAuth2Proxy{}).
Complete(r)
type oa2ProxyOpts struct {
id string
secret string
issuerURL string
redisHost string
redisPass string
groupClaim string
groups []string
optsMap map[string]string
}

func replaceWithOauth2Proxy(ctx context.Context, cs client.Client, ing *networkv1.Ingress, spec microcumulusv1beta1.OAuth2Proxy, id, sec, issuerURL, redisHost, redisSec string) error {
func replaceWithOauth2Proxy(ctx context.Context, cs client.Client, ing *networkv1.Ingress, spec microcumulusv1beta1.OAuth2Proxy, opts oa2ProxyOpts) error {
sp, ctx := opentracing.StartSpanFromContext(ctx, "replaceWithOauth2Proxy")
defer sp.Finish()

Expand All @@ -231,16 +259,25 @@ func replaceWithOauth2Proxy(ctx context.Context, cs client.Client, ing *networkv
be := rule.HTTP.Paths[0].Backend
m := map[string]string{
"UPSTREAM": fmt.Sprintf("http://%s:%d", be.Service.Name, be.Service.Port.Number),
"OIDC_ISSUER_URL": issuerURL,
"CLIENT_ID": id,
"CLIENT_SECRET": sec,
"OIDC_ISSUER_URL": opts.issuerURL,
"CLIENT_ID": opts.id,
"CLIENT_SECRET": opts.secret,
"COOKIE_SECRET": base64.StdEncoding.EncodeToString(bs),
}
if redisSec != "" {
m["REDIS_PASSWORD"] = redisSec
for k, v := range opts.optsMap {
m[k] = v
}
if opts.redisPass != "" {
m["REDIS_PASSWORD"] = opts.redisPass
}
if opts.groupClaim != "" {
m["OIDC_GROUPS_CLAIM"] = opts.groupClaim
}
if opts.groups != nil {
m["ALLOWED_GROUPS"] = strings.Join(opts.groups, ",")
}

proxName := fmt.Sprintf("oauth2-proxy-%s-%s", id, be.Service.Name)
proxName := fmt.Sprintf("oauth2-proxy-%s-%s", opts.id, be.Service.Name)

err := cs.Create(ctx, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -263,7 +300,7 @@ func replaceWithOauth2Proxy(ctx context.Context, cs client.Client, ing *networkv
Name: proxName,
Namespace: ing.Namespace,
Labels: map[string]string{
"app": id,
"app": opts.id,
"tier": "proxy",
},
Annotations: map[string]string{
Expand Down Expand Up @@ -307,14 +344,14 @@ func replaceWithOauth2Proxy(ctx context.Context, cs client.Client, ing *networkv
Replicas: &one32,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": id,
"app": opts.id,
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: om,
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
Name: id,
Name: opts.id,
Image: "quay.io/oauth2-proxy/oauth2-proxy:latest",
Args: []string{
"--upstream=$(OAUTH2_PROXY_UPSTREAM)",
Expand All @@ -324,7 +361,7 @@ func replaceWithOauth2Proxy(ctx context.Context, cs client.Client, ing *networkv
"--email-domain=*",
"--session-store-type=redis",
"--cookie-secure=true",
"--redis-connection-url=redis://" + redisHost,
"--redis-connection-url=redis://" + opts.redisHost,
`--banner=<img src="https://microcumul.us/images/logo/logo.svg" alt="microcumulus logo" />`,
"--custom-sign-in-logo=-",
},
Expand Down
Loading

0 comments on commit 45cdb59

Please sign in to comment.