Skip to content

Commit ed1e0ab

Browse files
committed
Add minimal permissionClaims API
1 parent 7b255ac commit ed1e0ab

6 files changed

Lines changed: 237 additions & 22 deletions

File tree

sdk/apis/kubebind/v1alpha2/apiservicebinding_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ type APIServiceBindingSpec struct {
8888
// +kubebuilder:validation:Required
8989
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="kubeconfigSecretRef is immutable"
9090
KubeconfigSecretRef ClusterSecretKeyRef `json:"kubeconfigSecretRef"`
91+
92+
// PermissionClaims records decisions about permission claims requested by the service provider.
93+
// Access is granted per GroupResource.
94+
PermissionClaims []PermissionClaim `json:"permissionClaims,omitempty"`
9195
}
9296

9397
type APIServiceBindingStatus struct {

sdk/apis/kubebind/v1alpha2/apiserviceexport_types.go

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package v1alpha2
1818

1919
import (
20-
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2120
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2221

2322
conditionsapi "github.com/kube-bind/kube-bind/sdk/apis/third_party/conditions/apis/conditions/v1alpha1"
@@ -38,6 +37,9 @@ const (
3837
// APIServiceExportConditionConsumerInSync is set to true when the APIServiceExport's
3938
// schema is applied to the consumer cluster.
4039
APIServiceExportConditionConsumerInSync conditionsapi.ConditionType = "ConsumerInSync"
40+
41+
// APIServiceExportConditionPermissionClaim describes status of the permission claim, requested in the APIServiceExport and APIServiceExportRequest.
42+
APIServiceExportConditionPermissionClaim conditionsapi.ConditionType = "PermissionClaim"
4143
)
4244

4345
// APIServiceExport specifies the resource to be exported. It is mostly a CRD:
@@ -86,6 +88,10 @@ type APIServiceExportSpec struct {
8688
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="resources are immutable"
8789
Resources []APIServiceExportResource `json:"resources"`
8890

91+
// PermissionClaims records decisions about permission claims requested by the service provider.
92+
// Access is granted per GroupResource.
93+
PermissionClaims []PermissionClaim `json:"permissionClaims,omitempty"`
94+
8995
// informerScope is the scope of the APIServiceExport. It can be either Cluster or Namespace.
9096
//
9197
// Cluster: The konnector has permission to watch all namespaces at once and cluster-scoped resources.
@@ -122,20 +128,6 @@ const (
122128
// APIServiceExportStatus stores status information about a APIServiceExport. It
123129
// reflects the status of the CRD of the consumer cluster.
124130
type APIServiceExportStatus struct {
125-
// acceptedNames are the names that are actually being used to serve discovery.
126-
// They may be different than the names in spec.
127-
// +optional
128-
AcceptedNames apiextensionsv1.CustomResourceDefinitionNames `json:"acceptedNames"`
129-
130-
// storedVersions lists all versions of CustomResources that were ever persisted. Tracking these
131-
// versions allows a migration path for stored versions in etcd. The field is mutable
132-
// so a migration controller can finish a migration to another version (ensuring
133-
// no old objects are left in storage), and then remove the rest of the
134-
// versions from this list.
135-
// Versions may not be removed from `spec.versions` while they exist in this list.
136-
// +optional
137-
StoredVersions []string `json:"storedVersions"`
138-
139131
// conditions is a list of conditions that apply to the APIServiceExport. It is
140132
// updated by the konnector on the consumer cluster.
141133
Conditions conditionsapi.Conditions `json:"conditions,omitempty"`

sdk/apis/kubebind/v1alpha2/apiserviceexportrequest_types.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ type APIServiceExportRequestSpec struct {
106106
// +kubebuilder:validation:MinItems=1
107107
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="resources are immutable"
108108
Resources []APIServiceExportRequestResource `json:"resources"`
109+
110+
// PermissionClaims records decisions about permission claims requested by the service provider.
111+
// Access is granted per GroupResource.
112+
PermissionClaims []PermissionClaim `json:"permissionClaims,omitempty"`
109113
}
110114

111115
type APIServiceExportRequestResource struct {
@@ -123,6 +127,20 @@ func (r APIServiceExportRequestResource) ResourceGroupName() string {
123127
return fmt.Sprintf("%s.%s", r.Resource, r.Group)
124128
}
125129

130+
// Selector is a resource selector that selects objects of a GVR.
131+
//
132+
// +kubebuilder:validation:XValidation:rule="(has(self.all) && self.all) != (has(self.labelSelector) && size(self.labelSelector) > 0)",message="either \"all\" or \"labelSelector\" must be set"
133+
type Selector struct {
134+
// all claims all resources for the given group/resource.
135+
// This is mutually exclusive with labelSelector.
136+
// +optional
137+
All bool `json:"all,omitempty"`
138+
139+
// LabelSelector is a label selector that selects objects of a GVR.
140+
// +optional
141+
LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"`
142+
}
143+
126144
// GroupResource identifies a resource.
127145
type GroupResource struct {
128146
// group is the name of an API group.
@@ -142,6 +160,33 @@ type GroupResource struct {
142160
Resource string `json:"resource"`
143161
}
144162

163+
func (r GroupResource) String() string {
164+
return fmt.Sprintf("%s.%s", r.Resource, r.Group)
165+
}
166+
167+
// PermissionClaim selects objects of a GVR that a service provider may
168+
// request and that a consumer may accept and allow the service provider access to.
169+
type PermissionClaim struct {
170+
GroupResource `json:",inline"`
171+
172+
// Selector is a resource selector that selects objects of a GVR.
173+
Selector Selector `json:"selector,omitempty"`
174+
}
175+
176+
// Owner is the owner of the resource.
177+
type Owner string
178+
179+
const (
180+
// OwnerProvider indicates that the resource is owned by the provider.
181+
OwnerProvider Owner = "provider"
182+
// OwnerConsumer indicates that the resource is owned by the consumer.
183+
OwnerConsumer Owner = "consumer"
184+
)
185+
186+
func (o Owner) String() string {
187+
return string(o)
188+
}
189+
145190
// APIServiceExportRequestPhase describes the phase of a binding request.
146191
type APIServiceExportRequestPhase string
147192

sdk/apis/kubebind/v1alpha2/boundchema_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package v1alpha2
1818

1919
import (
2020
"encoding/json"
21+
"fmt"
2122

2223
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2324
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -41,6 +42,13 @@ type BoundSchema struct {
4142
Status BoundSchemaStatus `json:"status,omitempty"`
4243
}
4344

45+
// ResourceGroupName returns the group name of the resource.
46+
//
47+
// Important: If you change this, change one for APIServiceExportRequestResource too.
48+
func (b *BoundSchema) ResourceGroupName() string {
49+
return fmt.Sprintf("%s.%s", b.Spec.Names.Plural, b.Spec.Group)
50+
}
51+
4452
// InformerScope is the scope of the Api.
4553
//
4654
// +kubebuilder:validation:Enum=Cluster;Namespaced
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright 2025 The Kube Bind Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha2
18+
19+
import (
20+
"fmt"
21+
22+
corev1 "k8s.io/api/core/v1"
23+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
24+
"k8s.io/apimachinery/pkg/runtime"
25+
"k8s.io/apimachinery/pkg/runtime/schema"
26+
)
27+
28+
// InternalAPI describes an API to be imported from some schemes and generated OpenAPI V2 definitions.
29+
type InternalAPI struct {
30+
Names apiextensionsv1.CustomResourceDefinitionNames
31+
GroupVersionResource schema.GroupVersionResource
32+
Instance runtime.Object
33+
ResourceScope apiextensionsv1.ResourceScope
34+
HasStatus bool
35+
}
36+
37+
// ClaimableAPIs is a list of APIs that can be claimed by a user.
38+
var ClaimableAPIs = []InternalAPI{
39+
{
40+
Names: apiextensionsv1.CustomResourceDefinitionNames{
41+
Plural: "configmaps",
42+
Singular: "configmap",
43+
Kind: "ConfigMap",
44+
},
45+
GroupVersionResource: schema.GroupVersionResource{
46+
Group: "",
47+
Version: "v1",
48+
Resource: "configmaps",
49+
},
50+
Instance: &corev1.ConfigMap{},
51+
ResourceScope: apiextensionsv1.NamespaceScoped,
52+
},
53+
{
54+
Names: apiextensionsv1.CustomResourceDefinitionNames{
55+
Plural: "secrets",
56+
Singular: "secret",
57+
Kind: "Secret",
58+
},
59+
GroupVersionResource: schema.GroupVersionResource{
60+
Group: "",
61+
Version: "v1",
62+
Resource: "secrets",
63+
},
64+
Instance: &corev1.Secret{},
65+
ResourceScope: apiextensionsv1.NamespaceScoped,
66+
},
67+
{
68+
Names: apiextensionsv1.CustomResourceDefinitionNames{
69+
Plural: "serviceaccounts",
70+
Singular: "serviceaccount",
71+
Kind: "ServiceAccount",
72+
},
73+
GroupVersionResource: schema.GroupVersionResource{
74+
Group: "",
75+
Version: "v1",
76+
Resource: "serviceaccounts",
77+
},
78+
Instance: &corev1.ServiceAccount{},
79+
ResourceScope: apiextensionsv1.NamespaceScoped,
80+
},
81+
}
82+
83+
func ResolveClaimableAPI(claim PermissionClaim) (schema.GroupVersionResource, error) {
84+
for _, api := range ClaimableAPIs {
85+
if api.Names.Plural == claim.Resource && api.GroupVersionResource.Group == claim.Group {
86+
return api.GroupVersionResource, nil
87+
}
88+
}
89+
return schema.GroupVersionResource{}, fmt.Errorf("no matching API found")
90+
}

sdk/apis/kubebind/v1alpha2/zz_generated.deepcopy.go

Lines changed: 83 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)