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

Restructure APIServiceBinding to remove kube-system access permissions #9

Merged
merged 3 commits into from
Mar 6, 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
11 changes: 4 additions & 7 deletions apis/kubebind/v1alpha1/apiservicebinding_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,17 @@ func (in *APIServiceBinding) SetConditions(conditions conditionsapi.Conditions)
}

type APIServiceBindingSpec struct {
// kubeconfigSecretName is the secret ref that contains the kubeconfig of the service cluster.
//
// +required
// +kubebuilder:validation:Required
KubeconfigSecretRefs []ClusterSecretKeyRef `json:"kubeconfigSecretRefs"`
// Providers contains the provider ClusterIdentity and KubeconfigSecretRef of the provider cluster
Providers []Provider `json:"providers,omitempty"`
}

type Provider struct {
ClusterIdentity `json:",inline"`
RemoteNamespace string `json:"remoteNamespace,omitempty"`

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

type ClusterIdentity struct {
Expand All @@ -104,9 +104,6 @@ type ClusterIdentity struct {
}

type APIServiceBindingStatus struct {
// 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.
Conditions conditionsapi.Conditions `json:"conditions,omitempty"`
}
Expand Down
19 changes: 4 additions & 15 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.

Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@
func (r *reconciler) reconcile(ctx context.Context, clusterBinding *v1alpha1.ClusterBinding) error {
var errs []error

if err := r.ensureKubeSystemNSAccess(ctx, clusterBinding); err != nil {
errs = append(errs, err)
}
//if err := r.ensureKubeSystemNSAccess(ctx, clusterBinding); err != nil {
// errs = append(errs, err)
//}
r.ensureClusterBindingConditions(clusterBinding)
if err := r.ensureRBACRoleBinding(ctx, clusterBinding); err != nil {
errs = append(errs, err)
Expand Down Expand Up @@ -117,7 +117,7 @@
}
}

func (r *reconciler) ensureKubeSystemNSAccess(ctx context.Context, clusterBinding *v1alpha1.ClusterBinding) error {

Check failure on line 120 in contrib/example-backend/controllers/clusterbinding/clusterbinding_reconcile.go

View workflow job for this annotation

GitHub Actions / Build

func `(*reconciler).ensureKubeSystemNSAccess` is unused (unused)
roleName := "kube-binder-namespace"
clusterRole, err := r.getClusterRole(roleName)
if err != nil && !errors.IsNotFound(err) {
Expand Down
79 changes: 28 additions & 51 deletions crds/kube-bind.appscode.com_apiservicebindings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,33 +55,42 @@ spec:
description: spec specifies how an API service from a service provider
should be bound in the local consumer cluster.
properties:
kubeconfigSecretRefs:
description: kubeconfigSecretName is the secret ref that contains
the kubeconfig of the service cluster.
providers:
description: Providers contains the provider ClusterIdentity and KubeconfigSecretRef
of the provider cluster
items:
properties:
key:
description: The key of the secret to select from. Must be
"kubeconfig".
enum:
- kubeconfig
clusterName:
type: string
name:
description: Name of the referent.
minLength: 1
clusterUID:
type: string
namespace:
description: Namespace of the referent.
minLength: 1
kubeconfig:
properties:
key:
description: The key of the secret to select from. Must
be "kubeconfig".
enum:
- kubeconfig
type: string
name:
description: Name of the referent.
minLength: 1
type: string
namespace:
description: Namespace of the referent.
minLength: 1
type: string
required:
- key
- name
- namespace
type: object
remoteNamespace:
type: string
required:
- key
- name
- namespace
type: object
type: array
required:
- kubeconfigSecretRefs
- providers
type: object
status:
description: status contains reconciliation information for a service
Expand Down Expand Up @@ -139,38 +148,6 @@ spec:
- type
type: object
type: array
providers:
description: Providers contains the provider ClusterIdentity and KubeconfigSecretRef
of the provider cluster
items:
properties:
clusterName:
type: string
clusterUID:
type: string
kubeconfigs:
properties:
key:
description: The key of the secret to select from. Must
be "kubeconfig".
enum:
- kubeconfig
type: string
name:
description: Name of the referent.
minLength: 1
type: string
namespace:
description: Namespace of the referent.
minLength: 1
type: string
required:
- key
- name
- namespace
type: object
type: object
type: array
type: object
type: object
served: true
Expand Down
2 changes: 1 addition & 1 deletion hack/examples/docker-machine.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
namespace: demo
annotations:
# provider.kube-bind.appscode.com/cluster-id: 71a87546-b339-45ee-bca5-033d277faca2
provider.kube-bind.appscode.com/cluster-id: e95736c6-06f2-43ae-9f17-bbcc0c38c4ed
provider.kube-bind.appscode.com/cluster-id: 68d95713-cdbf-4fc1-96ed-ca2fc743ec7c
spec:
driver:
name: google
Expand Down
6 changes: 3 additions & 3 deletions pkg/indexers/servicebinding.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ func IndexServiceBindingByKubeconfigSecret(obj interface{}) ([]string, error) {
}

func ByServiceBindingKubeconfigSecretKey(binding *kubebindv1alpha1.APIServiceBinding) []string {
refs := binding.Spec.KubeconfigSecretRefs
ps := binding.Spec.Providers
var secretRefs []string
for _, ref := range refs {
secretRefs = append(secretRefs, ref.Namespace+"/"+ref.Name)
for _, p := range ps {
secretRefs = append(secretRefs, p.Kubeconfig.Namespace+"/"+p.Kubeconfig.Name)
}
return secretRefs
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ func NewController(
heartbeatInterval: heartbeatInterval,
providerInfos: providerInfos,

updateServiceBinding: func(ctx context.Context, sbinding *v1alpha1.APIServiceBinding) error {
if _, err = consumerBindClient.KubeBindV1alpha1().APIServiceBindings().Update(ctx, sbinding, metav1.UpdateOptions{}); err != nil {
return err
}
return nil
},
getServiceBinding: func(ctx context.Context) (*v1alpha1.APIServiceBindingList, error) {
return consumerBindClient.KubeBindV1alpha1().APIServiceBindings().List(ctx, metav1.ListOptions{})
},
getProviderInfo: func(clusterID string) (*konnectormodels.ProviderInfo, error) {
for _, provider := range providerInfos {
if provider.ClusterID == clusterID {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package clusterbinding

import (
"context"
"fmt"
"time"

kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1"
Expand All @@ -38,6 +39,8 @@ import (
type reconciler struct {
heartbeatInterval time.Duration

updateServiceBinding func(ctx context.Context, sbinding *kubebindv1alpha1.APIServiceBinding) error
getServiceBinding func(ctx context.Context) (*kubebindv1alpha1.APIServiceBindingList, error)
getProviderSecret func(porvider *konnectormodels.ProviderInfo) (*corev1.Secret, error)
getConsumerSecret func(provider *konnectormodels.ProviderInfo) (*corev1.Secret, error)
updateConsumerSecret func(ctx context.Context, secret *corev1.Secret) (*corev1.Secret, error)
Expand Down Expand Up @@ -66,11 +69,40 @@ func (r *reconciler) reconcile(ctx context.Context, binding *kubebindv1alpha1.Cl
errs = append(errs, err)
}

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

conditions.SetSummary(binding)

return utilerrors.NewAggregate(errs)
}

func (r *reconciler) ensureRightScopedServiceBinding(ctx context.Context, binding *kubebindv1alpha1.ClusterBinding) error {
// return error if provider info is not set in clusterBinding status
if binding.Status.Provider.ClusterName == "" || binding.Status.Provider.ClusterUID == "" {
return fmt.Errorf("cluster name or uid is missing in ClusterBinding status")
}

sblist, err := r.getServiceBinding(ctx)
if err != nil {
return err
}
for _, sb := range sblist.Items {
for i := range sb.Spec.Providers {
if sb.Spec.Providers[i].RemoteNamespace == binding.Namespace && (sb.Spec.Providers[i].ClusterUID == "" || sb.Spec.Providers[i].ClusterName == "") {
sb.Spec.Providers[i].ClusterUID = binding.Status.Provider.ClusterUID
sb.Spec.Providers[i].ClusterName = binding.Status.Provider.ClusterName
if err = r.updateServiceBinding(ctx, &sb); err != nil {
return err
}
break
}
}
}
return nil
}

func (r *reconciler) ensureHeartbeat(ctx context.Context, binding *kubebindv1alpha1.ClusterBinding) error {
binding.Status.HeartbeatInterval.Duration = r.heartbeatInterval
if now := time.Now(); binding.Status.LastHeartbeatTime.IsZero() || now.After(binding.Status.LastHeartbeatTime.Add(r.heartbeatInterval/2)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ func (r *reconciler) reconcile(ctx context.Context, binding *v1alpha1.APIService
errs = append(errs, err)
}

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

conditions.SetSummary(binding)

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

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)
if err != nil && !errors.IsNotFound(err) {
return err
} else if errors.IsNotFound(err) {
return nil
}
prov := v1alpha1.Provider{}
prov.Kubeconfig = &v1alpha1.ClusterSecretKeyRef{
LocalSecretKeyRef: clusterBinding.Spec.KubeconfigSecretRef,
Namespace: clusterBinding.Namespace,
}
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)
}

return nil
}
//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)
// if err != nil && !errors.IsNotFound(err) {
// return err
// } else if errors.IsNotFound(err) {
// return nil
// }
// prov := v1alpha1.Provider{}
// prov.Kubeconfig = &v1alpha1.ClusterSecretKeyRef{
// LocalSecretKeyRef: clusterBinding.Spec.KubeconfigSecretRef,
// Namespace: clusterBinding.Namespace,
// }
// 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)
// }
//
// return nil
//}
Loading
Loading