crossplane-contrib / provider-kubernetes

Crossplane provider to provision and manage Kubernetes objects on (remote) Kubernetes clusters.
Apache License 2.0
136 stars 80 forks source link

Add support for auth with Upbound identity and refactor kube client builder as an importable package #251

Closed turkenh closed 1 month ago

turkenh commented 1 month ago

Description of your changes

This PR adding support for authenticating with Upbound identity using session/robot tokens:

apiVersion: kubernetes.crossplane.io/v1alpha1
kind: ProviderConfig
metadata:
  name: kubernetes-provider
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: cluster-config
      key: kubeconfig
  identity:
    type: UpboundTokens
    source: Secret
    secretRef:
      name: upbound-credentials
      namespace: crossplane-system
      key: token

With the number of identity providers increasing, I took the liberty of refactoring the relevant code piece so that we can consume the same package from the provider-helm (and other similar providers) instead of duplicating the code. After this PR, I'll open a PR to consume the package github.com/crossplane-contrib/provider-kubernetes/pkg/kube/ from provider-helm. It may not be the perfect solution but I believe it is a step forward and we can easily move it to a shared place (e.g. crossplane-runtime) if we decide to do so.

I have:

How has this code been tested

Configure & Create:

export UPBOUND_ACCOUNT=<YOUR_ACCOUNT>
export UPBOUND_TOKEN=<YOUR_API_TOKEN> # Robot tokens will be supported soon
export CONTROLPLANE_CONFIG=/tmp/controlplane-kubeconfig
rm -f $CONTROLPLANE_CONFIG

up alpha web-login -a $UPBOUND_ACCOUNT
KUBECONFIG=$CONTROLPLANE_CONFIG up ctx $UPBOUND_ACCOUNT/upbound-gcp-us-west-1/default/hasan-test

kubectl -n crossplane-system create secret generic cluster-config --from-file=kubeconfig=$CONTROLPLANE_CONFIG
kubectl -n crossplane-system create secret generic upbound-credentials --from-literal=token=$UPBOUND_TOKEN

kubectl apply -f examples/provider/provider-config-with-secret-upbound-identity.yaml
kubectl apply -f examples/object/object.yaml

Observe:

❯ kubectl get object
NAME               KIND        PROVIDERCONFIG        SYNCED   READY   AGE
sample-namespace   Namespace   kubernetes-provider   True     True    4s

❯ KUBECONFIG=$CONTROLPLANE_CONFIG kubectl get ns
NAME                STATUS   AGE
crossplane-system   Active   32h
default             Active   32h
kube-node-lease     Active   32h
kube-public         Active   32h
kube-system         Active   32h
sample-namespace    Active   4m20s
upbound-system      Active   32h
haarchri commented 1 month ago

@turkenh thanks for the implementation - i tested the implementation over time i got the following issue:

  Warning  CannotObserveExternalResource  2m8s (x2110 over 34h)  managed/object.kubernetes.crossplane.io  cannot get object: failed to get API group resources: unable to retrieve the complete list of server APIs: spaces.upbound.io/v1beta1: Get "https://upbound-gcp-us-west-1.space.mxe.upbound.io/apis/spaces.upbound.io/v1beta1": cannot get upbound org scoped token: Post "https://auth.upbound.io/apis/tokenexchange.upbound.io/v1alpha1/orgscopedtokens": context canceled
haarchri commented 1 month ago

yes looks like after 60 minutes something happens:

Events:
  Type     Reason                         Age                   From                                     Message
  ----     ------                         ----                  ----                                     -------
  Warning  CannotObserveExternalResource  2m23s (x46 over 42m)  managed/object.kubernetes.crossplane.io  cannot get object: failed to get API group resources: unable to retrieve the complete list of server APIs: spaces.upbound.io/v1beta1: Get "https://upbound-gcp-us-west-1.space.mxe.upbound.io/apis/spaces.upbound.io/v1beta1": cannot get upbound org scoped token: Post "https://auth.upbound.io/apis/tokenexchange.upbound.io/v1alpha1/orgscopedtokens": context canceled
NAME                                            KIND           PROVIDERCONFIG                               SYNCED   READY   AGE
object.kubernetes.crossplane.io/ctp-dev-69wbr   Secret         default                                      False    True    61m
object.kubernetes.crossplane.io/ctp-dev-bwqbl   ControlPlane   5ab0024e-fbc3-4a42-a1a1-a1dd4875093d-space   False    True    61m
object.kubernetes.crossplane.io/ctp-dev-qcj2n   Secret         default                                      False    True    61m
turkenh commented 1 month ago

yes looks like after 60 minutes something happens

@haarchri it should be fixed now.

Also, please note the small change in the identity type to be consistent with others, UpboundToken -> UpboundTokens.

haarchri commented 1 month ago

its working now:

object.kubernetes.crossplane.io/ctp-prod-cdd6x       Secret         default                                      True     True    83m
object.kubernetes.crossplane.io/ctp-prod-lgbtg       Secret         default                                      True     True    83m
object.kubernetes.crossplane.io/ctp-prod-wfzd4       ControlPlane   24bf1d49-140c-41e2-819e-15e14acf2538-space   True     True    83m

thanks for the implementation