mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-08-23 22:26:49 +00:00
clusterset v1beta1 migration (#315)
Signed-off-by: ldpliu <daliu@redhat.com>
This commit is contained in:
@@ -19,7 +19,7 @@ require (
|
||||
k8s.io/component-base v0.24.3
|
||||
k8s.io/klog/v2 v2.70.0
|
||||
k8s.io/kube-aggregator v0.24.3
|
||||
open-cluster-management.io/api v0.9.1-0.20221116150238-55691c2c5f04
|
||||
open-cluster-management.io/api v0.10.1-0.20230208112741-9a2b4f0edd3d
|
||||
sigs.k8s.io/controller-runtime v0.12.3
|
||||
sigs.k8s.io/kube-storage-version-migrator v0.0.5
|
||||
)
|
||||
@@ -70,7 +70,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/google/uuid v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
|
||||
@@ -345,8 +345,9 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
@@ -1234,8 +1235,8 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
open-cluster-management.io/api v0.9.1-0.20221116150238-55691c2c5f04 h1:lXewKgs1MeWN1wPIlMGQxfQj83CgjkNXQKVJVYQEB5I=
|
||||
open-cluster-management.io/api v0.9.1-0.20221116150238-55691c2c5f04/go.mod h1:9KkJPh/zpDevXj2P+zkvSVjC2pq2PQ1JDNLLEes8TEc=
|
||||
open-cluster-management.io/api v0.10.1-0.20230208112741-9a2b4f0edd3d h1:y18swHf6uA6UoAkqOx9ZXL7GJxGkale0H9qA1oeI3mk=
|
||||
open-cluster-management.io/api v0.10.1-0.20230208112741-9a2b4f0edd3d/go.mod h1:6BB/Y6r3hXlPjpJgDwIs6Ubxyx/kXXOg6D9Cntg1I9E=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: migration.k8s.io/v1alpha1
|
||||
kind: StorageVersionMigration
|
||||
metadata:
|
||||
name: managedclustersetbindings.cluster.open-cluster-management.io
|
||||
spec:
|
||||
resource:
|
||||
group: cluster.open-cluster-management.io
|
||||
resource: managedclustersetbindings
|
||||
version: v1beta1
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: migration.k8s.io/v1alpha1
|
||||
kind: StorageVersionMigration
|
||||
metadata:
|
||||
name: managedclustersets.cluster.open-cluster-management.io
|
||||
spec:
|
||||
resource:
|
||||
group: cluster.open-cluster-management.io
|
||||
resource: managedclustersets
|
||||
version: v1beta1
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: managedclustersets.cluster.open-cluster-management.io
|
||||
spec:
|
||||
group: cluster.open-cluster-management.io
|
||||
names:
|
||||
kind: ManagedClusterSet
|
||||
listKind: ManagedClusterSetList
|
||||
plural: managedclustersets
|
||||
shortNames:
|
||||
- mclset
|
||||
- mclsets
|
||||
singular: managedclusterset
|
||||
scope: Cluster
|
||||
preserveUnknownFields: false
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.conditions[?(@.type=="ClusterSetEmpty")].status
|
||||
name: Empty
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: "ManagedClusterSet defines a group of ManagedClusters that user's workload can run on. A workload can be defined to deployed on a ManagedClusterSet, which mean: 1. The workload can run on any ManagedCluster in the ManagedClusterSet 2. The workload cannot run on any ManagedCluster outside the ManagedClusterSet 3. The service exposed by the workload can be shared in any ManagedCluster in the ManagedClusterSet \n In order to assign a ManagedCluster to a certian ManagedClusterSet, add a label with name `cluster.open-cluster-management.io/clusterset` on the ManagedCluster to refers to the ManagedClusterSet. User is not allow to add/remove this label on a ManagedCluster unless they have a RBAC rule to CREATE on a virtual subresource of managedclustersets/join. In order to update this label, user must have the permission on both the old and new ManagedClusterSet."
|
||||
type: object
|
||||
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: Spec defines the attributes of the ManagedClusterSet
|
||||
type: object
|
||||
default:
|
||||
clusterSelector:
|
||||
selectorType: LegacyClusterSetLabel
|
||||
properties:
|
||||
clusterSelector:
|
||||
description: ClusterSelector represents a selector of ManagedClusters
|
||||
type: object
|
||||
default:
|
||||
selectorType: LegacyClusterSetLabel
|
||||
properties:
|
||||
labelSelector:
|
||||
description: LabelSelector define the general labelSelector which clusterset will use to select target managedClusters
|
||||
type: object
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
type: array
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
matchLabels:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
selectorType:
|
||||
description: SelectorType could only be "LegacyClusterSetLabel" or "LabelSelector" "LegacyClusterSetLabel" means to use label "cluster.open-cluster-management.io/clusterset:<ManagedClusterSet Name>"" to select target clusters. "LabelSelector" means use labelSelector to select target managedClusters
|
||||
type: string
|
||||
default: LegacyClusterSetLabel
|
||||
enum:
|
||||
- LegacyClusterSetLabel
|
||||
- LabelSelector
|
||||
status:
|
||||
description: Status represents the current status of the ManagedClusterSet
|
||||
type: object
|
||||
properties:
|
||||
conditions:
|
||||
description: Conditions contains the different condition statuses for this ManagedClusterSet.
|
||||
type: array
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
type: object
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
type: string
|
||||
format: date-time
|
||||
message:
|
||||
description: message is a human readable message indicating details about the transition. This may be an empty string.
|
||||
type: string
|
||||
maxLength: 32768
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 0
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
|
||||
type: string
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
type: string
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
+2
-2
@@ -212,7 +212,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
@@ -396,7 +396,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
|
||||
+2
-2
@@ -88,7 +88,7 @@ spec:
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
served: true
|
||||
storage: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- name: v1beta2
|
||||
@@ -162,7 +162,7 @@ spec:
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
served: true
|
||||
storage: false
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
|
||||
+5
-6
@@ -7,6 +7,8 @@ package clustermanagercontroller
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/openshift/library-go/pkg/assets"
|
||||
"github.com/openshift/library-go/pkg/operator/events"
|
||||
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
|
||||
@@ -21,7 +23,6 @@ import (
|
||||
"open-cluster-management.io/registration-operator/pkg/helpers"
|
||||
"open-cluster-management.io/registration-operator/pkg/operators/clustermanager/controllers/migrationcontroller"
|
||||
"open-cluster-management.io/registration-operator/pkg/operators/crdmanager"
|
||||
"reflect"
|
||||
migrationclient "sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset/typed/migration/v1alpha1"
|
||||
)
|
||||
|
||||
@@ -51,10 +52,8 @@ var (
|
||||
|
||||
// removed CRD StoredVersions
|
||||
removedCRDStoredVersions = map[string]string{
|
||||
"placements.cluster.open-cluster-management.io": "v1alpha1",
|
||||
"placementdecisions.cluster.open-cluster-management.io": "v1alpha1",
|
||||
"managedclustersets.cluster.open-cluster-management.io": "v1alpha1",
|
||||
"managedclustersetbindings.cluster.open-cluster-management.io": "v1alpha1",
|
||||
"managedclustersets.cluster.open-cluster-management.io": "v1beta1",
|
||||
"managedclustersetbindings.cluster.open-cluster-management.io": "v1beta1",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -163,7 +162,7 @@ func (c *crdReconcile) updateStoredVersion(ctx context.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
// remove v1alpha1 from its status
|
||||
// remove old versions from its status
|
||||
oldStoredVersions := crd.Status.StoredVersions
|
||||
newStoredVersions := make([]string, 0, len(oldStoredVersions))
|
||||
for _, stored := range oldStoredVersions {
|
||||
|
||||
+4
-1
@@ -44,7 +44,10 @@ var (
|
||||
// migrationRequestFiles = []string{
|
||||
// "cluster-manager/cluster-manager-managedclustersets-migration.yaml",
|
||||
// }
|
||||
migrationRequestFiles = []string{}
|
||||
migrationRequestFiles = []string{
|
||||
"cluster-manager/cluster-manager-managedclustersets-migration.yaml",
|
||||
"cluster-manager/cluster-manager-managedclustersetbindings-migration.yaml",
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
+2
-10
@@ -61,15 +61,11 @@ func TestApplyStorageVersionMigrations(t *testing.T) {
|
||||
{
|
||||
name: "created",
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
assertActions(t, actions, "get", "create", "get", "create", "get", "create", "get", "create")
|
||||
assertActions(t, actions, "get", "create", "get", "create")
|
||||
actual := actions[1].(clienttesting.CreateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "managedclustersets.cluster.open-cluster-management.io", actual)
|
||||
actual = actions[3].(clienttesting.CreateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "managedclustersetbindings.cluster.open-cluster-management.io", actual)
|
||||
actual = actions[5].(clienttesting.CreateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "placements.cluster.open-cluster-management.io", actual)
|
||||
actual = actions[7].(clienttesting.CreateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "placementdecisions.cluster.open-cluster-management.io", actual)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -87,15 +83,11 @@ func TestApplyStorageVersionMigrations(t *testing.T) {
|
||||
},
|
||||
},
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
assertActions(t, actions, "get", "create", "get", "update", "get", "create", "get", "update")
|
||||
assertActions(t, actions, "get", "create", "get", "update")
|
||||
actual := actions[1].(clienttesting.CreateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "managedclustersets.cluster.open-cluster-management.io", actual)
|
||||
actual = actions[3].(clienttesting.UpdateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "managedclustersetbindings.cluster.open-cluster-management.io", actual)
|
||||
actual = actions[5].(clienttesting.CreateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "placements.cluster.open-cluster-management.io", actual)
|
||||
actual = actions[7].(clienttesting.UpdateActionImpl).Object
|
||||
assertStorageVersionMigration(t, "placementdecisions.cluster.open-cluster-management.io", actual)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ import (
|
||||
clusterv1beta2 "open-cluster-management.io/api/cluster/v1beta2"
|
||||
)
|
||||
|
||||
const (
|
||||
clustersetCrdName = "managedclustersets.cluster.open-cluster-management.io"
|
||||
clustersetBindingCrdName = "managedclustersetbindings.cluster.open-cluster-management.io"
|
||||
)
|
||||
|
||||
var _ = ginkgo.Describe("Create v1beta2 managedclusterset", func() {
|
||||
ginkgo.It("Create a v1beta2 labelselector based ManagedClusterSet and get/update/delete with v1beta2 client", func() {
|
||||
ginkgo.By("Create a v1beta2 ManagedClusterSet")
|
||||
@@ -113,4 +118,34 @@ var _ = ginkgo.Describe("Create v1beta2 managedclusterset", func() {
|
||||
err := t.ClusterClient.ClusterV1beta1().ManagedClusterSets().Delete(context.Background(), managedClusterSetName, metav1.DeleteOptions{})
|
||||
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||
})
|
||||
ginkgo.It("Check if the v1beta1 storageversion is removed from clusterset crd", func() {
|
||||
gomega.Eventually(func() error {
|
||||
clustersetCrd, err := t.HubAPIExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.Background(), clustersetCrdName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(clustersetCrd.Status.StoredVersions) != 1 {
|
||||
return fmt.Errorf("clustersetCrd.Status.StoredVersions should be v1beta2, but got:%v", clustersetCrd.Status.StoredVersions)
|
||||
}
|
||||
if clustersetCrd.Status.StoredVersions[0] != "v1beta2" {
|
||||
return fmt.Errorf("clustersetCrd.Status.StoredVersions should be v1beta2, but got:%v", clustersetCrd.Status.StoredVersions)
|
||||
}
|
||||
return nil
|
||||
}, t.EventuallyTimeout*5, t.EventuallyInterval*5).Should(gomega.Succeed())
|
||||
})
|
||||
ginkgo.It("Check if the v1beta1 storageversion is removed from clustersetbinding crd", func() {
|
||||
gomega.Eventually(func() error {
|
||||
clustersetBindingCrd, err := t.HubAPIExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.Background(), clustersetBindingCrdName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(clustersetBindingCrd.Status.StoredVersions) != 1 {
|
||||
return fmt.Errorf("clustersetBindingCrd.Status.StoredVersions should be v1beta2, but got:%v", clustersetBindingCrd.Status.StoredVersions)
|
||||
}
|
||||
if clustersetBindingCrd.Status.StoredVersions[0] != "v1beta2" {
|
||||
return fmt.Errorf("clustersetBindingCrd.Status.StoredVersions should be v1beta2, but got:%v", clustersetBindingCrd.Status.StoredVersions)
|
||||
}
|
||||
return nil
|
||||
}, t.EventuallyTimeout*5, t.EventuallyInterval*5).Should(gomega.Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/onsi/gomega"
|
||||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
|
||||
certificatesv1 "k8s.io/api/certificates/v1"
|
||||
coordv1 "k8s.io/api/coordination/v1"
|
||||
@@ -38,6 +39,7 @@ import (
|
||||
type Tester struct {
|
||||
kubeconfigPath string
|
||||
KubeClient kubernetes.Interface
|
||||
HubAPIExtensionClient apiextensionsclient.Interface
|
||||
ClusterCfg *rest.Config
|
||||
OperatorClient operatorclient.Interface
|
||||
ClusterClient clusterclient.Interface
|
||||
@@ -95,6 +97,11 @@ func (t *Tester) Init() error {
|
||||
klog.Errorf("failed to get KubeClient. %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if t.HubAPIExtensionClient, err = apiextensionsclient.NewForConfig(t.ClusterCfg); err != nil {
|
||||
klog.Errorf("failed to get HubApiExtensionClient. %v", err)
|
||||
return err
|
||||
}
|
||||
if t.OperatorClient, err = operatorclient.NewForConfig(t.ClusterCfg); err != nil {
|
||||
klog.Errorf("failed to get OperatorClient. %v", err)
|
||||
return err
|
||||
|
||||
+2
-2
@@ -26,8 +26,8 @@ var (
|
||||
// NewMD5 and NewSHA1.
|
||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
h.Reset()
|
||||
h.Write(space[:])
|
||||
h.Write(data)
|
||||
h.Write(space[:]) //nolint:errcheck
|
||||
h.Write(data) //nolint:errcheck
|
||||
s := h.Sum(nil)
|
||||
var uuid UUID
|
||||
copy(uuid[:], s)
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently.
|
||||
// Currently, database types that map to string and []byte are supported. Please
|
||||
// consult database-specific driver documentation for matching types.
|
||||
func (uuid *UUID) Scan(src interface{}) error {
|
||||
|
||||
+8
-2
@@ -35,6 +35,12 @@ const (
|
||||
|
||||
var rander = rand.Reader // random function
|
||||
|
||||
type invalidLengthError struct{ len int }
|
||||
|
||||
func (err invalidLengthError) Error() string {
|
||||
return fmt.Sprintf("invalid UUID length: %d", err.len)
|
||||
}
|
||||
|
||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
||||
@@ -68,7 +74,7 @@ func Parse(s string) (UUID, error) {
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||
return uuid, invalidLengthError{len(s)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
@@ -112,7 +118,7 @@ func ParseBytes(b []byte) (UUID, error) {
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||
return uuid, invalidLengthError{len(b)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
|
||||
+8
@@ -14,6 +14,14 @@ func New() UUID {
|
||||
return Must(NewRandom())
|
||||
}
|
||||
|
||||
// NewString creates a new random UUID and returns it as a string or panics.
|
||||
// NewString is equivalent to the expression
|
||||
//
|
||||
// uuid.New().String()
|
||||
func NewString() string {
|
||||
return Must(NewRandom()).String()
|
||||
}
|
||||
|
||||
// NewRandom returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
|
||||
Vendored
+2
-2
@@ -95,7 +95,7 @@ github.com/google/go-cmp/cmp/internal/value
|
||||
# github.com/google/gofuzz v1.1.0
|
||||
## explicit; go 1.12
|
||||
github.com/google/gofuzz
|
||||
# github.com/google/uuid v1.1.2
|
||||
# github.com/google/uuid v1.2.0
|
||||
## explicit
|
||||
github.com/google/uuid
|
||||
# github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
@@ -1170,7 +1170,7 @@ k8s.io/utils/path
|
||||
k8s.io/utils/pointer
|
||||
k8s.io/utils/strings/slices
|
||||
k8s.io/utils/trace
|
||||
# open-cluster-management.io/api v0.9.1-0.20221116150238-55691c2c5f04
|
||||
# open-cluster-management.io/api v0.10.1-0.20230208112741-9a2b4f0edd3d
|
||||
## explicit; go 1.19
|
||||
open-cluster-management.io/api/addon/v1alpha1
|
||||
open-cluster-management.io/api/client/addon/clientset/versioned
|
||||
|
||||
Generated
Vendored
+54
@@ -216,3 +216,57 @@ type ManagedClusterAddOnList struct {
|
||||
|
||||
Items []ManagedClusterAddOn `json:"items"`
|
||||
}
|
||||
|
||||
const (
|
||||
// Label and annotation keys set on ManagedClusterAddon.
|
||||
|
||||
// AddonLabelKey is the label key to set addon name. It is to set on the resources on the hub relating
|
||||
// to an addon
|
||||
AddonLabelKey = "open-cluster-management.io/addon-name"
|
||||
|
||||
// DisableAddonAutomaticInstallationAnnotationKey is the annotation key for disabling the functionality of
|
||||
// installing addon automatically. it should be set on ManagedClusterAddon resource only.
|
||||
DisableAddonAutomaticInstallationAnnotationKey = "addon.open-cluster-management.io/disable-automatic-installation"
|
||||
|
||||
// AddonNamespaceLabelKey is the label key to set namespace of ManagedClusterAddon.
|
||||
AddonNamespaceLabelKey = "open-cluster-management.io/addon-namespace"
|
||||
|
||||
// Label and annotation keys set on manifests of addon agent.
|
||||
|
||||
// AddonPreDeleteHookLabelKey is the label key to identify that a resource manifest is used as pre-delete hook for an addon
|
||||
// and should be created and deleted before the specified ManagedClusterAddon is deleted.
|
||||
// Deprecated, and will be removed in the future release, please use annotation AddonPreDeleteHookAnnotationKey from v0.10.0.
|
||||
AddonPreDeleteHookLabelKey = "open-cluster-management.io/addon-pre-delete"
|
||||
|
||||
// AddonPreDeleteHookAnnotationKey is the annotation key to identify that a resource manifest is used as pre-delete hook for an addon
|
||||
// and should be created and deleted before the specified ManagedClusterAddon is deleted.
|
||||
AddonPreDeleteHookAnnotationKey = "addon.open-cluster-management.io/addon-pre-delete"
|
||||
|
||||
// HostingClusterNameAnnotationKey is the annotation key for indicating the hosting cluster name, it should be set
|
||||
// on ManagedClusterAddon resource only.
|
||||
HostingClusterNameAnnotationKey = "addon.open-cluster-management.io/hosting-cluster-name"
|
||||
|
||||
// DeletionOrphanAnnotationKey is an annotation for the manifest of addon indicating that it will not be cleaned up
|
||||
// after the addon is deleted.
|
||||
DeletionOrphanAnnotationKey = "addon.open-cluster-management.io/deletion-orphan"
|
||||
|
||||
// HostedManifestLocationLabelKey is the label key to identify where a resource manifest of addon agent
|
||||
// with this label should be deployed in Hosted mode.
|
||||
// Deprecated, will be removed in the future release, please use annotation HostedManifestLocationAnnotationKey from v0.10.0.
|
||||
HostedManifestLocationLabelKey = "addon.open-cluster-management.io/hosted-manifest-location"
|
||||
|
||||
// HostedManifestLocationAnnotationKey is the annotation key to identify where a resource manifest of addon agent
|
||||
// with this annotation should be deployed in Hosted mode.
|
||||
HostedManifestLocationAnnotationKey = "addon.open-cluster-management.io/hosted-manifest-location"
|
||||
|
||||
// HostedManifestLocationManagedValue is a value of the annotation HostedManifestLocationAnnotationKey,
|
||||
// indicates the manifest will be deployed on the managed cluster in Hosted mode,
|
||||
// it is the default value of a manifest in Hosted mode.
|
||||
HostedManifestLocationManagedValue = "managed"
|
||||
// HostedManifestLocationHostingValue is a value of the annotation HostedManifestLocationAnnotationKey,
|
||||
// indicates the manifest will be deployed on the hosting cluster in Hosted mode.
|
||||
HostedManifestLocationHostingValue = "hosting"
|
||||
// HostedManifestLocationNoneValue is a value of the annotation HostedManifestLocationAnnotationKey,,
|
||||
// indicates the manifest will not be deployed in Hosted mode.
|
||||
HostedManifestLocationNoneValue = "none"
|
||||
)
|
||||
|
||||
Generated
Vendored
+4
@@ -45,6 +45,10 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
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 {
|
||||
|
||||
Generated
Vendored
+4
@@ -69,6 +69,10 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
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 {
|
||||
|
||||
Generated
Vendored
+4
@@ -45,6 +45,10 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
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 {
|
||||
|
||||
Generated
Vendored
+4
@@ -53,6 +53,10 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
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 {
|
||||
|
||||
+5
@@ -229,3 +229,8 @@ type ManagedClusterList struct {
|
||||
// Items is a list of managed clusters.
|
||||
Items []ManagedCluster `json:"items"`
|
||||
}
|
||||
|
||||
const (
|
||||
// ClusterNameLabelKey is the key of a label to set ManagedCluster name.
|
||||
ClusterNameLabelKey = "open-cluster-management.io/cluster-name"
|
||||
)
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -26,7 +26,7 @@ spec:
|
||||
deprecated: true
|
||||
deprecationWarning: "cluster.open-cluster-management.io/v1beta1 ManagedClusterSet is deprecated; use cluster.open-cluster-management.io/v1beta2 ManagedClusterSet"
|
||||
served: true
|
||||
storage: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
"schema":
|
||||
@@ -149,7 +149,7 @@ spec:
|
||||
type: date
|
||||
name: v1beta2
|
||||
served: true
|
||||
storage: false
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
"schema":
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -88,7 +88,7 @@ spec:
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
served: true
|
||||
storage: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- name: v1beta2
|
||||
@@ -162,7 +162,7 @@ spec:
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
served: true
|
||||
storage: false
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -1,13 +1,13 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: placementmanifestworks.work.open-cluster-management.io
|
||||
name: placemanifestworks.work.open-cluster-management.io
|
||||
spec:
|
||||
group: work.open-cluster-management.io
|
||||
names:
|
||||
kind: PlaceManifestWork
|
||||
listKind: PlaceManifestWorkList
|
||||
plural: placementmanifestworks
|
||||
plural: placemanifestworks
|
||||
shortNames:
|
||||
- pmw
|
||||
- pmws
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import (
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:path=placementmanifestworks,shortName=pmw;pmws,scope=Namespaced
|
||||
// +kubebuilder:resource:path=placemanifestworks,shortName=pmw;pmws,scope=Namespaced
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Placement",type="string",JSONPath=".status.conditions[?(@.type==\"PlacementVerified\")].reason",description="Reason"
|
||||
|
||||
Reference in New Issue
Block a user