Added support for about-api for cluster properties (#1006)
Some checks failed
Post / coverage (push) Failing after 33m23s
Post / images (amd64) (push) Failing after 8m28s
Post / images (arm64) (push) Failing after 7m59s
Post / image manifest (push) Has been skipped
Post / trigger clusteradm e2e (push) Has been skipped
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1m20s
Close stale issues and PRs / stale (push) Successful in 57s

* Added support for about-api for cluster properties

Signed-off-by: gnana997 <gnana097@gmail.com>

* refactored failing registration test cases

Signed-off-by: gnana997 <gnana097@gmail.com>

* Added new fake classes and test cases

Signed-off-by: gnana997 <gnana097@gmail.com>

* Refactored test cases and vendors

Signed-off-by: gnana997 <gnana097@gmail.com>

* updated the open-cluster api package and updated cluster property

Signed-off-by: gnana997 <gnana097@gmail.com>

* Refactored the pr with just registration details and crds

Signed-off-by: gnana997 <gnana097@gmail.com>

* Fix fake client

Signed-off-by: Jian Qiu <jqiu@redhat.com>

* Add integration test for clusterproperty

Signed-off-by: Jian Qiu <jqiu@redhat.com>

---------

Signed-off-by: gnana997 <gnana097@gmail.com>
Signed-off-by: Jian Qiu <jqiu@redhat.com>
Co-authored-by: gnana997 <gnana097@gmail.com>
This commit is contained in:
Jian Qiu
2025-06-04 17:17:55 +08:00
committed by GitHub
parent 5bcfeca203
commit 8faa1b2327
39 changed files with 2410 additions and 40 deletions

1
go.mod
View File

@@ -39,6 +39,7 @@ require (
open-cluster-management.io/addon-framework v0.12.1-0.20250407131028-9d436ffc2da7
open-cluster-management.io/api v0.16.2-0.20250529024642-922ceaca4e66
open-cluster-management.io/sdk-go v0.16.1-0.20250428032116-875454003818
sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03
sigs.k8s.io/cluster-inventory-api v0.0.0-20240730014211-ef0154379848
sigs.k8s.io/controller-runtime v0.20.2
sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96

2
go.sum
View File

@@ -491,6 +491,8 @@ open-cluster-management.io/api v0.16.2-0.20250529024642-922ceaca4e66 h1:al0mUH6t
open-cluster-management.io/api v0.16.2-0.20250529024642-922ceaca4e66/go.mod h1:/OeqXycNBZQoe3WG6ghuWsMgsKGuMZrK8ZpsU6gWL0Y=
open-cluster-management.io/sdk-go v0.16.1-0.20250428032116-875454003818 h1:b7HpdTpKPzLEoJ5UtrXCed1PjxaKOxEboJ+kG6FZudI=
open-cluster-management.io/sdk-go v0.16.1-0.20250428032116-875454003818/go.mod h1:n89YVVoi5zm3KVpOyVMmTdD4rGOVSsykUtu7Ol3do3M=
sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03 h1:1ShFiMjGQOR/8jTBkmZrk1gORxnvMwm1nOy2/DbHg4U=
sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03/go.mod h1:F1pT4mK53U6F16/zuaPSYpBaR7x5Kjym6aKJJC0/DHU=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/cluster-inventory-api v0.0.0-20240730014211-ef0154379848 h1:WYPi2PdQyZwZkHG648v2jQl6deyCgyjJ0fkLYgUJ618=

View File

@@ -0,0 +1,62 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
api-approved.kubernetes.io: "https://github.com/kubernetes/enhancements/pull/3084"
name: clusterproperties.about.k8s.io
spec:
group: about.k8s.io
names:
kind: ClusterProperty
listKind: ClusterPropertyList
plural: clusterproperties
singular: clusterproperty
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .spec.value
name: value
type: string
- jsonPath: .metadata.creationTimestamp
name: age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: ClusterProperty is the Schema for the clusterproperties API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: ClusterPropertySpec defines the desired state of ClusterProperty
properties:
value:
description: ClusterProperty value
minLength: 1
type: string
required:
- value
type: object
status:
description: ClusterPropertyStatus defines the observed state of ClusterProperty
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -11,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/util/sets"
aboutv1alpha1listers "sigs.k8s.io/about-api/pkg/generated/listers/apis/v1alpha1"
clusterv1alpha1listers "open-cluster-management.io/api/client/cluster/listers/cluster/v1alpha1"
clusterv1 "open-cluster-management.io/api/cluster/v1"
@@ -25,14 +26,12 @@ const labelCustomizedOnly = "open-cluster-management.io/spoke-only"
type claimReconcile struct {
recorder events.Recorder
claimLister clusterv1alpha1listers.ClusterClaimLister
aboutLister aboutv1alpha1listers.ClusterPropertyLister
maxCustomClusterClaims int
reservedClusterClaimSuffixes []string
}
func (r *claimReconcile) reconcile(ctx context.Context, cluster *clusterv1.ManagedCluster) (*clusterv1.ManagedCluster, reconcileState, error) {
if !features.SpokeMutableFeatureGate.Enabled(ocmfeature.ClusterClaim) {
return cluster, reconcileContinue, nil
}
// current managed cluster has not joined the hub yet, do nothing.
if !meta.IsStatusConditionTrue(cluster.Status.Conditions, clusterv1.ManagedClusterConditionJoined) {
r.recorder.Eventf("ManagedClusterIsNotAccepted", "Managed cluster %q does not join the hub yet", cluster.Name)
@@ -46,31 +45,61 @@ func (r *claimReconcile) reconcile(ctx context.Context, cluster *clusterv1.Manag
// exposeClaims saves cluster claims fetched on managed cluster into status of the
// managed cluster on hub. Some of the customized claims might not be exposed once
// the total number of the claims exceeds the value of `cluster-claims-max`.
func (r *claimReconcile) exposeClaims(ctx context.Context, cluster *clusterv1.ManagedCluster) error {
func (r *claimReconcile) exposeClaims(_ context.Context, cluster *clusterv1.ManagedCluster) error {
var reservedClaims, customClaims []clusterv1.ManagedClusterClaim
var clusterClaims []*clusterv1alpha1.ClusterClaim
claimsMap := map[string]clusterv1.ManagedClusterClaim{}
// clusterClaim with label `open-cluster-management.io/spoke-only` will not be synced to managedCluster.Status at hub.
requirement, _ := labels.NewRequirement(labelCustomizedOnly, selection.DoesNotExist, []string{})
selector := labels.NewSelector().Add(*requirement)
clusterClaims, err := r.claimLister.List(selector)
requirement, err := labels.NewRequirement(labelCustomizedOnly, selection.DoesNotExist, []string{})
if err != nil {
return fmt.Errorf("unable to list cluster claims: %w", err)
return err
}
selector := labels.NewSelector().Add(*requirement)
if features.SpokeMutableFeatureGate.Enabled(ocmfeature.ClusterProperty) {
clusterProperties, err := r.aboutLister.List(selector)
if err != nil {
return fmt.Errorf("unable to list cluster properties: %w", err)
}
for _, property := range clusterProperties {
claimsMap[property.Name] = clusterv1.ManagedClusterClaim{
Name: property.Name,
Value: property.Spec.Value,
}
}
}
if features.SpokeMutableFeatureGate.Enabled(ocmfeature.ClusterClaim) {
clusterClaims, err = r.claimLister.List(selector)
if err != nil {
return fmt.Errorf("unable to list cluster claims: %w", err)
}
for _, claim := range clusterClaims {
// if the claim has the same name with the property, ignore it.
if _, ok := claimsMap[claim.Name]; !ok {
claimsMap[claim.Name] = clusterv1.ManagedClusterClaim{
Name: claim.Name,
Value: claim.Spec.Value,
}
}
}
}
// check if the cluster claim is one of the reserved claims or has a reserved suffix.
// if so, it will be treated as a reserved claim and will always be exposed.
reservedClaimNames := sets.New(clusterv1alpha1.ReservedClusterClaimNames[:]...)
reservedClaimSuffixes := sets.New(r.reservedClusterClaimSuffixes...)
for _, clusterClaim := range clusterClaims {
managedClusterClaim := clusterv1.ManagedClusterClaim{
Name: clusterClaim.Name,
Value: clusterClaim.Spec.Value,
}
for _, managedClusterClaim := range claimsMap {
if matchReservedClaims(reservedClaimNames, reservedClaimSuffixes, managedClusterClaim) {
reservedClaims = append(reservedClaims, managedClusterClaim)
// reservedClaimNames.Insert(managedClusterClaim.Name)
continue
}
customClaims = append(customClaims, managedClusterClaim)
}

View File

@@ -12,9 +12,11 @@ import (
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
kubeinformers "k8s.io/client-go/informers"
fakekube "k8s.io/client-go/kubernetes/fake"
kubefake "k8s.io/client-go/kubernetes/fake"
clienttesting "k8s.io/client-go/testing"
aboutv1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
aboutclusterfake "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/fake"
aboutinformers "sigs.k8s.io/about-api/pkg/generated/informers/externalversions"
clusterfake "open-cluster-management.io/api/client/cluster/clientset/versioned/fake"
clusterscheme "open-cluster-management.io/api/client/cluster/clientset/versioned/scheme"
@@ -37,6 +39,7 @@ func TestSync(t *testing.T) {
cases := []struct {
name string
cluster runtime.Object
properties []runtime.Object
claims []runtime.Object
validateActions func(t *testing.T, actions []clienttesting.Action)
expectedErr string
@@ -55,6 +58,16 @@ func TestSync(t *testing.T) {
{
name: "sync a joined managed cluster",
cluster: testinghelpers.NewJoinedManagedCluster(),
properties: []runtime.Object{
&aboutv1alpha1.ClusterProperty{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "test",
},
},
},
claims: []runtime.Object{
&clusterv1alpha1.ClusterClaim{
ObjectMeta: metav1.ObjectMeta{
@@ -78,6 +91,65 @@ func TestSync(t *testing.T) {
Name: "a",
Value: "b",
},
{
Name: "name",
Value: "test",
},
}
actual := cluster.Status.ClusterClaims
if !reflect.DeepEqual(actual, expected) {
t.Errorf("expected cluster claim %v but got: %v", expected, actual)
}
},
},
{
name: "sync a joined managed cluster with same property and claims",
cluster: testinghelpers.NewJoinedManagedCluster(),
properties: []runtime.Object{
&aboutv1alpha1.ClusterProperty{
ObjectMeta: metav1.ObjectMeta{
Name: "key1",
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "value1",
},
},
&aboutv1alpha1.ClusterProperty{
ObjectMeta: metav1.ObjectMeta{
Name: "key2",
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "value2",
},
},
},
claims: []runtime.Object{
&clusterv1alpha1.ClusterClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "key1",
},
Spec: clusterv1alpha1.ClusterClaimSpec{
Value: "value3",
},
},
},
validateActions: func(t *testing.T, actions []clienttesting.Action) {
testingcommon.AssertActions(t, actions, "patch")
patch := actions[0].(clienttesting.PatchAction).GetPatch()
cluster := &clusterv1.ManagedCluster{}
err := json.Unmarshal(patch, cluster)
if err != nil {
t.Fatal(err)
}
expected := []clusterv1.ManagedClusterClaim{
{
Name: "key1",
Value: "value1",
},
{
Name: "key2",
Value: "value2",
},
}
actual := cluster.Status.ClusterClaims
if !reflect.DeepEqual(actual, expected) {
@@ -89,8 +161,12 @@ func TestSync(t *testing.T) {
apiServer, discoveryClient := newDiscoveryServer(t, nil)
defer apiServer.Close()
kubeClient := kubefake.NewSimpleClientset()
kubeClient := kubefake.NewClientset()
kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Minute*10)
err := features.SpokeMutableFeatureGate.Set("ClusterProperty=true")
if err != nil {
t.Fatal(err)
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
@@ -100,6 +176,8 @@ func TestSync(t *testing.T) {
}
clusterClient := clusterfake.NewSimpleClientset(objects...)
aboutClusterClient := aboutclusterfake.NewSimpleClientset()
clusterPropertyInformerFactory := aboutinformers.NewSharedInformerFactory(aboutClusterClient, time.Minute*10)
clusterInformerFactory := clusterinformers.NewSharedInformerFactory(clusterClient, time.Minute*10)
if c.cluster != nil {
if err := clusterInformerFactory.Cluster().V1().ManagedClusters().Informer().GetStore().Add(c.cluster); err != nil {
@@ -113,7 +191,13 @@ func TestSync(t *testing.T) {
}
}
fakeHubClient := fakekube.NewSimpleClientset()
for _, property := range c.properties {
if err := clusterPropertyInformerFactory.About().V1alpha1().ClusterProperties().Informer().GetStore().Add(property); err != nil {
t.Fatal(err)
}
}
fakeHubClient := kubefake.NewClientset()
ctx := context.TODO()
hubEventRecorder, err := helpers.NewEventRecorder(ctx,
clusterscheme.Scheme, fakeHubClient.EventsV1(), "test")
@@ -126,6 +210,7 @@ func TestSync(t *testing.T) {
clusterInformerFactory.Cluster().V1().ManagedClusters(),
discoveryClient,
clusterInformerFactory.Cluster().V1alpha1().ClusterClaims(),
clusterPropertyInformerFactory.About().V1alpha1().ClusterProperties(),
kubeInformerFactory.Core().V1().Nodes(),
20,
[]string{},
@@ -146,20 +231,21 @@ func TestExposeClaims(t *testing.T) {
name string
cluster *clusterv1.ManagedCluster
claims []*clusterv1alpha1.ClusterClaim
properties []*aboutv1alpha1.ClusterProperty
maxCustomClusterClaims int
reservedClusterClaimSuffixes []string
validateActions func(t *testing.T, actions []clienttesting.Action)
expectedErr string
}{
{
name: "sync claims into status of the managed cluster",
name: "sync properties into status of the managed cluster",
cluster: testinghelpers.NewJoinedManagedCluster(),
claims: []*clusterv1alpha1.ClusterClaim{
properties: []*aboutv1alpha1.ClusterProperty{
{
ObjectMeta: metav1.ObjectMeta{
Name: "a",
},
Spec: clusterv1alpha1.ClusterClaimSpec{
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "b",
},
},
@@ -359,6 +445,48 @@ func TestExposeClaims(t *testing.T) {
}
},
},
{
name: "sync non-customized-only properties into status of the managed cluster",
cluster: testinghelpers.NewJoinedManagedCluster(),
properties: []*aboutv1alpha1.ClusterProperty{
{
ObjectMeta: metav1.ObjectMeta{
Name: "a",
Labels: map[string]string{labelCustomizedOnly: ""},
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "b",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "c",
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "d",
},
},
},
validateActions: func(t *testing.T, actions []clienttesting.Action) {
testingcommon.AssertActions(t, actions, "patch")
patch := actions[0].(clienttesting.PatchAction).GetPatch()
cluster := &clusterv1.ManagedCluster{}
err := json.Unmarshal(patch, cluster)
if err != nil {
t.Fatal(err)
}
expected := []clusterv1.ManagedClusterClaim{
{
Name: "c",
Value: "d",
},
}
actual := cluster.Status.ClusterClaims
if !reflect.DeepEqual(actual, expected) {
t.Errorf("expected cluster claim %v but got: %v", expected, actual)
}
},
},
{
name: "sync non-customized-only claims into status of the managed cluster",
cluster: testinghelpers.NewJoinedManagedCluster(),
@@ -405,8 +533,12 @@ func TestExposeClaims(t *testing.T) {
apiServer, discoveryClient := newDiscoveryServer(t, nil)
defer apiServer.Close()
kubeClient := kubefake.NewSimpleClientset()
kubeClient := kubefake.NewClientset()
kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Minute*10)
err := features.SpokeMutableFeatureGate.Set("ClusterProperty=true")
if err != nil {
t.Fatal(err)
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
@@ -416,6 +548,8 @@ func TestExposeClaims(t *testing.T) {
}
clusterClient := clusterfake.NewSimpleClientset(objects...)
aboutClusterClient := aboutclusterfake.NewSimpleClientset()
clusterPropertyInformerFactory := aboutinformers.NewSharedInformerFactory(aboutClusterClient, time.Minute*10)
clusterInformerFactory := clusterinformers.NewSharedInformerFactory(clusterClient, time.Minute*10)
if c.cluster != nil {
if err := clusterInformerFactory.Cluster().V1().ManagedClusters().Informer().GetStore().Add(c.cluster); err != nil {
@@ -429,11 +563,17 @@ func TestExposeClaims(t *testing.T) {
}
}
for _, property := range c.properties {
if err := clusterPropertyInformerFactory.About().V1alpha1().ClusterProperties().Informer().GetStore().Add(property); err != nil {
t.Fatal(err)
}
}
if c.maxCustomClusterClaims == 0 {
c.maxCustomClusterClaims = 20
}
fakeHubClient := fakekube.NewSimpleClientset()
fakeHubClient := kubefake.NewClientset()
ctx := context.TODO()
hubEventRecorder, err := helpers.NewEventRecorder(ctx,
clusterscheme.Scheme, fakeHubClient.EventsV1(), "test")
@@ -446,6 +586,7 @@ func TestExposeClaims(t *testing.T) {
clusterInformerFactory.Cluster().V1().ManagedClusters(),
discoveryClient,
clusterInformerFactory.Cluster().V1alpha1().ClusterClaims(),
clusterPropertyInformerFactory.About().V1alpha1().ClusterProperties(),
kubeInformerFactory.Core().V1().Nodes(),
c.maxCustomClusterClaims,
c.reservedClusterClaimSuffixes,

View File

@@ -13,6 +13,8 @@ import (
fakekube "k8s.io/client-go/kubernetes/fake"
kubefake "k8s.io/client-go/kubernetes/fake"
clienttesting "k8s.io/client-go/testing"
aboutclusterfake "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/fake"
aboutinformers "sigs.k8s.io/about-api/pkg/generated/informers/externalversions"
clusterfake "open-cluster-management.io/api/client/cluster/clientset/versioned/fake"
clusterscheme "open-cluster-management.io/api/client/cluster/clientset/versioned/scheme"
@@ -73,6 +75,8 @@ func TestSyncManagedCluster(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
clusterClient := clusterfake.NewSimpleClientset(c.startingObjects...)
aboutClusterClient := aboutclusterfake.NewSimpleClientset()
clusterPropertyInformerFactory := aboutinformers.NewSharedInformerFactory(aboutClusterClient, time.Minute*10)
clusterInformerFactory := clusterinformers.NewSharedInformerFactory(clusterClient, time.Minute*10)
clusterStore := clusterInformerFactory.Cluster().V1().ManagedClusters().Informer().GetStore()
for _, cluster := range c.startingObjects {
@@ -94,6 +98,7 @@ func TestSyncManagedCluster(t *testing.T) {
clusterInformerFactory.Cluster().V1().ManagedClusters(),
discoveryClient,
clusterInformerFactory.Cluster().V1alpha1().ClusterClaims(),
clusterPropertyInformerFactory.About().V1alpha1().ClusterProperties(),
kubeInformerFactory.Core().V1().Nodes(),
20,
[]string{},

View File

@@ -19,6 +19,8 @@ import (
kubefake "k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/rest"
clienttesting "k8s.io/client-go/testing"
aboutclusterfake "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/fake"
aboutinformers "sigs.k8s.io/about-api/pkg/generated/informers/externalversions"
clusterfake "open-cluster-management.io/api/client/cluster/clientset/versioned/fake"
clusterscheme "open-cluster-management.io/api/client/cluster/clientset/versioned/scheme"
@@ -294,6 +296,8 @@ func TestHealthCheck(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
clusterClient := clusterfake.NewSimpleClientset(c.clusters...)
aboutClusterClient := aboutclusterfake.NewSimpleClientset()
clusterPropertyInformerFactory := aboutinformers.NewSharedInformerFactory(aboutClusterClient, time.Minute*10)
clusterInformerFactory := clusterinformers.NewSharedInformerFactory(clusterClient, time.Minute*10)
clusterStore := clusterInformerFactory.Cluster().V1().ManagedClusters().Informer().GetStore()
for _, cluster := range c.clusters {
@@ -328,6 +332,7 @@ func TestHealthCheck(t *testing.T) {
clusterInformerFactory.Cluster().V1().ManagedClusters(),
discoveryClient,
clusterInformerFactory.Cluster().V1alpha1().ClusterClaims(),
clusterPropertyInformerFactory.About().V1alpha1().ClusterProperties(),
kubeInformerFactory.Core().V1().Nodes(),
20,
[]string{},

View File

@@ -14,13 +14,17 @@ import (
"k8s.io/client-go/discovery"
corev1informers "k8s.io/client-go/informers/core/v1"
kevents "k8s.io/client-go/tools/events"
aboutv1alpha1informer "sigs.k8s.io/about-api/pkg/generated/informers/externalversions/apis/v1alpha1"
clientset "open-cluster-management.io/api/client/cluster/clientset/versioned"
clusterv1informer "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1"
clusterv1alpha1informer "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1alpha1"
clusterv1listers "open-cluster-management.io/api/client/cluster/listers/cluster/v1"
clusterv1 "open-cluster-management.io/api/cluster/v1"
ocmfeature "open-cluster-management.io/api/feature"
"open-cluster-management.io/sdk-go/pkg/patcher"
"open-cluster-management.io/ocm/pkg/features"
)
// managedClusterStatusController checks the kube-apiserver health on managed cluster to determine it whether is available
@@ -52,6 +56,7 @@ func NewManagedClusterStatusController(
hubClusterInformer clusterv1informer.ManagedClusterInformer,
managedClusterDiscoveryClient discovery.DiscoveryInterface,
claimInformer clusterv1alpha1informer.ClusterClaimInformer,
propertyInformer aboutv1alpha1informer.ClusterPropertyInformer,
nodeInformer corev1informers.NodeInformer,
maxCustomClusterClaims int,
reservedClusterClaimSuffixes []string,
@@ -64,6 +69,7 @@ func NewManagedClusterStatusController(
hubClusterInformer,
managedClusterDiscoveryClient,
claimInformer,
propertyInformer,
nodeInformer,
maxCustomClusterClaims,
reservedClusterClaimSuffixes,
@@ -71,11 +77,18 @@ func NewManagedClusterStatusController(
hubEventRecorder,
)
return factory.New().
WithInformers(hubClusterInformer.Informer(), nodeInformer.Informer(), claimInformer.Informer()).
WithSync(c.sync).
ResyncEvery(resyncInterval).
ToController("ManagedClusterStatusController", recorder)
controllerFactory := factory.New().
WithInformers(hubClusterInformer.Informer(), nodeInformer.Informer()).
WithSync(c.sync).ResyncEvery(resyncInterval)
if features.SpokeMutableFeatureGate.Enabled(ocmfeature.ClusterClaim) {
controllerFactory = controllerFactory.WithInformers(claimInformer.Informer())
}
if features.SpokeMutableFeatureGate.Enabled(ocmfeature.ClusterProperty) {
controllerFactory = controllerFactory.WithInformers(propertyInformer.Informer())
}
return controllerFactory.ToController("ManagedClusterStatusController", recorder)
}
func newManagedClusterStatusController(
@@ -84,6 +97,7 @@ func newManagedClusterStatusController(
hubClusterInformer clusterv1informer.ManagedClusterInformer,
managedClusterDiscoveryClient discovery.DiscoveryInterface,
claimInformer clusterv1alpha1informer.ClusterClaimInformer,
propertyInformer aboutv1alpha1informer.ClusterPropertyInformer,
nodeInformer corev1informers.NodeInformer,
maxCustomClusterClaims int,
reservedClusterClaimSuffixes []string,
@@ -98,7 +112,10 @@ func newManagedClusterStatusController(
&joiningReconcile{recorder: recorder},
&resoureReconcile{managedClusterDiscoveryClient: managedClusterDiscoveryClient, nodeLister: nodeInformer.Lister()},
&claimReconcile{claimLister: claimInformer.Lister(), recorder: recorder,
maxCustomClusterClaims: maxCustomClusterClaims, reservedClusterClaimSuffixes: reservedClusterClaimSuffixes},
maxCustomClusterClaims: maxCustomClusterClaims,
reservedClusterClaimSuffixes: reservedClusterClaimSuffixes,
aboutLister: propertyInformer.Lister(),
},
},
hubClusterLister: hubClusterInformer.Lister(),
hubEventRecorder: hubEventRecorder,
@@ -131,7 +148,7 @@ func (c *managedClusterStatusController) sync(ctx context.Context, syncCtx facto
outOfSynced := meta.IsStatusConditionFalse(newCluster.Status.Conditions, clusterv1.ManagedClusterConditionClockSynced)
if outOfSynced {
c.recorder.Eventf("ClockOutOfSync", "The managed cluster's clock is out of sync, the agent will not be able to update the status of managed cluster.")
return fmt.Errorf("the managed cluster's clock is out of sync, the agent will not be able to update the status of managed cluster.")
return fmt.Errorf("the managed cluster's clock is out of sync, the agent will not be able to update the status of managed cluster")
}
changed, err := c.patcher.PatchStatus(ctx, newCluster, newCluster.Status, cluster.Status)
@@ -168,5 +185,4 @@ func (c *managedClusterStatusController) sendAvailableConditionEvent(
c.hubEventRecorder.Eventf(newCluster, nil, corev1.EventTypeWarning, "Unavailable", "Unavailable",
"The %s is successfully imported. However, its Kube API server is unavailable", cluster.Name)
}
}

View File

@@ -15,6 +15,8 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
aboutclient "sigs.k8s.io/about-api/pkg/generated/clientset/versioned"
aboutinformers "sigs.k8s.io/about-api/pkg/generated/informers/externalversions"
clusterv1client "open-cluster-management.io/api/client/cluster/clientset/versioned"
clusterscheme "open-cluster-management.io/api/client/cluster/clientset/versioned/scheme"
@@ -129,6 +131,11 @@ func (o *SpokeAgentConfig) RunSpokeAgent(ctx context.Context, controllerContext
return err
}
aboutClusterClient, err := aboutclient.NewForConfig(spokeClientConfig)
if err != nil {
return err
}
return o.RunSpokeAgentWithSpokeInformers(
ctx,
kubeConfig,
@@ -136,6 +143,7 @@ func (o *SpokeAgentConfig) RunSpokeAgent(ctx context.Context, controllerContext
spokeKubeClient,
informers.NewSharedInformerFactory(spokeKubeClient, 10*time.Minute),
clusterv1informers.NewSharedInformerFactory(spokeClusterClient, 10*time.Minute),
aboutinformers.NewSharedInformerFactory(aboutClusterClient, 10*time.Minute),
controllerContext.EventRecorder,
)
}
@@ -145,6 +153,7 @@ func (o *SpokeAgentConfig) RunSpokeAgentWithSpokeInformers(ctx context.Context,
spokeKubeClient kubernetes.Interface,
spokeKubeInformerFactory informers.SharedInformerFactory,
spokeClusterInformerFactory clusterv1informers.SharedInformerFactory,
aboutInformers aboutinformers.SharedInformerFactory,
recorder events.Recorder) error {
logger := klog.FromContext(ctx)
logger.Info("Cluster name and agent ID", "clusterName", o.agentOptions.SpokeClusterName, "agentID", o.agentOptions.AgentID)
@@ -356,6 +365,7 @@ func (o *SpokeAgentConfig) RunSpokeAgentWithSpokeInformers(ctx context.Context,
hubClient.ClusterInformer,
spokeKubeClient.Discovery(),
spokeClusterInformerFactory.Cluster().V1alpha1().ClusterClaims(),
aboutInformers.About().V1alpha1().ClusterProperties(),
spokeKubeInformerFactory.Core().V1().Nodes(),
o.registrationOption.MaxCustomClusterClaims,
o.registrationOption.ReservedClusterClaimSuffixes,
@@ -431,6 +441,10 @@ func (o *SpokeAgentConfig) RunSpokeAgentWithSpokeInformers(ctx context.Context,
go spokeClusterInformerFactory.Start(ctx.Done())
}
if features.SpokeMutableFeatureGate.Enabled(ocmfeature.ClusterProperty) {
go aboutInformers.Start(ctx.Done())
}
go secretController.Run(ctx, 1)
go managedClusterLeaseController.Run(ctx, 1)
go managedClusterHealthCheckController.Run(ctx, 1)

View File

@@ -79,6 +79,7 @@ var CRDPaths = []string{
"./vendor/open-cluster-management.io/api/cluster/v1alpha1/0000_02_clusters.open-cluster-management.io_clusterclaims.crd.yaml",
// external API deps
"./test/integration/testdeps/capi/cluster.x-k8s.io_clusters.yaml",
"./manifests/klusterlet/managed/clusterproperties.crd.yaml",
}
func runAgent(name string, opt *spoke.SpokeAgentOptions, commOption *commonoptions.AgentOptions, cfg *rest.Config) context.CancelFunc {

View File

@@ -12,12 +12,15 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/rand"
aboutv1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
aboutclient "sigs.k8s.io/about-api/pkg/generated/clientset/versioned"
clusterv1 "open-cluster-management.io/api/cluster/v1"
clusterv1alpha1 "open-cluster-management.io/api/cluster/v1alpha1"
commonhelpers "open-cluster-management.io/ocm/pkg/common/helpers"
commonoptions "open-cluster-management.io/ocm/pkg/common/options"
"open-cluster-management.io/ocm/pkg/features"
registerfactory "open-cluster-management.io/ocm/pkg/registration/register/factory"
"open-cluster-management.io/ocm/pkg/registration/spoke"
"open-cluster-management.io/ocm/test/integration/util"
@@ -37,14 +40,6 @@ var _ = ginkgo.Describe("Cluster Claim", func() {
hubKubeconfigSecret = fmt.Sprintf("hub-kubeconfig-secret-%s", suffix)
hubKubeconfigDir = path.Join(util.TestDir, fmt.Sprintf("claimtest-%s", suffix), "hub-kubeconfig")
// delete all existing claims
claimList, err := clusterClient.ClusterV1alpha1().ClusterClaims().List(context.TODO(), metav1.ListOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
for _, claim := range claimList.Items {
err = clusterClient.ClusterV1alpha1().ClusterClaims().Delete(context.TODO(), claim.Name, metav1.DeleteOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
}
// create claims
for _, claim := range claims {
_, err = clusterClient.ClusterV1alpha1().ClusterClaims().Create(context.TODO(), claim, metav1.CreateOptions{})
@@ -64,12 +59,14 @@ var _ = ginkgo.Describe("Cluster Claim", func() {
commOptions.HubKubeconfigDir = hubKubeconfigDir
commOptions.SpokeClusterName = managedClusterName
cancel = runAgent("claimtest", agentOptions, commOptions, spokeCfg)
})
ginkgo.AfterEach(
func() {
ginkgo.DeferCleanup(func() {
err = clusterClient.ClusterV1alpha1().ClusterClaims().DeleteCollection(
context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
cancel()
})
})
assertSuccessBootstrap := func() {
// the spoke cluster and csr should be created after bootstrap
@@ -243,6 +240,215 @@ var _ = ginkgo.Describe("Cluster Claim", func() {
})
})
ginkgo.Context("Sync all clusterproperties", func() {
var aboutClient aboutclient.Interface
var err error
var properties []*aboutv1alpha1.ClusterProperty
ginkgo.BeforeEach(func() {
maxCustomClusterClaims = 20
claims = []*clusterv1alpha1.ClusterClaim{}
properties = []*aboutv1alpha1.ClusterProperty{
{
ObjectMeta: metav1.ObjectMeta{
Name: "property1",
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "value1",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "property2",
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "value2",
},
},
}
aboutClient, err = aboutclient.NewForConfig(spokeCfg)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
for _, prop := range properties {
_, err = aboutClient.AboutV1alpha1().ClusterProperties().Create(
context.Background(), prop, metav1.CreateOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
}
err = features.SpokeMutableFeatureGate.Set("ClusterProperty=true")
gomega.Expect(err).NotTo(gomega.HaveOccurred())
ginkgo.DeferCleanup(func() {
err := aboutClient.AboutV1alpha1().ClusterProperties().DeleteCollection(
context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
err = features.SpokeMutableFeatureGate.Set("ClusterProperty=false")
gomega.Expect(err).NotTo(gomega.HaveOccurred())
})
})
ginkgo.It("should sync all cluster properties on spoke to status of ManagedCluster", func() {
assertSuccessBootstrap()
ginkgo.By("Sync existing clusterproperty")
var clusterClaims []clusterv1.ManagedClusterClaim
for _, claim := range properties {
clusterClaims = append(clusterClaims, clusterv1.ManagedClusterClaim{
Name: claim.Name,
Value: claim.Spec.Value,
})
}
gomega.Eventually(func() error {
spokeCluster, err := util.GetManagedCluster(clusterClient, managedClusterName)
if err != nil {
return err
}
if !reflect.DeepEqual(clusterClaims, spokeCluster.Status.ClusterClaims) {
return fmt.Errorf("cluster claims are not equal, got %v", spokeCluster.Status.ClusterClaims)
}
return nil
}, eventuallyTimeout, eventuallyInterval).Should(gomega.Succeed())
ginkgo.By("Create a new clusterproperty")
newProperty := &aboutv1alpha1.ClusterProperty{
ObjectMeta: metav1.ObjectMeta{
Name: "property3",
},
Spec: aboutv1alpha1.ClusterPropertySpec{
Value: "value3",
},
}
newProperty, err = aboutClient.AboutV1alpha1().ClusterProperties().Create(context.TODO(), newProperty, metav1.CreateOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
var newClusterClaims []clusterv1.ManagedClusterClaim
newClusterClaims = append(newClusterClaims, clusterClaims...)
newClusterClaims = append(newClusterClaims, clusterv1.ManagedClusterClaim{
Name: newProperty.Name,
Value: newProperty.Spec.Value,
})
gomega.Eventually(func() error {
spokeCluster, err := util.GetManagedCluster(clusterClient, managedClusterName)
if err != nil {
return err
}
if !reflect.DeepEqual(newClusterClaims, spokeCluster.Status.ClusterClaims) {
return fmt.Errorf("cluster claims are not equal, got %v", spokeCluster.Status.ClusterClaims)
}
return nil
}, eventuallyTimeout, eventuallyInterval).Should(gomega.Succeed())
ginkgo.By("Update the property")
newProperty.Spec.Value = "Z"
_, err := aboutClient.AboutV1alpha1().ClusterProperties().Update(context.TODO(), newProperty, metav1.UpdateOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
var updatedClusterClaims []clusterv1.ManagedClusterClaim
updatedClusterClaims = append(updatedClusterClaims, clusterClaims...)
updatedClusterClaims = append(updatedClusterClaims, clusterv1.ManagedClusterClaim{
Name: newProperty.Name,
Value: newProperty.Spec.Value,
})
gomega.Eventually(func() error {
spokeCluster, err := util.GetManagedCluster(clusterClient, managedClusterName)
if err != nil {
return err
}
if !reflect.DeepEqual(updatedClusterClaims, spokeCluster.Status.ClusterClaims) {
return fmt.Errorf("cluster claims are not equal, got %v", spokeCluster.Status.ClusterClaims)
}
return nil
}, eventuallyTimeout, eventuallyInterval).Should(gomega.Succeed())
ginkgo.By("Delete the property")
err = aboutClient.AboutV1alpha1().ClusterProperties().Delete(context.TODO(), newProperty.Name, metav1.DeleteOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Eventually(func() error {
spokeCluster, err := util.GetManagedCluster(clusterClient, managedClusterName)
if err != nil {
return err
}
if !reflect.DeepEqual(clusterClaims, spokeCluster.Status.ClusterClaims) {
return fmt.Errorf("cluster claims are not equal, got %v", spokeCluster.Status.ClusterClaims)
}
return nil
}, eventuallyTimeout, eventuallyInterval).Should(gomega.Succeed())
})
ginkgo.It("should sync all both properties and claims", func() {
assertSuccessBootstrap()
var clusterClaims []clusterv1.ManagedClusterClaim
for _, claim := range properties {
clusterClaims = append(clusterClaims, clusterv1.ManagedClusterClaim{
Name: claim.Name,
Value: claim.Spec.Value,
})
}
ginkgo.By("Create a new claim")
newClaim := &clusterv1alpha1.ClusterClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "c",
},
Spec: clusterv1alpha1.ClusterClaimSpec{
Value: "z",
},
}
newClaim, err = clusterClient.ClusterV1alpha1().ClusterClaims().Create(context.TODO(), newClaim, metav1.CreateOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
var updatedClusterClaims []clusterv1.ManagedClusterClaim
updatedClusterClaims = append(updatedClusterClaims, clusterv1.ManagedClusterClaim{
Name: newClaim.Name,
Value: newClaim.Spec.Value,
})
updatedClusterClaims = append(updatedClusterClaims, clusterClaims...)
gomega.Eventually(func() error {
spokeCluster, err := util.GetManagedCluster(clusterClient, managedClusterName)
if err != nil {
return err
}
if !reflect.DeepEqual(updatedClusterClaims, spokeCluster.Status.ClusterClaims) {
return fmt.Errorf("cluster claims are not equal, got %v", spokeCluster.Status.ClusterClaims)
}
return nil
}, eventuallyTimeout, eventuallyInterval).Should(gomega.Succeed())
ginkgo.By("create a claim with the same key")
updateProperty, err := aboutClient.AboutV1alpha1().ClusterProperties().Get(
context.TODO(), "property1", metav1.GetOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
updateProperty.Spec.Value = "newValue"
_, err = aboutClient.AboutV1alpha1().ClusterProperties().Update(context.TODO(), updateProperty, metav1.UpdateOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
newClaim = &clusterv1alpha1.ClusterClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "property1",
},
Spec: clusterv1alpha1.ClusterClaimSpec{
Value: "value1",
},
}
newClaim, err = clusterClient.ClusterV1alpha1().ClusterClaims().Create(context.TODO(), newClaim, metav1.CreateOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
updatedClusterClaims[1].Value = "newValue"
gomega.Eventually(func() error {
spokeCluster, err := util.GetManagedCluster(clusterClient, managedClusterName)
if err != nil {
return err
}
if !reflect.DeepEqual(updatedClusterClaims, spokeCluster.Status.ClusterClaims) {
return fmt.Errorf("cluster claims are not equal, got %v", spokeCluster.Status.ClusterClaims)
}
return nil
}, eventuallyTimeout, eventuallyInterval).Should(gomega.Succeed())
})
})
ginkgo.Context("Truncate exposed claims", func() {
ginkgo.BeforeEach(func() {
maxCustomClusterClaims = 5

13
vendor/modules.txt vendored
View File

@@ -1822,6 +1822,19 @@ open-cluster-management.io/sdk-go/pkg/cloudevents/generic/payload
open-cluster-management.io/sdk-go/pkg/cloudevents/generic/types
open-cluster-management.io/sdk-go/pkg/helpers
open-cluster-management.io/sdk-go/pkg/patcher
# sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03
## explicit; go 1.22
sigs.k8s.io/about-api/pkg/apis/v1alpha1
sigs.k8s.io/about-api/pkg/generated/clientset/versioned
sigs.k8s.io/about-api/pkg/generated/clientset/versioned/fake
sigs.k8s.io/about-api/pkg/generated/clientset/versioned/scheme
sigs.k8s.io/about-api/pkg/generated/clientset/versioned/typed/apis/v1alpha1
sigs.k8s.io/about-api/pkg/generated/clientset/versioned/typed/apis/v1alpha1/fake
sigs.k8s.io/about-api/pkg/generated/informers/externalversions
sigs.k8s.io/about-api/pkg/generated/informers/externalversions/apis
sigs.k8s.io/about-api/pkg/generated/informers/externalversions/apis/v1alpha1
sigs.k8s.io/about-api/pkg/generated/informers/externalversions/internalinterfaces
sigs.k8s.io/about-api/pkg/generated/listers/apis/v1alpha1
# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0
## explicit; go 1.21
sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client

201
vendor/sigs.k8s.io/about-api/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,59 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
//+genclient
//+genclient:nonNamespaced
//+kubebuilder:object:root=true
//+kubebuilder:resource:scope=Cluster
//+kubebuilder:printcolumn:name="value",type=string,JSONPath=`.spec.value`
//+kubebuilder:printcolumn:name="age",type=date,JSONPath=`.metadata.creationTimestamp`
// ClusterProperty is a resource provides a way to store identification related,
// cluster scoped information for multi-cluster tools while creating flexibility
// for implementations.
type ClusterProperty struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec represents the desired behavior.
// +required
Spec ClusterPropertySpec `json:"spec"`
}
// ClusterPropertySpec defines the desired state of ClusterProperty.
type ClusterPropertySpec struct {
// Value is the property-dependent string.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Maxlength=128000
// +required
Value string `json:"value"`
}
//+kubebuilder:object:root=true
// ClusterPropertyList contains a list of ClusterProperty.
type ClusterPropertyList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
// Items is the list of ClusterProperty.
Items []ClusterProperty `json:"items"`
}

20
vendor/sigs.k8s.io/about-api/pkg/apis/v1alpha1/doc.go generated vendored Normal file
View File

@@ -0,0 +1,20 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1alpha1 contains API schema definitions for the ClusterProperty.
//+kubebuilder:object:generate=true
//+groupName=about.k8s.io
package v1alpha1

View File

@@ -0,0 +1,99 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by controller-gen. DO NOT EDIT.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterProperty) DeepCopyInto(out *ClusterProperty) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProperty.
func (in *ClusterProperty) DeepCopy() *ClusterProperty {
if in == nil {
return nil
}
out := new(ClusterProperty)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterProperty) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterPropertyList) DeepCopyInto(out *ClusterPropertyList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterProperty, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPropertyList.
func (in *ClusterPropertyList) DeepCopy() *ClusterPropertyList {
if in == nil {
return nil
}
out := new(ClusterPropertyList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterPropertyList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterPropertySpec) DeepCopyInto(out *ClusterPropertySpec) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPropertySpec.
func (in *ClusterPropertySpec) DeepCopy() *ClusterPropertySpec {
if in == nil {
return nil
}
out := new(ClusterPropertySpec)
in.DeepCopyInto(out)
return out
}

View File

@@ -0,0 +1,67 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by register-gen. DO NOT EDIT.
package v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName specifies the group name used to register the objects.
const GroupName = "about.k8s.io"
// GroupVersion specifies the group and the version used to register the objects.
var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"}
// SchemeGroupVersion is group version used to register these objects
// Deprecated: use GroupVersion instead.
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
// Depreciated: use Install instead
AddToScheme = localSchemeBuilder.AddToScheme
Install = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes)
}
// Adds the list of known types to Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&ClusterProperty{},
&ClusterPropertyList{},
)
// AddToGroupVersion allows the serialization of client types like ListOptions.
v1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View File

@@ -0,0 +1,121 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package versioned
import (
"fmt"
"net/http"
discovery "k8s.io/client-go/discovery"
rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol"
aboutv1alpha1 "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/typed/apis/v1alpha1"
)
type Interface interface {
Discovery() discovery.DiscoveryInterface
AboutV1alpha1() aboutv1alpha1.AboutV1alpha1Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
type Clientset struct {
*discovery.DiscoveryClient
aboutV1alpha1 *aboutv1alpha1.AboutV1alpha1Client
}
// AboutV1alpha1 retrieves the AboutV1alpha1Client
func (c *Clientset) AboutV1alpha1() aboutv1alpha1.AboutV1alpha1Interface {
return c.aboutV1alpha1
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
if c == nil {
return nil
}
return c.DiscoveryClient
}
// NewForConfig creates a new Clientset for the given config.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// NewForConfig will generate a rate-limiter in configShallowCopy.
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
// where httpClient was generated with rest.HTTPClientFor(c).
func NewForConfig(c *rest.Config) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.UserAgent == "" {
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
}
// share the transport between all clients
httpClient, err := rest.HTTPClientFor(&configShallowCopy)
if err != nil {
return nil, err
}
return NewForConfigAndClient(&configShallowCopy, httpClient)
}
// NewForConfigAndClient creates a new Clientset for the given config and http client.
// Note the http client provided takes precedence over the configured transport values.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// NewForConfigAndClient will generate a rate-limiter in configShallowCopy.
func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
if configShallowCopy.Burst <= 0 {
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
}
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.aboutV1alpha1, err = aboutv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient)
if err != nil {
return nil, err
}
return &cs, nil
}
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {
cs, err := NewForConfig(c)
if err != nil {
panic(err)
}
return cs
}
// New creates a new Clientset for the given RESTClient.
func New(c rest.Interface) *Clientset {
var cs Clientset
cs.aboutV1alpha1 = aboutv1alpha1.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs
}

View File

@@ -0,0 +1,20 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated clientset.
package versioned

View File

@@ -0,0 +1,85 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/discovery"
fakediscovery "k8s.io/client-go/discovery/fake"
"k8s.io/client-go/testing"
clientset "sigs.k8s.io/about-api/pkg/generated/clientset/versioned"
aboutv1alpha1 "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/typed/apis/v1alpha1"
fakeaboutv1alpha1 "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/typed/apis/v1alpha1/fake"
)
// NewSimpleClientset returns a clientset that will respond with the provided objects.
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
// without applying any validations and/or defaults. It shouldn't be considered a replacement
// for a real clientset and is mostly useful in simple unit tests.
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
for _, obj := range objects {
if err := o.Add(obj); err != nil {
panic(err)
}
}
cs := &Clientset{tracker: o}
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
cs.AddReactor("*", "*", testing.ObjectReaction(o))
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
gvr := action.GetResource()
ns := action.GetNamespace()
watch, err := o.Watch(gvr, ns)
if err != nil {
return false, nil, err
}
return true, watch, nil
})
return cs
}
// Clientset implements clientset.Interface. Meant to be embedded into a
// struct to get a default implementation. This makes faking out just the method
// you want to test easier.
type Clientset struct {
testing.Fake
discovery *fakediscovery.FakeDiscovery
tracker testing.ObjectTracker
}
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return c.discovery
}
func (c *Clientset) Tracker() testing.ObjectTracker {
return c.tracker
}
var (
_ clientset.Interface = &Clientset{}
_ testing.FakeClient = &Clientset{}
)
// AboutV1alpha1 retrieves the AboutV1alpha1Client
func (c *Clientset) AboutV1alpha1() aboutv1alpha1.AboutV1alpha1Interface {
return &fakeaboutv1alpha1.FakeAboutV1alpha1{Fake: &c.Fake}
}

View File

@@ -0,0 +1,20 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated fake clientset.
package fake

View File

@@ -0,0 +1,56 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
aboutv1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
)
var scheme = runtime.NewScheme()
var codecs = serializer.NewCodecFactory(scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
aboutv1alpha1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(scheme))
}

View File

@@ -0,0 +1,20 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package contains the scheme of the automatically generated clientset.
package scheme

View File

@@ -0,0 +1,56 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package scheme
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
aboutv1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
)
var Scheme = runtime.NewScheme()
var Codecs = serializer.NewCodecFactory(Scheme)
var ParameterCodec = runtime.NewParameterCodec(Scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
aboutv1alpha1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(Scheme))
}

View File

@@ -0,0 +1,107 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
"net/http"
rest "k8s.io/client-go/rest"
v1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
"sigs.k8s.io/about-api/pkg/generated/clientset/versioned/scheme"
)
type AboutV1alpha1Interface interface {
RESTClient() rest.Interface
ClusterPropertiesGetter
}
// AboutV1alpha1Client is used to interact with features provided by the about.k8s.io group.
type AboutV1alpha1Client struct {
restClient rest.Interface
}
func (c *AboutV1alpha1Client) ClusterProperties() ClusterPropertyInterface {
return newClusterProperties(c)
}
// NewForConfig creates a new AboutV1alpha1Client for the given config.
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
// where httpClient was generated with rest.HTTPClientFor(c).
func NewForConfig(c *rest.Config) (*AboutV1alpha1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
httpClient, err := rest.HTTPClientFor(&config)
if err != nil {
return nil, err
}
return NewForConfigAndClient(&config, httpClient)
}
// NewForConfigAndClient creates a new AboutV1alpha1Client for the given config and http client.
// Note the http client provided takes precedence over the configured transport values.
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AboutV1alpha1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientForConfigAndClient(&config, h)
if err != nil {
return nil, err
}
return &AboutV1alpha1Client{client}, nil
}
// NewForConfigOrDie creates a new AboutV1alpha1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *AboutV1alpha1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new AboutV1alpha1Client for the given RESTClient.
func New(c rest.Interface) *AboutV1alpha1Client {
return &AboutV1alpha1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1alpha1.SchemeGroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *AboutV1alpha1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}

View File

@@ -0,0 +1,168 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
scheme "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/scheme"
)
// ClusterPropertiesGetter has a method to return a ClusterPropertyInterface.
// A group's client should implement this interface.
type ClusterPropertiesGetter interface {
ClusterProperties() ClusterPropertyInterface
}
// ClusterPropertyInterface has methods to work with ClusterProperty resources.
type ClusterPropertyInterface interface {
Create(ctx context.Context, clusterProperty *v1alpha1.ClusterProperty, opts v1.CreateOptions) (*v1alpha1.ClusterProperty, error)
Update(ctx context.Context, clusterProperty *v1alpha1.ClusterProperty, opts v1.UpdateOptions) (*v1alpha1.ClusterProperty, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterProperty, error)
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterPropertyList, error)
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterProperty, err error)
ClusterPropertyExpansion
}
// clusterProperties implements ClusterPropertyInterface
type clusterProperties struct {
client rest.Interface
}
// newClusterProperties returns a ClusterProperties
func newClusterProperties(c *AboutV1alpha1Client) *clusterProperties {
return &clusterProperties{
client: c.RESTClient(),
}
}
// Get takes name of the clusterProperty, and returns the corresponding clusterProperty object, and an error if there is any.
func (c *clusterProperties) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterProperty, err error) {
result = &v1alpha1.ClusterProperty{}
err = c.client.Get().
Resource("clusterproperties").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of ClusterProperties that match those selectors.
func (c *clusterProperties) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterPropertyList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.ClusterPropertyList{}
err = c.client.Get().
Resource("clusterproperties").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested clusterProperties.
func (c *clusterProperties) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Resource("clusterproperties").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a clusterProperty and creates it. Returns the server's representation of the clusterProperty, and an error, if there is any.
func (c *clusterProperties) Create(ctx context.Context, clusterProperty *v1alpha1.ClusterProperty, opts v1.CreateOptions) (result *v1alpha1.ClusterProperty, err error) {
result = &v1alpha1.ClusterProperty{}
err = c.client.Post().
Resource("clusterproperties").
VersionedParams(&opts, scheme.ParameterCodec).
Body(clusterProperty).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a clusterProperty and updates it. Returns the server's representation of the clusterProperty, and an error, if there is any.
func (c *clusterProperties) Update(ctx context.Context, clusterProperty *v1alpha1.ClusterProperty, opts v1.UpdateOptions) (result *v1alpha1.ClusterProperty, err error) {
result = &v1alpha1.ClusterProperty{}
err = c.client.Put().
Resource("clusterproperties").
Name(clusterProperty.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(clusterProperty).
Do(ctx).
Into(result)
return
}
// Delete takes name of the clusterProperty and deletes it. Returns an error if one occurs.
func (c *clusterProperties) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Resource("clusterproperties").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *clusterProperties) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("clusterproperties").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched clusterProperty.
func (c *clusterProperties) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterProperty, err error) {
result = &v1alpha1.ClusterProperty{}
err = c.client.Patch(pt).
Resource("clusterproperties").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@@ -0,0 +1,20 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1alpha1

View File

@@ -0,0 +1,20 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake

View File

@@ -0,0 +1,40 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
v1alpha1 "sigs.k8s.io/about-api/pkg/generated/clientset/versioned/typed/apis/v1alpha1"
)
type FakeAboutV1alpha1 struct {
*testing.Fake
}
func (c *FakeAboutV1alpha1) ClusterProperties() v1alpha1.ClusterPropertyInterface {
return &FakeClusterProperties{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeAboutV1alpha1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}

View File

@@ -0,0 +1,122 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
)
// FakeClusterProperties implements ClusterPropertyInterface
type FakeClusterProperties struct {
Fake *FakeAboutV1alpha1
}
var clusterpropertiesResource = schema.GroupVersionResource{Group: "about.k8s.io", Version: "v1alpha1", Resource: "clusterproperties"}
var clusterpropertiesKind = schema.GroupVersionKind{Group: "about.k8s.io", Version: "v1alpha1", Kind: "ClusterProperty"}
// Get takes name of the clusterProperty, and returns the corresponding clusterProperty object, and an error if there is any.
func (c *FakeClusterProperties) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterProperty, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(clusterpropertiesResource, name), &v1alpha1.ClusterProperty{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ClusterProperty), err
}
// List takes label and field selectors, and returns the list of ClusterProperties that match those selectors.
func (c *FakeClusterProperties) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterPropertyList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(clusterpropertiesResource, clusterpropertiesKind, opts), &v1alpha1.ClusterPropertyList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha1.ClusterPropertyList{ListMeta: obj.(*v1alpha1.ClusterPropertyList).ListMeta}
for _, item := range obj.(*v1alpha1.ClusterPropertyList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested clusterProperties.
func (c *FakeClusterProperties) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(clusterpropertiesResource, opts))
}
// Create takes the representation of a clusterProperty and creates it. Returns the server's representation of the clusterProperty, and an error, if there is any.
func (c *FakeClusterProperties) Create(ctx context.Context, clusterProperty *v1alpha1.ClusterProperty, opts v1.CreateOptions) (result *v1alpha1.ClusterProperty, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(clusterpropertiesResource, clusterProperty), &v1alpha1.ClusterProperty{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ClusterProperty), err
}
// Update takes the representation of a clusterProperty and updates it. Returns the server's representation of the clusterProperty, and an error, if there is any.
func (c *FakeClusterProperties) Update(ctx context.Context, clusterProperty *v1alpha1.ClusterProperty, opts v1.UpdateOptions) (result *v1alpha1.ClusterProperty, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(clusterpropertiesResource, clusterProperty), &v1alpha1.ClusterProperty{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ClusterProperty), err
}
// Delete takes name of the clusterProperty and deletes it. Returns an error if one occurs.
func (c *FakeClusterProperties) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteActionWithOptions(clusterpropertiesResource, name, opts), &v1alpha1.ClusterProperty{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeClusterProperties) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(clusterpropertiesResource, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.ClusterPropertyList{})
return err
}
// Patch applies the patch and returns the patched clusterProperty.
func (c *FakeClusterProperties) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterProperty, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(clusterpropertiesResource, name, pt, data, subresources...), &v1alpha1.ClusterProperty{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ClusterProperty), err
}

View File

@@ -0,0 +1,21 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
type ClusterPropertyExpansion interface{}

View File

@@ -0,0 +1,46 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package apis
import (
v1alpha1 "sigs.k8s.io/about-api/pkg/generated/informers/externalversions/apis/v1alpha1"
internalinterfaces "sigs.k8s.io/about-api/pkg/generated/informers/externalversions/internalinterfaces"
)
// Interface provides access to each of this group's versions.
type Interface interface {
// V1alpha1 provides access to shared informers for resources in V1alpha1.
V1alpha1() v1alpha1.Interface
}
type group struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// V1alpha1 returns a new v1alpha1.Interface.
func (g *group) V1alpha1() v1alpha1.Interface {
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
}

View File

@@ -0,0 +1,89 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
apisv1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
versioned "sigs.k8s.io/about-api/pkg/generated/clientset/versioned"
internalinterfaces "sigs.k8s.io/about-api/pkg/generated/informers/externalversions/internalinterfaces"
v1alpha1 "sigs.k8s.io/about-api/pkg/generated/listers/apis/v1alpha1"
)
// ClusterPropertyInformer provides access to a shared informer and lister for
// ClusterProperties.
type ClusterPropertyInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha1.ClusterPropertyLister
}
type clusterPropertyInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// NewClusterPropertyInformer constructs a new informer for ClusterProperty type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewClusterPropertyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredClusterPropertyInformer(client, resyncPeriod, indexers, nil)
}
// NewFilteredClusterPropertyInformer constructs a new informer for ClusterProperty type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredClusterPropertyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.AboutV1alpha1().ClusterProperties().List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.AboutV1alpha1().ClusterProperties().Watch(context.TODO(), options)
},
},
&apisv1alpha1.ClusterProperty{},
resyncPeriod,
indexers,
)
}
func (f *clusterPropertyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredClusterPropertyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *clusterPropertyInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&apisv1alpha1.ClusterProperty{}, f.defaultInformer)
}
func (f *clusterPropertyInformer) Lister() v1alpha1.ClusterPropertyLister {
return v1alpha1.NewClusterPropertyLister(f.Informer().GetIndexer())
}

View File

@@ -0,0 +1,45 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha1
import (
internalinterfaces "sigs.k8s.io/about-api/pkg/generated/informers/externalversions/internalinterfaces"
)
// Interface provides access to all the informers in this group version.
type Interface interface {
// ClusterProperties returns a ClusterPropertyInformer.
ClusterProperties() ClusterPropertyInformer
}
type version struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// ClusterProperties returns a ClusterPropertyInformer.
func (v *version) ClusterProperties() ClusterPropertyInformer {
return &clusterPropertyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
}

View File

@@ -0,0 +1,180 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package externalversions
import (
reflect "reflect"
sync "sync"
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
versioned "sigs.k8s.io/about-api/pkg/generated/clientset/versioned"
apis "sigs.k8s.io/about-api/pkg/generated/informers/externalversions/apis"
internalinterfaces "sigs.k8s.io/about-api/pkg/generated/informers/externalversions/internalinterfaces"
)
// SharedInformerOption defines the functional option type for SharedInformerFactory.
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
type sharedInformerFactory struct {
client versioned.Interface
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
lock sync.Mutex
defaultResync time.Duration
customResync map[reflect.Type]time.Duration
informers map[reflect.Type]cache.SharedIndexInformer
// startedInformers is used for tracking which informers have been started.
// This allows Start() to be called multiple times safely.
startedInformers map[reflect.Type]bool
}
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
for k, v := range resyncConfig {
factory.customResync[reflect.TypeOf(k)] = v
}
return factory
}
}
// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
factory.tweakListOptions = tweakListOptions
return factory
}
}
// WithNamespace limits the SharedInformerFactory to the specified namespace.
func WithNamespace(namespace string) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
factory.namespace = namespace
return factory
}
}
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync)
}
// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
// Listers obtained via this SharedInformerFactory will be subject to the same filters
// as specified here.
// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
}
// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
factory := &sharedInformerFactory{
client: client,
namespace: v1.NamespaceAll,
defaultResync: defaultResync,
informers: make(map[reflect.Type]cache.SharedIndexInformer),
startedInformers: make(map[reflect.Type]bool),
customResync: make(map[reflect.Type]time.Duration),
}
// Apply all options
for _, opt := range options {
factory = opt(factory)
}
return factory
}
// Start initializes all requested informers.
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
f.lock.Lock()
defer f.lock.Unlock()
for informerType, informer := range f.informers {
if !f.startedInformers[informerType] {
go informer.Run(stopCh)
f.startedInformers[informerType] = true
}
}
}
// WaitForCacheSync waits for all started informers' cache were synced.
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
informers := func() map[reflect.Type]cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informers := map[reflect.Type]cache.SharedIndexInformer{}
for informerType, informer := range f.informers {
if f.startedInformers[informerType] {
informers[informerType] = informer
}
}
return informers
}()
res := map[reflect.Type]bool{}
for informType, informer := range informers {
res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
}
return res
}
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
// client.
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(obj)
informer, exists := f.informers[informerType]
if exists {
return informer
}
resyncPeriod, exists := f.customResync[informerType]
if !exists {
resyncPeriod = f.defaultResync
}
informer = newFunc(f.client, resyncPeriod)
f.informers[informerType] = informer
return informer
}
// SharedInformerFactory provides shared informers for resources in all known
// API group versions.
type SharedInformerFactory interface {
internalinterfaces.SharedInformerFactory
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
About() apis.Interface
}
func (f *sharedInformerFactory) About() apis.Interface {
return apis.New(f, f.namespace, f.tweakListOptions)
}

View File

@@ -0,0 +1,62 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package externalversions
import (
"fmt"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
v1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
)
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
// sharedInformers based on type
type GenericInformer interface {
Informer() cache.SharedIndexInformer
Lister() cache.GenericLister
}
type genericInformer struct {
informer cache.SharedIndexInformer
resource schema.GroupResource
}
// Informer returns the SharedIndexInformer.
func (f *genericInformer) Informer() cache.SharedIndexInformer {
return f.informer
}
// Lister returns the GenericLister.
func (f *genericInformer) Lister() cache.GenericLister {
return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
}
// ForResource gives generic access to a shared informer of the matching type
// TODO extend this to unknown resources with a client pool
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
switch resource {
// Group=about.k8s.io, Version=v1alpha1
case v1alpha1.SchemeGroupVersion.WithResource("clusterproperties"):
return &genericInformer{resource: resource.GroupResource(), informer: f.About().V1alpha1().ClusterProperties().Informer()}, nil
}
return nil, fmt.Errorf("no informer found for %v", resource)
}

View File

@@ -0,0 +1,40 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package internalinterfaces
import (
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
cache "k8s.io/client-go/tools/cache"
versioned "sigs.k8s.io/about-api/pkg/generated/clientset/versioned"
)
// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
type SharedInformerFactory interface {
Start(stopCh <-chan struct{})
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
type TweakListOptionsFunc func(*v1.ListOptions)

View File

@@ -0,0 +1,68 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1alpha1 "sigs.k8s.io/about-api/pkg/apis/v1alpha1"
)
// ClusterPropertyLister helps list ClusterProperties.
// All objects returned here must be treated as read-only.
type ClusterPropertyLister interface {
// List lists all ClusterProperties in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha1.ClusterProperty, err error)
// Get retrieves the ClusterProperty from the index for a given name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1alpha1.ClusterProperty, error)
ClusterPropertyListerExpansion
}
// clusterPropertyLister implements the ClusterPropertyLister interface.
type clusterPropertyLister struct {
indexer cache.Indexer
}
// NewClusterPropertyLister returns a new ClusterPropertyLister.
func NewClusterPropertyLister(indexer cache.Indexer) ClusterPropertyLister {
return &clusterPropertyLister{indexer: indexer}
}
// List lists all ClusterProperties in the indexer.
func (s *clusterPropertyLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterProperty, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.ClusterProperty))
})
return ret, err
}
// Get retrieves the ClusterProperty from the index for a given name.
func (s *clusterPropertyLister) Get(name string) (*v1alpha1.ClusterProperty, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("clusterproperty"), name)
}
return obj.(*v1alpha1.ClusterProperty), nil
}

View File

@@ -0,0 +1,23 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha1
// ClusterPropertyListerExpansion allows custom methods to be added to
// ClusterPropertyLister.
type ClusterPropertyListerExpansion interface{}