Skip to content
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

Revise provider cluster identity #8

Merged
merged 2 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -149,6 +149,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 @@ -182,7 +184,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
Loading