Skip to content

Commit

Permalink
Revise provider cluster identity (#8)
Browse files Browse the repository at this point in the history
Signed-off-by: Tamal Saha <[email protected]>
Signed-off-by: rasel <[email protected]>
Co-authored-by: rasel <[email protected]>
  • Loading branch information
tamalsaha and Superm4n97 authored Mar 2, 2024
1 parent fccdf0c commit 3d1723e
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 35 deletions.
12 changes: 7 additions & 5 deletions apis/kubebind/v1alpha1/apiservicebinding_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ const (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:scope=Cluster,categories=kube-bindings,shortName=sb
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Provider",type="string",JSONPath=`.status.providerPrettyName`,priority=0
// +kubebuilder:printcolumn:name="Resources",type="string",JSONPath=`.metadata.annotations.kube-bind\.appscode\.com/resources`,priority=1
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=`.status.conditions[?(@.type=="Ready")].status`,priority=0
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=`.status.conditions[?(@.type=="Ready")].message`,priority=0
Expand Down Expand Up @@ -94,15 +93,18 @@ type APIServiceBindingSpec struct {
}

type Provider struct {
// providerPrettyName is the pretty name of the service provider cluster. This
// can be shared among different APIServiceBindings.
PrettyName string `json:"providerPrettyName,omitempty"`
ClusterIdentity `json:",inline"`

Kubeconfig *ClusterSecretKeyRef `json:"kubeconfigs,omitempty"`
}

type ClusterIdentity struct {
ClusterUID string `json:"clusterUID"`
ClusterName string `json:"clusterName"`
}

type APIServiceBindingStatus struct {
// Providers contains the PrettyName and KubeconfigSecretRef of the provider cluster
// Providers contains the provider ClusterIdentity and KubeconfigSecretRef of the provider cluster
Providers []Provider `json:"providers,omitempty"`

// conditions is a list of conditions that apply to the APIServiceBinding.
Expand Down
8 changes: 0 additions & 8 deletions apis/kubebind/v1alpha1/bindingprovider_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@ import (
type BindingProvider struct {
metav1.TypeMeta `json:",inline"`

// providerPrettyName is the name of the provider that is displayed to the user, e.g:
// MangoDB Inc.
//
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
ProviderPrettyName string `json:"providerPrettyName"`

// version is the kube-bind.appscode.com version of the provider. The kubectl bind will check
// this for compatibility.
//
Expand Down
7 changes: 5 additions & 2 deletions apis/kubebind/v1alpha1/clusterbinding_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ type ClusterBindingSpec struct {
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="kubeconfigSecretRef is immutable"
KubeconfigSecretRef LocalSecretKeyRef `json:"kubeconfigSecretRef"`

// providerPrettyName is the pretty name of the service provider cluster. This
// providerClusterName is the cluster name of the service provider cluster. This
// can be shared among different ServiceBindings.
//
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
ProviderPrettyName string `json:"providerPrettyName"`
ProviderClusterName string `json:"providerClusterName"`

// serviceProviderSpec contains all the data and information about the service which has been bound to the service
// binding request. The service providers decide what they need and what to configure based on what then include in
Expand All @@ -122,6 +122,9 @@ type ClusterBindingSpec struct {
// ClusterBindingStatus stores status information about a service binding. It is
// updated by both the konnector and the service provider.
type ClusterBindingStatus struct {
// Provider is the cluster id and name of the service provider cluster.
Provider *ClusterIdentity `json:"provider,omitempty"`

// lastHeartbeatTime is the last time the konnector updated the status.
LastHeartbeatTime metav1.Time `json:"lastHeartbeatTime,omitempty"`

Expand Down
22 changes: 22 additions & 0 deletions apis/kubebind/v1alpha1/zz_generated.deepcopy.go

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

3 changes: 1 addition & 2 deletions contrib/example-backend/http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ func (h *handler) handleServiceExport(w http.ResponseWriter, r *http.Request) {
APIVersion: v1alpha1.GroupVersion,
Kind: "BindingProvider",
},
Version: ver,
ProviderPrettyName: "example-backend",
Version: ver,
AuthenticationMethods: []v1alpha1.AuthenticationMethod{
{
Method: "OAuth2CodeGrant",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"k8s.io/klog/v2"
)

func CreateClusterBinding(ctx context.Context, client bindclient.Interface, ns, secretName, providerPrettyName string) error {
func CreateClusterBinding(ctx context.Context, client bindclient.Interface, ns, secretName, clusterName string) error {
logger := klog.FromContext(ctx)

clusterBinding := &v1alpha1.ClusterBinding{
Expand All @@ -35,7 +35,7 @@ func CreateClusterBinding(ctx context.Context, client bindclient.Interface, ns,
Namespace: ns,
},
Spec: v1alpha1.ClusterBindingSpec{
ProviderPrettyName: providerPrettyName,
ProviderClusterName: clusterName,
KubeconfigSecretRef: v1alpha1.LocalSecretKeyRef{
Name: secretName,
Key: "kubeconfig",
Expand Down
13 changes: 5 additions & 8 deletions crds/kube-bind.appscode.com_apiservicebindings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ spec:
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .status.providerPrettyName
name: Provider
type: string
- jsonPath: .metadata.annotations.kube-bind\.appscode\.com/resources
name: Resources
priority: 1
Expand Down Expand Up @@ -143,10 +140,14 @@ spec:
type: object
type: array
providers:
description: Providers contains the PrettyName and KubeconfigSecretRef
description: Providers contains the provider ClusterIdentity and KubeconfigSecretRef
of the provider cluster
items:
properties:
clusterName:
type: string
clusterUID:
type: string
kubeconfigs:
properties:
key:
Expand All @@ -168,10 +169,6 @@ spec:
- name
- namespace
type: object
providerPrettyName:
description: providerPrettyName is the pretty name of the service
provider cluster. This can be shared among different APIServiceBindings.
type: string
type: object
type: array
type: object
Expand Down
15 changes: 12 additions & 3 deletions crds/kube-bind.appscode.com_clusterbindings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ spec:
x-kubernetes-validations:
- message: kubeconfigSecretRef is immutable
rule: self == oldSelf
providerPrettyName:
description: providerPrettyName is the pretty name of the service
providerClusterName:
description: providerClusterName is the cluster name of the service
provider cluster. This can be shared among different ServiceBindings.
minLength: 1
type: string
Expand All @@ -85,7 +85,7 @@ spec:
x-kubernetes-preserve-unknown-fields: true
required:
- kubeconfigSecretRef
- providerPrettyName
- providerClusterName
type: object
status:
description: status contains reconciliation information for the service
Expand Down Expand Up @@ -158,6 +158,15 @@ spec:
the status.
format: date-time
type: string
provider:
description: Provider is the cluster id and name of the service provider
cluster.
properties:
clusterName:
type: string
clusterUID:
type: string
type: object
type: object
required:
- spec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (r *reconciler) reconcile(ctx context.Context, binding *v1alpha1.APIService
errs = append(errs, err)
}

if err := r.ensurePrettyName(ctx, binding); err != nil {
if err := r.ensureClusterName(ctx, binding); err != nil {
errs = append(errs, err)
}

Expand Down Expand Up @@ -197,7 +197,7 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *v1alpha1.APIServic
return utilerrors.NewAggregate(errs)
}

func (r *reconciler) ensurePrettyName(ctx context.Context, binding *v1alpha1.APIServiceBinding) error {
func (r *reconciler) ensureClusterName(ctx context.Context, binding *v1alpha1.APIServiceBinding) error {
binding.Status.Providers = []v1alpha1.Provider{}
for _, provider := range r.providerInfos {
clusterBinding, err := r.getClusterBinding(ctx, provider)
Expand All @@ -211,7 +211,10 @@ func (r *reconciler) ensurePrettyName(ctx context.Context, binding *v1alpha1.API
LocalSecretKeyRef: clusterBinding.Spec.KubeconfigSecretRef,
Namespace: clusterBinding.Namespace,
}
prov.PrettyName = clusterBinding.Spec.ProviderPrettyName
if clusterBinding.Status.Provider != nil {
prov.ClusterIdentity.ClusterName = clusterBinding.Spec.ProviderClusterName
prov.ClusterIdentity.ClusterUID = clusterBinding.Status.Provider.ClusterUID
}
binding.Status.Providers = append(binding.Status.Providers, prov)
}

Expand Down
4 changes: 3 additions & 1 deletion pkg/kubectl/bind/plugin/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
clientgoversion "k8s.io/client-go/pkg/version"
)

// getProvider calls for /export url and returns BindingProvider which contains the oidc authentication method
func getProvider(url string) (*kubebindv1alpha1.BindingProvider, error) {
resp, err := http.Get(url)
if err != nil {
Expand Down Expand Up @@ -90,7 +91,7 @@ func validateProviderVersion(providerVersion string) error {
return nil
}

func (b *BindOptions) authenticate(provider *kubebindv1alpha1.BindingProvider, callback, sessionID, clusterID string, urlCh chan<- string) error {
func (b *BindOptions) authenticate(provider *kubebindv1alpha1.BindingProvider, callback, sessionID, clusterID, clusterName string, urlCh chan<- string) error {
var oauth2Method *kubebindv1alpha1.OAuth2CodeGrant
for _, m := range provider.AuthenticationMethods {
if m.Method == "OAuth2CodeGrant" {
Expand Down Expand Up @@ -120,6 +121,7 @@ func (b *BindOptions) authenticate(provider *kubebindv1alpha1.BindingProvider, c
values.Add("p", cbPort)
values.Add("s", sessionID)
values.Add("c", clusterID)
values.Add("n", clusterName)
u.RawQuery = values.Encode()

fmt.Fprintf(b.Options.ErrOut, "\nTo authenticate, visit in your browser:\n\n\t%s\n", u.String()) // nolint: errcheck
Expand Down
4 changes: 3 additions & 1 deletion pkg/kubectl/bind/plugin/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ func (b *BindOptions) Run(ctx context.Context, urlCh chan<- string) error {
return err // should never happen because we test this in Validate()
}

providerClusterName := exportURL.Query().Get("cluster")

provider, err := getProvider(exportURL.String())
if err != nil {
return fmt.Errorf("failed to fetch authentication url %q: %v", exportURL, err)
Expand Down Expand Up @@ -183,7 +185,7 @@ func (b *BindOptions) Run(ctx context.Context, urlCh chan<- string) error {
}

sessionID := SessionID()
if err := b.authenticate(provider, auth.Endpoint(), sessionID, ClusterID(ns), urlCh); err != nil {
if err := b.authenticate(provider, auth.Endpoint(), sessionID, ClusterID(ns), providerClusterName, urlCh); err != nil {
return err
}

Expand Down

0 comments on commit 3d1723e

Please sign in to comment.