From b7d110baeb656c8e250a7d1f1d416c6e046be85d Mon Sep 17 00:00:00 2001 From: Mike Morris <1149913+mikemorris@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:42:43 -0400 Subject: [PATCH 1/7] apis/v1alpha2: move ServiceImport spec fields to status --- pkg/apis/v1alpha2/BUILD | 35 ++++ pkg/apis/v1alpha2/doc.go | 21 ++ pkg/apis/v1alpha2/serviceexport.go | 76 +++++++ pkg/apis/v1alpha2/serviceimport.go | 120 +++++++++++ pkg/apis/v1alpha2/well_known_labels.go | 26 +++ pkg/apis/v1alpha2/zz_generated.deepcopy.go | 233 +++++++++++++++++++++ pkg/apis/v1alpha2/zz_generated.register.go | 72 +++++++ 7 files changed, 583 insertions(+) create mode 100644 pkg/apis/v1alpha2/BUILD create mode 100644 pkg/apis/v1alpha2/doc.go create mode 100644 pkg/apis/v1alpha2/serviceexport.go create mode 100644 pkg/apis/v1alpha2/serviceimport.go create mode 100644 pkg/apis/v1alpha2/well_known_labels.go create mode 100644 pkg/apis/v1alpha2/zz_generated.deepcopy.go create mode 100644 pkg/apis/v1alpha2/zz_generated.register.go diff --git a/pkg/apis/v1alpha2/BUILD b/pkg/apis/v1alpha2/BUILD new file mode 100644 index 0000000..895283b --- /dev/null +++ b/pkg/apis/v1alpha2/BUILD @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "doc.go", + "register.go", + "types.go", + "well_known_labels.go", + "zz_generated.deepcopy.go", + ], + importmap = "k8s.io/kubernetes/vendor/k8s.io/mcs-api/pkg/apis/v1alpha2", + importpath = "k8s.io/mcs-api/pkg/apis/v1alpha2", + visibility = ["//visibility:public"], + deps = [ + "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/pkg/apis/v1alpha2/doc.go b/pkg/apis/v1alpha2/doc.go new file mode 100644 index 0000000..64e70a4 --- /dev/null +++ b/pkg/apis/v1alpha2/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 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 Multi-Cluster +// Services v1alpha1 API group. +// +kubebuilder:object:generate=true +// +groupName=multicluster.x-k8s.io +package v1alpha2 diff --git a/pkg/apis/v1alpha2/serviceexport.go b/pkg/apis/v1alpha2/serviceexport.go new file mode 100644 index 0000000..d081fcd --- /dev/null +++ b/pkg/apis/v1alpha2/serviceexport.go @@ -0,0 +1,76 @@ +/* +Copyright 2020 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 v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:object:root=true + +// ServiceExport declares that the Service with the same name and namespace +// as this export should be consumable from other clusters. +type ServiceExport struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + // status describes the current state of an exported service. + // Service configuration comes from the Service that had the same + // name and namespace as this ServiceExport. + // Populated by the multi-cluster service implementation's controller. + // +optional + Status ServiceExportStatus `json:"status,omitempty"` +} + +// ServiceExportStatus contains the current status of an export. +type ServiceExportStatus struct { + // +optional + // +patchStrategy=merge + // +patchMergeKey=type + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +const ( + // ServiceExportValid means that the service referenced by this + // service export has been recognized as valid by an mcs-controller. + // This will be false if the service is found to be unexportable + // (ExternalName, not found). + ServiceExportValid = "Valid" + // ServiceExportConflict means that there is a conflict between two + // exports for the same Service. When "True", the condition message + // should contain enough information to diagnose the conflict: + // field(s) under contention, which cluster won, and why. + // Users should not expect detailed per-cluster information in the + // conflict message. + ServiceExportConflict = "Conflict" +) + +// +kubebuilder:object:root=true + +// ServiceExportList represents a list of endpoint slices +type ServiceExportList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + // List of endpoint slices + // +listType=set + Items []ServiceExport `json:"items"` +} diff --git a/pkg/apis/v1alpha2/serviceimport.go b/pkg/apis/v1alpha2/serviceimport.go new file mode 100644 index 0000000..0a086ec --- /dev/null +++ b/pkg/apis/v1alpha2/serviceimport.go @@ -0,0 +1,120 @@ +/* +Copyright 2020 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 v1alpha2 + +import ( + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:object:root=true + +// ServiceImport describes a service imported from clusters in a ClusterSet. +type ServiceImport struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + // spec defines the behavior of a ServiceImport. + // +optional + Spec ServiceImportSpec `json:"spec,omitempty"` + // status contains information about the exported services that form + // the multi-cluster service referenced by this ServiceImport. + // +optional + Status ServiceImportStatus `json:"status,omitempty"` +} + +// ServiceImportType designates the type of a ServiceImport +type ServiceImportType string + +const ( + // ClusterSetIP services are only accessible via the ClusterSet IP. + ClusterSetIP ServiceImportType = "ClusterSetIP" + // Headless services allow backend pods to be addressed directly. + Headless ServiceImportType = "Headless" +) + +// ServiceImportSpec describes an imported service and the information necessary to consume it. +type ServiceImportSpec struct{} + +// ServiceImportStatus describes derived state of an imported service. +type ServiceImportStatus struct { + // +listType=atomic + Ports []v1.ServicePort `json:"ports"` + // ips will be used as the VIP(s) for this service when type is ClusterSetIP. + // +kubebuilder:validation:MaxItems:=1 + // +optional + IPs []string `json:"ips,omitempty"` + // type defines the type of this service. + // Must be "ClusterSetIP" or "Headless". + // The "ClusterSetIP" type reflects exported Service(s) with type ClusterIP + // and the "Headless" type reflects exported Service(s) with type Headless. + // A ServiceImport with type ClusterSetIP SHOULD populate `.status.ips` + // with virtual IP address(es) where the service can be reached from within + // the importing cluster. + // If exported Services of the same name and namespace in a given ClusterSet + // have differing types, a "Conflict" status condition SHOULD be reported in + // ServiceExport status. + // +kubebuilder:validation:Enum=ClusterSetIP;Headless + Type ServiceImportType `json:"type"` + // sessionAffinity is used to maintain client IP based session affinity. + // Supports "ClientIP" and "None". Defaults to "None". + // Reflects the `.spec.sessionAffinity` configuration of the underlying + // exported Service. Ignored when exported Service type is Headless. If + // exported Services of the same name and namespace in a given ClusterSet have + // differing session affinity configuration, a "Conflict" status condition + // SHOULD be reported in ServiceExport status. + // More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + // +optional + SessionAffinity v1.ServiceAffinity `json:"sessionAffinity,omitempty"` + // sessionAffinityConfig contains session affinity configuration. + // Reflects the `.spec.sessionAffinityConfig` configuration of the underlying + // exported Service. Ignored when exported Service type is "Headless". If + // exported Services of the same name and namespace in a given ClusterSet have + // differing session affinity configuration, a "Conflict" status condition + // SHOULD be reported in ServiceExport status. + // +optional + SessionAffinityConfig *v1.SessionAffinityConfig `json:"sessionAffinityConfig,omitempty"` + // clusters is the list of exporting clusters from which this service + // was derived. + // +optional + // +patchStrategy=merge + // +patchMergeKey=cluster + // +listType=map + // +listMapKey=cluster + Clusters []ClusterStatus `json:"clusters,omitempty"` +} + +// ClusterStatus contains service configuration mapped to a specific source cluster +type ClusterStatus struct { + // cluster is the name of the exporting cluster. Must be a valid RFC-1123 DNS + // label. + Cluster string `json:"cluster"` +} + +// +kubebuilder:object:root=true + +// ServiceImportList represents a list of endpoint slices +type ServiceImportList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + // List of endpoint slices + // +listType=set + Items []ServiceImport `json:"items"` +} diff --git a/pkg/apis/v1alpha2/well_known_labels.go b/pkg/apis/v1alpha2/well_known_labels.go new file mode 100644 index 0000000..130b09b --- /dev/null +++ b/pkg/apis/v1alpha2/well_known_labels.go @@ -0,0 +1,26 @@ +/* +Copyright 2020 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 v1alpha2 + +const ( + // LabelServiceName is used to indicate the name of multi-cluster service + // that an EndpointSlice belongs to. + LabelServiceName = "multicluster.kubernetes.io/service-name" + + // LabelSourceCluster is used to indicate the name of the cluster in which an exported resource exists. + LabelSourceCluster = "multicluster.kubernetes.io/source-cluster" +) diff --git a/pkg/apis/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/v1alpha2/zz_generated.deepcopy.go new file mode 100644 index 0000000..8dd9066 --- /dev/null +++ b/pkg/apis/v1alpha2/zz_generated.deepcopy.go @@ -0,0 +1,233 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2020 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 v1alpha2 + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceExport) DeepCopyInto(out *ServiceExport) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceExport. +func (in *ServiceExport) DeepCopy() *ServiceExport { + if in == nil { + return nil + } + out := new(ServiceExport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceExport) 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 *ServiceExportList) DeepCopyInto(out *ServiceExportList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServiceExport, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceExportList. +func (in *ServiceExportList) DeepCopy() *ServiceExportList { + if in == nil { + return nil + } + out := new(ServiceExportList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceExportList) 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 *ServiceExportStatus) DeepCopyInto(out *ServiceExportStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceExportStatus. +func (in *ServiceExportStatus) DeepCopy() *ServiceExportStatus { + if in == nil { + return nil + } + out := new(ServiceExportStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceImport) DeepCopyInto(out *ServiceImport) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceImport. +func (in *ServiceImport) DeepCopy() *ServiceImport { + if in == nil { + return nil + } + out := new(ServiceImport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceImport) 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 *ServiceImportList) DeepCopyInto(out *ServiceImportList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServiceImport, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceImportList. +func (in *ServiceImportList) DeepCopy() *ServiceImportList { + if in == nil { + return nil + } + out := new(ServiceImportList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceImportList) 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 *ServiceImportSpec) DeepCopyInto(out *ServiceImportSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceImportSpec. +func (in *ServiceImportSpec) DeepCopy() *ServiceImportSpec { + if in == nil { + return nil + } + out := new(ServiceImportSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceImportStatus) DeepCopyInto(out *ServiceImportStatus) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]corev1.ServicePort, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.IPs != nil { + in, out := &in.IPs, &out.IPs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SessionAffinityConfig != nil { + in, out := &in.SessionAffinityConfig, &out.SessionAffinityConfig + *out = new(corev1.SessionAffinityConfig) + (*in).DeepCopyInto(*out) + } + if in.Clusters != nil { + in, out := &in.Clusters, &out.Clusters + *out = make([]ClusterStatus, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceImportStatus. +func (in *ServiceImportStatus) DeepCopy() *ServiceImportStatus { + if in == nil { + return nil + } + out := new(ServiceImportStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/v1alpha2/zz_generated.register.go b/pkg/apis/v1alpha2/zz_generated.register.go new file mode 100644 index 0000000..f7be6aa --- /dev/null +++ b/pkg/apis/v1alpha2/zz_generated.register.go @@ -0,0 +1,72 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2020 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 = "multicluster.x-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 + // Deprecated: 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, + &ServiceExport{}, + &ServiceExportList{}, + &ServiceImport{}, + &ServiceImportList{}, + ) + // AddToGroupVersion allows the serialization of client types like ListOptions. + v1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} From 6c5f8daeb52a7dceb9d4144650ccc426ee0b89af Mon Sep 17 00:00:00 2001 From: Mike Morris <1149913+mikemorris@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:57:20 -0400 Subject: [PATCH 2/7] collapse spec/status to flatten ServiceImport definition --- pkg/apis/v1alpha2/serviceimport.go | 47 ++++++++++++------------------ 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/pkg/apis/v1alpha2/serviceimport.go b/pkg/apis/v1alpha2/serviceimport.go index 0a086ec..24b8e72 100644 --- a/pkg/apis/v1alpha2/serviceimport.go +++ b/pkg/apis/v1alpha2/serviceimport.go @@ -24,48 +24,29 @@ import ( // +genclient // +kubebuilder:object:root=true -// ServiceImport describes a service imported from clusters in a ClusterSet. +// ServiceImport describes a service imported from clusters in a ClusterSet and +// the information necessary to consume it. ServiceImport is managed by an MCS +// controller and should be updated automatically to show derived state as IP +// addresses or ServiceExport resources change. type ServiceImport struct { metav1.TypeMeta `json:",inline"` // +optional metav1.ObjectMeta `json:"metadata,omitempty"` - // spec defines the behavior of a ServiceImport. - // +optional - Spec ServiceImportSpec `json:"spec,omitempty"` - // status contains information about the exported services that form - // the multi-cluster service referenced by this ServiceImport. - // +optional - Status ServiceImportStatus `json:"status,omitempty"` -} - -// ServiceImportType designates the type of a ServiceImport -type ServiceImportType string - -const ( - // ClusterSetIP services are only accessible via the ClusterSet IP. - ClusterSetIP ServiceImportType = "ClusterSetIP" - // Headless services allow backend pods to be addressed directly. - Headless ServiceImportType = "Headless" -) - -// ServiceImportSpec describes an imported service and the information necessary to consume it. -type ServiceImportSpec struct{} - -// ServiceImportStatus describes derived state of an imported service. -type ServiceImportStatus struct { // +listType=atomic Ports []v1.ServicePort `json:"ports"` // ips will be used as the VIP(s) for this service when type is ClusterSetIP. - // +kubebuilder:validation:MaxItems:=1 + // +kubebuilder:validation:MaxItems:=2 // +optional IPs []string `json:"ips,omitempty"` // type defines the type of this service. // Must be "ClusterSetIP" or "Headless". // The "ClusterSetIP" type reflects exported Service(s) with type ClusterIP // and the "Headless" type reflects exported Service(s) with type Headless. - // A ServiceImport with type ClusterSetIP SHOULD populate `.status.ips` + // A ServiceImport with type ClusterSetIP SHOULD populate `.ips` // with virtual IP address(es) where the service can be reached from within - // the importing cluster. + // the importing cluster. These addresses MAY be endpoints directly reachable + // over a "flat" network between clusters, or MAY direct traffic through + // topology such as an intermediate east-west gateway. // If exported Services of the same name and namespace in a given ClusterSet // have differing types, a "Conflict" status condition SHOULD be reported in // ServiceExport status. @@ -99,6 +80,16 @@ type ServiceImportStatus struct { Clusters []ClusterStatus `json:"clusters,omitempty"` } +// ServiceImportType designates the type of a ServiceImport +type ServiceImportType string + +const ( + // ClusterSetIP services are only accessible via the ClusterSet IP. + ClusterSetIP ServiceImportType = "ClusterSetIP" + // Headless services allow backend pods to be addressed directly. + Headless ServiceImportType = "Headless" +) + // ClusterStatus contains service configuration mapped to a specific source cluster type ClusterStatus struct { // cluster is the name of the exporting cluster. Must be a valid RFC-1123 DNS From cdd27071e25ff49668c693996b8a6c7b1aad8010 Mon Sep 17 00:00:00 2001 From: Mike Morris <1149913+mikemorris@users.noreply.github.com> Date: Tue, 3 Sep 2024 13:19:37 -0400 Subject: [PATCH 3/7] add CEL kubebuilder validation for ClusterName --- pkg/apis/v1alpha2/serviceimport.go | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/pkg/apis/v1alpha2/serviceimport.go b/pkg/apis/v1alpha2/serviceimport.go index 24b8e72..e859e8c 100644 --- a/pkg/apis/v1alpha2/serviceimport.go +++ b/pkg/apis/v1alpha2/serviceimport.go @@ -92,11 +92,34 @@ const ( // ClusterStatus contains service configuration mapped to a specific source cluster type ClusterStatus struct { - // cluster is the name of the exporting cluster. Must be a valid RFC-1123 DNS - // label. - Cluster string `json:"cluster"` + // cluster is the name of the exporting cluster. + Cluster ClusterName `json:"cluster"` } +// ClusterName is the name of a cluster from which a service has been exported. +// Must be a valid RFC-1123 DNS label, which must consist of lower case +// alphanumeric characters, '-' or '.', and must start and end with an +// alphanumeric character. +// +// This validation is based off of the corresponding Kubernetes validation: +// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208 +// +// Valid values include: +// +// * "example" +// * "example-01" +// * "01-example.com" +// * "foo.example.com" +// +// Invalid values include: +// +// * "example.com/bar" - "/" is an invalid character +// +// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` +// +kubebuilder:validation:MinLength=1 +// +kubebuilder:validation:MaxLength=253 +type ClusterName string + // +kubebuilder:object:root=true // ServiceImportList represents a list of endpoint slices From 63386c7277483de5b0bbaa4a913bbd86e9c683a1 Mon Sep 17 00:00:00 2001 From: Mike Morris <1149913+mikemorris@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:13:43 -0400 Subject: [PATCH 4/7] update codegen --- pkg/apis/v1alpha2/zz_generated.deepcopy.go | 76 +++++++--------------- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/pkg/apis/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/v1alpha2/zz_generated.deepcopy.go index 8dd9066..e8603d0 100644 --- a/pkg/apis/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/v1alpha2/zz_generated.deepcopy.go @@ -126,8 +126,28 @@ func (in *ServiceImport) DeepCopyInto(out *ServiceImport) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]corev1.ServicePort, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.IPs != nil { + in, out := &in.IPs, &out.IPs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SessionAffinityConfig != nil { + in, out := &in.SessionAffinityConfig, &out.SessionAffinityConfig + *out = new(corev1.SessionAffinityConfig) + (*in).DeepCopyInto(*out) + } + if in.Clusters != nil { + in, out := &in.Clusters, &out.Clusters + *out = make([]ClusterStatus, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceImport. @@ -179,55 +199,3 @@ func (in *ServiceImportList) DeepCopyObject() runtime.Object { } return nil } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceImportSpec) DeepCopyInto(out *ServiceImportSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceImportSpec. -func (in *ServiceImportSpec) DeepCopy() *ServiceImportSpec { - if in == nil { - return nil - } - out := new(ServiceImportSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceImportStatus) DeepCopyInto(out *ServiceImportStatus) { - *out = *in - if in.Ports != nil { - in, out := &in.Ports, &out.Ports - *out = make([]corev1.ServicePort, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.IPs != nil { - in, out := &in.IPs, &out.IPs - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.SessionAffinityConfig != nil { - in, out := &in.SessionAffinityConfig, &out.SessionAffinityConfig - *out = new(corev1.SessionAffinityConfig) - (*in).DeepCopyInto(*out) - } - if in.Clusters != nil { - in, out := &in.Clusters, &out.Clusters - *out = make([]ClusterStatus, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceImportStatus. -func (in *ServiceImportStatus) DeepCopy() *ServiceImportStatus { - if in == nil { - return nil - } - out := new(ServiceImportStatus) - in.DeepCopyInto(out) - return out -} From df706d667078d0983755b54a352e686c9db9274b Mon Sep 17 00:00:00 2001 From: Arthur Outhenin-Chalandre Date: Tue, 3 Dec 2024 13:36:34 +0100 Subject: [PATCH 5/7] Applying PR suggestions Signed-off-by: Arthur Outhenin-Chalandre --- Makefile | 3 +- hack/update-codegen.sh | 12 +- pkg/apis/v1alpha1/serviceexport.go | 1 + pkg/apis/v1alpha1/serviceimport.go | 1 + pkg/apis/v1alpha2/doc.go | 4 +- pkg/apis/v1alpha2/zz_generated.register.go | 6 +- pkg/client/clientset/versioned/clientset.go | 13 ++ .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 2 + .../clientset/versioned/scheme/register.go | 2 + .../typed/apis/v1alpha2/apis_client.go | 112 ++++++++++ .../versioned/typed/apis/v1alpha2/doc.go | 20 ++ .../versioned/typed/apis/v1alpha2/fake/doc.go | 20 ++ .../apis/v1alpha2/fake/fake_apis_client.go | 44 ++++ .../apis/v1alpha2/fake/fake_serviceexport.go | 141 +++++++++++++ .../apis/v1alpha2/fake/fake_serviceimport.go | 129 ++++++++++++ .../apis/v1alpha2/generated_expansion.go | 23 +++ .../typed/apis/v1alpha2/serviceexport.go | 195 ++++++++++++++++++ .../typed/apis/v1alpha2/serviceimport.go | 178 ++++++++++++++++ .../externalversions/apis/interface.go | 8 + .../apis/v1alpha2/interface.go | 52 +++++ .../apis/v1alpha2/serviceexport.go | 90 ++++++++ .../apis/v1alpha2/serviceimport.go | 90 ++++++++ .../informers/externalversions/generic.go | 7 + .../apis/v1alpha2/expansion_generated.go | 35 ++++ .../listers/apis/v1alpha2/serviceexport.go | 99 +++++++++ .../listers/apis/v1alpha2/serviceimport.go | 99 +++++++++ 27 files changed, 1380 insertions(+), 13 deletions(-) create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/apis_client.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/doc.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/doc.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_apis_client.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceexport.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceimport.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/generated_expansion.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceexport.go create mode 100644 pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceimport.go create mode 100644 pkg/client/informers/externalversions/apis/v1alpha2/interface.go create mode 100644 pkg/client/informers/externalversions/apis/v1alpha2/serviceexport.go create mode 100644 pkg/client/informers/externalversions/apis/v1alpha2/serviceimport.go create mode 100644 pkg/client/listers/apis/v1alpha2/expansion_generated.go create mode 100644 pkg/client/listers/apis/v1alpha2/serviceexport.go create mode 100644 pkg/client/listers/apis/v1alpha2/serviceimport.go diff --git a/Makefile b/Makefile index d54d98f..837a38a 100644 --- a/Makefile +++ b/Makefile @@ -19,8 +19,7 @@ TOP := $(dir $(firstword $(MAKEFILE_LIST))) ROOT := $(abspath $(TOP)) # Image URL to use all building/pushing image targets IMG ?= mcs-api-controller:latest -# Need v1 to support defaults in CRDs, unfortunately limiting us to k8s 1.16+ -CRD_OPTIONS ?= "crd:crdVersions=v1" +CRD_OPTIONS ?= "crd" CONTROLLER_GEN=go -C tools run sigs.k8s.io/controller-tools/cmd/controller-gen # enable Go modules diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index d7a587f..64d08d0 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -28,7 +28,7 @@ gobin="${GOBIN:-$(go env GOPATH)/bin}" OUTPUT_PKG=sigs.k8s.io/mcs-api/pkg/client OUTPUT_DIR=$SCRIPT_ROOT/pkg/client -FQ_APIS=sigs.k8s.io/mcs-api/pkg/apis/v1alpha1 +FQ_APIS=(sigs.k8s.io/mcs-api/pkg/apis/v1alpha1 sigs.k8s.io/mcs-api/pkg/apis/v1alpha2) CLIENTSET_NAME=versioned CLIENTSET_PKG_NAME=clientset @@ -44,22 +44,22 @@ fi COMMON_FLAGS="--go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt" echo "Generating clientset at ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME}" -"${gobin}/client-gen" --clientset-name "${CLIENTSET_NAME}" --input-base "" --input "${FQ_APIS}" --output-pkg "${OUTPUT_PKG}/${CLIENTSET_PKG_NAME}" --output-dir "$OUTPUT_DIR/$CLIENTSET_PKG_NAME" ${COMMON_FLAGS} +"${gobin}/client-gen" --clientset-name "${CLIENTSET_NAME}" --input-base "" "${FQ_APIS[@]/#/--input=}" --output-pkg "${OUTPUT_PKG}/${CLIENTSET_PKG_NAME}" --output-dir "$OUTPUT_DIR/$CLIENTSET_PKG_NAME" ${COMMON_FLAGS} echo "Generating listers at ${OUTPUT_PKG}/listers" -"${gobin}/lister-gen" "${FQ_APIS}" --output-pkg "${OUTPUT_PKG}/listers" --output-dir "${OUTPUT_DIR}/listers" ${COMMON_FLAGS} +"${gobin}/lister-gen" "${FQ_APIS[@]}" --output-pkg "${OUTPUT_PKG}/listers" --output-dir "${OUTPUT_DIR}/listers" ${COMMON_FLAGS} echo "Generating informers at ${OUTPUT_PKG}/informers" "${gobin}/informer-gen" \ - "${FQ_APIS}" \ + "${FQ_APIS[@]}" \ --versioned-clientset-package "${OUTPUT_PKG}/${CLIENTSET_PKG_NAME}/${CLIENTSET_NAME}" \ --listers-package "${OUTPUT_PKG}/listers" \ --output-pkg "${OUTPUT_PKG}/informers" \ --output-dir "${OUTPUT_DIR}/informers" \ ${COMMON_FLAGS} -echo "Generating register at ${FQ_APIS}" -"${gobin}/register-gen" ${FQ_APIS} --output-file zz_generated.register.go ${COMMON_FLAGS} +echo "Generating register at" "${FQ_APIS[@]}" +"${gobin}/register-gen" "${FQ_APIS[@]}" --output-file zz_generated.register.go ${COMMON_FLAGS} if [[ "${VERIFY_CODEGEN:-}" == "true" ]]; then diff -urN "$ORIG_OUTPUT_DIR" "$OUTPUT_DIR" diff --git a/pkg/apis/v1alpha1/serviceexport.go b/pkg/apis/v1alpha1/serviceexport.go index 15e4d7b..874df26 100644 --- a/pkg/apis/v1alpha1/serviceexport.go +++ b/pkg/apis/v1alpha1/serviceexport.go @@ -22,6 +22,7 @@ import ( // +genclient // +kubebuilder:object:root=true +// +kubebuilder:storageversion // ServiceExport declares that the Service with the same name and namespace // as this export should be consumable from other clusters. diff --git a/pkg/apis/v1alpha1/serviceimport.go b/pkg/apis/v1alpha1/serviceimport.go index 11103da..238d612 100644 --- a/pkg/apis/v1alpha1/serviceimport.go +++ b/pkg/apis/v1alpha1/serviceimport.go @@ -23,6 +23,7 @@ import ( // +genclient // +kubebuilder:object:root=true +// +kubebuilder:storageversion // ServiceImport describes a service imported from clusters in a ClusterSet. type ServiceImport struct { diff --git a/pkg/apis/v1alpha2/doc.go b/pkg/apis/v1alpha2/doc.go index 64e70a4..f606edd 100644 --- a/pkg/apis/v1alpha2/doc.go +++ b/pkg/apis/v1alpha2/doc.go @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package v1alpha1 contains API schema definitions for the Multi-Cluster -// Services v1alpha1 API group. +// Package v1alpha2 contains API schema definitions for the Multi-Cluster +// Services v1alpha2 API group. // +kubebuilder:object:generate=true // +groupName=multicluster.x-k8s.io package v1alpha2 diff --git a/pkg/apis/v1alpha2/zz_generated.register.go b/pkg/apis/v1alpha2/zz_generated.register.go index f7be6aa..1657d28 100644 --- a/pkg/apis/v1alpha2/zz_generated.register.go +++ b/pkg/apis/v1alpha2/zz_generated.register.go @@ -19,7 +19,7 @@ limitations under the License. // Code generated by register-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -31,11 +31,11 @@ import ( const GroupName = "multicluster.x-k8s.io" // GroupVersion specifies the group and the version used to register the objects. -var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"} +var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha2"} // SchemeGroupVersion is group version used to register these objects // Deprecated: use GroupVersion instead. -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"} // Resource takes an unqualified resource and returns a Group qualified GroupResource func Resource(resource string) schema.GroupResource { diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index e4016d3..b9536d0 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -26,17 +26,20 @@ import ( rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" multiclusterv1alpha1 "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/typed/apis/v1alpha1" + multiclusterv1alpha2 "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/typed/apis/v1alpha2" ) type Interface interface { Discovery() discovery.DiscoveryInterface MulticlusterV1alpha1() multiclusterv1alpha1.MulticlusterV1alpha1Interface + MulticlusterV1alpha2() multiclusterv1alpha2.MulticlusterV1alpha2Interface } // Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient multiclusterV1alpha1 *multiclusterv1alpha1.MulticlusterV1alpha1Client + multiclusterV1alpha2 *multiclusterv1alpha2.MulticlusterV1alpha2Client } // MulticlusterV1alpha1 retrieves the MulticlusterV1alpha1Client @@ -44,6 +47,11 @@ func (c *Clientset) MulticlusterV1alpha1() multiclusterv1alpha1.MulticlusterV1al return c.multiclusterV1alpha1 } +// MulticlusterV1alpha2 retrieves the MulticlusterV1alpha2Client +func (c *Clientset) MulticlusterV1alpha2() multiclusterv1alpha2.MulticlusterV1alpha2Interface { + return c.multiclusterV1alpha2 +} + // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { @@ -92,6 +100,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.multiclusterV1alpha2, err = multiclusterv1alpha2.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) if err != nil { @@ -114,6 +126,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { func New(c rest.Interface) *Clientset { var cs Clientset cs.multiclusterV1alpha1 = multiclusterv1alpha1.New(c) + cs.multiclusterV1alpha2 = multiclusterv1alpha2.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 87ce5e7..ffc35ed 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -27,6 +27,8 @@ import ( clientset "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned" multiclusterv1alpha1 "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/typed/apis/v1alpha1" fakemulticlusterv1alpha1 "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/typed/apis/v1alpha1/fake" + multiclusterv1alpha2 "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/typed/apis/v1alpha2" + fakemulticlusterv1alpha2 "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake" ) // NewSimpleClientset returns a clientset that will respond with the provided objects. @@ -83,3 +85,8 @@ var ( func (c *Clientset) MulticlusterV1alpha1() multiclusterv1alpha1.MulticlusterV1alpha1Interface { return &fakemulticlusterv1alpha1.FakeMulticlusterV1alpha1{Fake: &c.Fake} } + +// MulticlusterV1alpha2 retrieves the MulticlusterV1alpha2Client +func (c *Clientset) MulticlusterV1alpha2() multiclusterv1alpha2.MulticlusterV1alpha2Interface { + return &fakemulticlusterv1alpha2.FakeMulticlusterV1alpha2{Fake: &c.Fake} +} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index a245e73..c8e807b 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -25,6 +25,7 @@ import ( serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" multiclusterv1alpha1 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" + multiclusterv1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" ) var scheme = runtime.NewScheme() @@ -32,6 +33,7 @@ var codecs = serializer.NewCodecFactory(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ multiclusterv1alpha1.AddToScheme, + multiclusterv1alpha2.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index c7c4237..d2139f8 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -25,6 +25,7 @@ import ( serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" multiclusterv1alpha1 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" + multiclusterv1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" ) var Scheme = runtime.NewScheme() @@ -32,6 +33,7 @@ var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ multiclusterv1alpha1.AddToScheme, + multiclusterv1alpha2.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/apis_client.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/apis_client.go new file mode 100644 index 0000000..ec965f9 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/apis_client.go @@ -0,0 +1,112 @@ +/* +Copyright 2020 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 v1alpha2 + +import ( + "net/http" + + rest "k8s.io/client-go/rest" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" + "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/scheme" +) + +type MulticlusterV1alpha2Interface interface { + RESTClient() rest.Interface + ServiceExportsGetter + ServiceImportsGetter +} + +// MulticlusterV1alpha2Client is used to interact with features provided by the multicluster.x-k8s.io group. +type MulticlusterV1alpha2Client struct { + restClient rest.Interface +} + +func (c *MulticlusterV1alpha2Client) ServiceExports(namespace string) ServiceExportInterface { + return newServiceExports(c, namespace) +} + +func (c *MulticlusterV1alpha2Client) ServiceImports(namespace string) ServiceImportInterface { + return newServiceImports(c, namespace) +} + +// NewForConfig creates a new MulticlusterV1alpha2Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*MulticlusterV1alpha2Client, 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 MulticlusterV1alpha2Client 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) (*MulticlusterV1alpha2Client, 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 &MulticlusterV1alpha2Client{client}, nil +} + +// NewForConfigOrDie creates a new MulticlusterV1alpha2Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *MulticlusterV1alpha2Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new MulticlusterV1alpha2Client for the given RESTClient. +func New(c rest.Interface) *MulticlusterV1alpha2Client { + return &MulticlusterV1alpha2Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha2.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 *MulticlusterV1alpha2Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/doc.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/doc.go new file mode 100644 index 0000000..545cbe5 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2020 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 v1alpha2 diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/doc.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/doc.go new file mode 100644 index 0000000..0243e68 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2020 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 diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_apis_client.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_apis_client.go new file mode 100644 index 0000000..c28bfb3 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_apis_client.go @@ -0,0 +1,44 @@ +/* +Copyright 2020 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" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/typed/apis/v1alpha2" +) + +type FakeMulticlusterV1alpha2 struct { + *testing.Fake +} + +func (c *FakeMulticlusterV1alpha2) ServiceExports(namespace string) v1alpha2.ServiceExportInterface { + return &FakeServiceExports{c, namespace} +} + +func (c *FakeMulticlusterV1alpha2) ServiceImports(namespace string) v1alpha2.ServiceImportInterface { + return &FakeServiceImports{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeMulticlusterV1alpha2) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceexport.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceexport.go new file mode 100644 index 0000000..4e070cd --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceexport.go @@ -0,0 +1,141 @@ +/* +Copyright 2020 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" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" +) + +// FakeServiceExports implements ServiceExportInterface +type FakeServiceExports struct { + Fake *FakeMulticlusterV1alpha2 + ns string +} + +var serviceexportsResource = v1alpha2.SchemeGroupVersion.WithResource("serviceexports") + +var serviceexportsKind = v1alpha2.SchemeGroupVersion.WithKind("ServiceExport") + +// Get takes name of the serviceExport, and returns the corresponding serviceExport object, and an error if there is any. +func (c *FakeServiceExports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ServiceExport, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(serviceexportsResource, c.ns, name), &v1alpha2.ServiceExport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceExport), err +} + +// List takes label and field selectors, and returns the list of ServiceExports that match those selectors. +func (c *FakeServiceExports) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ServiceExportList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(serviceexportsResource, serviceexportsKind, c.ns, opts), &v1alpha2.ServiceExportList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.ServiceExportList{ListMeta: obj.(*v1alpha2.ServiceExportList).ListMeta} + for _, item := range obj.(*v1alpha2.ServiceExportList).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 serviceExports. +func (c *FakeServiceExports) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(serviceexportsResource, c.ns, opts)) + +} + +// Create takes the representation of a serviceExport and creates it. Returns the server's representation of the serviceExport, and an error, if there is any. +func (c *FakeServiceExports) Create(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.CreateOptions) (result *v1alpha2.ServiceExport, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(serviceexportsResource, c.ns, serviceExport), &v1alpha2.ServiceExport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceExport), err +} + +// Update takes the representation of a serviceExport and updates it. Returns the server's representation of the serviceExport, and an error, if there is any. +func (c *FakeServiceExports) Update(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.UpdateOptions) (result *v1alpha2.ServiceExport, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(serviceexportsResource, c.ns, serviceExport), &v1alpha2.ServiceExport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceExport), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeServiceExports) UpdateStatus(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.UpdateOptions) (*v1alpha2.ServiceExport, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(serviceexportsResource, "status", c.ns, serviceExport), &v1alpha2.ServiceExport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceExport), err +} + +// Delete takes name of the serviceExport and deletes it. Returns an error if one occurs. +func (c *FakeServiceExports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(serviceexportsResource, c.ns, name, opts), &v1alpha2.ServiceExport{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeServiceExports) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(serviceexportsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha2.ServiceExportList{}) + return err +} + +// Patch applies the patch and returns the patched serviceExport. +func (c *FakeServiceExports) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ServiceExport, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(serviceexportsResource, c.ns, name, pt, data, subresources...), &v1alpha2.ServiceExport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceExport), err +} diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceimport.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceimport.go new file mode 100644 index 0000000..1f427d0 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/fake/fake_serviceimport.go @@ -0,0 +1,129 @@ +/* +Copyright 2020 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" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" +) + +// FakeServiceImports implements ServiceImportInterface +type FakeServiceImports struct { + Fake *FakeMulticlusterV1alpha2 + ns string +} + +var serviceimportsResource = v1alpha2.SchemeGroupVersion.WithResource("serviceimports") + +var serviceimportsKind = v1alpha2.SchemeGroupVersion.WithKind("ServiceImport") + +// Get takes name of the serviceImport, and returns the corresponding serviceImport object, and an error if there is any. +func (c *FakeServiceImports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ServiceImport, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(serviceimportsResource, c.ns, name), &v1alpha2.ServiceImport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceImport), err +} + +// List takes label and field selectors, and returns the list of ServiceImports that match those selectors. +func (c *FakeServiceImports) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ServiceImportList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(serviceimportsResource, serviceimportsKind, c.ns, opts), &v1alpha2.ServiceImportList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.ServiceImportList{ListMeta: obj.(*v1alpha2.ServiceImportList).ListMeta} + for _, item := range obj.(*v1alpha2.ServiceImportList).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 serviceImports. +func (c *FakeServiceImports) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(serviceimportsResource, c.ns, opts)) + +} + +// Create takes the representation of a serviceImport and creates it. Returns the server's representation of the serviceImport, and an error, if there is any. +func (c *FakeServiceImports) Create(ctx context.Context, serviceImport *v1alpha2.ServiceImport, opts v1.CreateOptions) (result *v1alpha2.ServiceImport, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(serviceimportsResource, c.ns, serviceImport), &v1alpha2.ServiceImport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceImport), err +} + +// Update takes the representation of a serviceImport and updates it. Returns the server's representation of the serviceImport, and an error, if there is any. +func (c *FakeServiceImports) Update(ctx context.Context, serviceImport *v1alpha2.ServiceImport, opts v1.UpdateOptions) (result *v1alpha2.ServiceImport, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(serviceimportsResource, c.ns, serviceImport), &v1alpha2.ServiceImport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceImport), err +} + +// Delete takes name of the serviceImport and deletes it. Returns an error if one occurs. +func (c *FakeServiceImports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(serviceimportsResource, c.ns, name, opts), &v1alpha2.ServiceImport{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeServiceImports) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(serviceimportsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha2.ServiceImportList{}) + return err +} + +// Patch applies the patch and returns the patched serviceImport. +func (c *FakeServiceImports) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ServiceImport, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(serviceimportsResource, c.ns, name, pt, data, subresources...), &v1alpha2.ServiceImport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ServiceImport), err +} diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/generated_expansion.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/generated_expansion.go new file mode 100644 index 0000000..ebaed81 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright 2020 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 v1alpha2 + +type ServiceExportExpansion interface{} + +type ServiceImportExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceexport.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceexport.go new file mode 100644 index 0000000..c39c5e1 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceexport.go @@ -0,0 +1,195 @@ +/* +Copyright 2020 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 v1alpha2 + +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" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" + scheme "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/scheme" +) + +// ServiceExportsGetter has a method to return a ServiceExportInterface. +// A group's client should implement this interface. +type ServiceExportsGetter interface { + ServiceExports(namespace string) ServiceExportInterface +} + +// ServiceExportInterface has methods to work with ServiceExport resources. +type ServiceExportInterface interface { + Create(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.CreateOptions) (*v1alpha2.ServiceExport, error) + Update(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.UpdateOptions) (*v1alpha2.ServiceExport, error) + UpdateStatus(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.UpdateOptions) (*v1alpha2.ServiceExport, 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) (*v1alpha2.ServiceExport, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ServiceExportList, 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 *v1alpha2.ServiceExport, err error) + ServiceExportExpansion +} + +// serviceExports implements ServiceExportInterface +type serviceExports struct { + client rest.Interface + ns string +} + +// newServiceExports returns a ServiceExports +func newServiceExports(c *MulticlusterV1alpha2Client, namespace string) *serviceExports { + return &serviceExports{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the serviceExport, and returns the corresponding serviceExport object, and an error if there is any. +func (c *serviceExports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ServiceExport, err error) { + result = &v1alpha2.ServiceExport{} + err = c.client.Get(). + Namespace(c.ns). + Resource("serviceexports"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ServiceExports that match those selectors. +func (c *serviceExports) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ServiceExportList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ServiceExportList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("serviceexports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested serviceExports. +func (c *serviceExports) 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(). + Namespace(c.ns). + Resource("serviceexports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a serviceExport and creates it. Returns the server's representation of the serviceExport, and an error, if there is any. +func (c *serviceExports) Create(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.CreateOptions) (result *v1alpha2.ServiceExport, err error) { + result = &v1alpha2.ServiceExport{} + err = c.client.Post(). + Namespace(c.ns). + Resource("serviceexports"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceExport). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a serviceExport and updates it. Returns the server's representation of the serviceExport, and an error, if there is any. +func (c *serviceExports) Update(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.UpdateOptions) (result *v1alpha2.ServiceExport, err error) { + result = &v1alpha2.ServiceExport{} + err = c.client.Put(). + Namespace(c.ns). + Resource("serviceexports"). + Name(serviceExport.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceExport). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *serviceExports) UpdateStatus(ctx context.Context, serviceExport *v1alpha2.ServiceExport, opts v1.UpdateOptions) (result *v1alpha2.ServiceExport, err error) { + result = &v1alpha2.ServiceExport{} + err = c.client.Put(). + Namespace(c.ns). + Resource("serviceexports"). + Name(serviceExport.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceExport). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the serviceExport and deletes it. Returns an error if one occurs. +func (c *serviceExports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("serviceexports"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *serviceExports) 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(). + Namespace(c.ns). + Resource("serviceexports"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched serviceExport. +func (c *serviceExports) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ServiceExport, err error) { + result = &v1alpha2.ServiceExport{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("serviceexports"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceimport.go b/pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceimport.go new file mode 100644 index 0000000..060f137 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apis/v1alpha2/serviceimport.go @@ -0,0 +1,178 @@ +/* +Copyright 2020 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 v1alpha2 + +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" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" + scheme "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned/scheme" +) + +// ServiceImportsGetter has a method to return a ServiceImportInterface. +// A group's client should implement this interface. +type ServiceImportsGetter interface { + ServiceImports(namespace string) ServiceImportInterface +} + +// ServiceImportInterface has methods to work with ServiceImport resources. +type ServiceImportInterface interface { + Create(ctx context.Context, serviceImport *v1alpha2.ServiceImport, opts v1.CreateOptions) (*v1alpha2.ServiceImport, error) + Update(ctx context.Context, serviceImport *v1alpha2.ServiceImport, opts v1.UpdateOptions) (*v1alpha2.ServiceImport, 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) (*v1alpha2.ServiceImport, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ServiceImportList, 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 *v1alpha2.ServiceImport, err error) + ServiceImportExpansion +} + +// serviceImports implements ServiceImportInterface +type serviceImports struct { + client rest.Interface + ns string +} + +// newServiceImports returns a ServiceImports +func newServiceImports(c *MulticlusterV1alpha2Client, namespace string) *serviceImports { + return &serviceImports{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the serviceImport, and returns the corresponding serviceImport object, and an error if there is any. +func (c *serviceImports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ServiceImport, err error) { + result = &v1alpha2.ServiceImport{} + err = c.client.Get(). + Namespace(c.ns). + Resource("serviceimports"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ServiceImports that match those selectors. +func (c *serviceImports) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ServiceImportList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ServiceImportList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("serviceimports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested serviceImports. +func (c *serviceImports) 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(). + Namespace(c.ns). + Resource("serviceimports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a serviceImport and creates it. Returns the server's representation of the serviceImport, and an error, if there is any. +func (c *serviceImports) Create(ctx context.Context, serviceImport *v1alpha2.ServiceImport, opts v1.CreateOptions) (result *v1alpha2.ServiceImport, err error) { + result = &v1alpha2.ServiceImport{} + err = c.client.Post(). + Namespace(c.ns). + Resource("serviceimports"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceImport). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a serviceImport and updates it. Returns the server's representation of the serviceImport, and an error, if there is any. +func (c *serviceImports) Update(ctx context.Context, serviceImport *v1alpha2.ServiceImport, opts v1.UpdateOptions) (result *v1alpha2.ServiceImport, err error) { + result = &v1alpha2.ServiceImport{} + err = c.client.Put(). + Namespace(c.ns). + Resource("serviceimports"). + Name(serviceImport.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceImport). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the serviceImport and deletes it. Returns an error if one occurs. +func (c *serviceImports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("serviceimports"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *serviceImports) 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(). + Namespace(c.ns). + Resource("serviceimports"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched serviceImport. +func (c *serviceImports) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ServiceImport, err error) { + result = &v1alpha2.ServiceImport{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("serviceimports"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/informers/externalversions/apis/interface.go b/pkg/client/informers/externalversions/apis/interface.go index 51f9c6c..299bb7d 100644 --- a/pkg/client/informers/externalversions/apis/interface.go +++ b/pkg/client/informers/externalversions/apis/interface.go @@ -20,6 +20,7 @@ package apis import ( v1alpha1 "sigs.k8s.io/mcs-api/pkg/client/informers/externalversions/apis/v1alpha1" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/client/informers/externalversions/apis/v1alpha2" internalinterfaces "sigs.k8s.io/mcs-api/pkg/client/informers/externalversions/internalinterfaces" ) @@ -27,6 +28,8 @@ import ( type Interface interface { // V1alpha1 provides access to shared informers for resources in V1alpha1. V1alpha1() v1alpha1.Interface + // V1alpha2 provides access to shared informers for resources in V1alpha2. + V1alpha2() v1alpha2.Interface } type group struct { @@ -44,3 +47,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (g *group) V1alpha1() v1alpha1.Interface { return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1alpha2 returns a new v1alpha2.Interface. +func (g *group) V1alpha2() v1alpha2.Interface { + return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/apis/v1alpha2/interface.go b/pkg/client/informers/externalversions/apis/v1alpha2/interface.go new file mode 100644 index 0000000..802ca0c --- /dev/null +++ b/pkg/client/informers/externalversions/apis/v1alpha2/interface.go @@ -0,0 +1,52 @@ +/* +Copyright 2020 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 v1alpha2 + +import ( + internalinterfaces "sigs.k8s.io/mcs-api/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ServiceExports returns a ServiceExportInformer. + ServiceExports() ServiceExportInformer + // ServiceImports returns a ServiceImportInformer. + ServiceImports() ServiceImportInformer +} + +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} +} + +// ServiceExports returns a ServiceExportInformer. +func (v *version) ServiceExports() ServiceExportInformer { + return &serviceExportInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ServiceImports returns a ServiceImportInformer. +func (v *version) ServiceImports() ServiceImportInformer { + return &serviceImportInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/informers/externalversions/apis/v1alpha2/serviceexport.go b/pkg/client/informers/externalversions/apis/v1alpha2/serviceexport.go new file mode 100644 index 0000000..bbaea04 --- /dev/null +++ b/pkg/client/informers/externalversions/apis/v1alpha2/serviceexport.go @@ -0,0 +1,90 @@ +/* +Copyright 2020 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 v1alpha2 + +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" + apisv1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" + versioned "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned" + internalinterfaces "sigs.k8s.io/mcs-api/pkg/client/informers/externalversions/internalinterfaces" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/client/listers/apis/v1alpha2" +) + +// ServiceExportInformer provides access to a shared informer and lister for +// ServiceExports. +type ServiceExportInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.ServiceExportLister +} + +type serviceExportInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewServiceExportInformer constructs a new informer for ServiceExport 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 NewServiceExportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredServiceExportInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredServiceExportInformer constructs a new informer for ServiceExport 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 NewFilteredServiceExportInformer(client versioned.Interface, namespace string, 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.MulticlusterV1alpha2().ServiceExports(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.MulticlusterV1alpha2().ServiceExports(namespace).Watch(context.TODO(), options) + }, + }, + &apisv1alpha2.ServiceExport{}, + resyncPeriod, + indexers, + ) +} + +func (f *serviceExportInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredServiceExportInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *serviceExportInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apisv1alpha2.ServiceExport{}, f.defaultInformer) +} + +func (f *serviceExportInformer) Lister() v1alpha2.ServiceExportLister { + return v1alpha2.NewServiceExportLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/apis/v1alpha2/serviceimport.go b/pkg/client/informers/externalversions/apis/v1alpha2/serviceimport.go new file mode 100644 index 0000000..384dbfe --- /dev/null +++ b/pkg/client/informers/externalversions/apis/v1alpha2/serviceimport.go @@ -0,0 +1,90 @@ +/* +Copyright 2020 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 v1alpha2 + +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" + apisv1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" + versioned "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned" + internalinterfaces "sigs.k8s.io/mcs-api/pkg/client/informers/externalversions/internalinterfaces" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/client/listers/apis/v1alpha2" +) + +// ServiceImportInformer provides access to a shared informer and lister for +// ServiceImports. +type ServiceImportInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.ServiceImportLister +} + +type serviceImportInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewServiceImportInformer constructs a new informer for ServiceImport 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 NewServiceImportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredServiceImportInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredServiceImportInformer constructs a new informer for ServiceImport 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 NewFilteredServiceImportInformer(client versioned.Interface, namespace string, 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.MulticlusterV1alpha2().ServiceImports(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.MulticlusterV1alpha2().ServiceImports(namespace).Watch(context.TODO(), options) + }, + }, + &apisv1alpha2.ServiceImport{}, + resyncPeriod, + indexers, + ) +} + +func (f *serviceImportInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredServiceImportInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *serviceImportInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apisv1alpha2.ServiceImport{}, f.defaultInformer) +} + +func (f *serviceImportInformer) Lister() v1alpha2.ServiceImportLister { + return v1alpha2.NewServiceImportLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 01b03b3..2bc8424 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -24,6 +24,7 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" v1alpha1 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" ) // GenericInformer is type of SharedIndexInformer which will locate and delegate to other @@ -58,6 +59,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v1alpha1.SchemeGroupVersion.WithResource("serviceimports"): return &genericInformer{resource: resource.GroupResource(), informer: f.Multicluster().V1alpha1().ServiceImports().Informer()}, nil + // Group=multicluster.x-k8s.io, Version=v1alpha2 + case v1alpha2.SchemeGroupVersion.WithResource("serviceexports"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Multicluster().V1alpha2().ServiceExports().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("serviceimports"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Multicluster().V1alpha2().ServiceImports().Informer()}, nil + } return nil, fmt.Errorf("no informer found for %v", resource) diff --git a/pkg/client/listers/apis/v1alpha2/expansion_generated.go b/pkg/client/listers/apis/v1alpha2/expansion_generated.go new file mode 100644 index 0000000..6c6b92f --- /dev/null +++ b/pkg/client/listers/apis/v1alpha2/expansion_generated.go @@ -0,0 +1,35 @@ +/* +Copyright 2020 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 v1alpha2 + +// ServiceExportListerExpansion allows custom methods to be added to +// ServiceExportLister. +type ServiceExportListerExpansion interface{} + +// ServiceExportNamespaceListerExpansion allows custom methods to be added to +// ServiceExportNamespaceLister. +type ServiceExportNamespaceListerExpansion interface{} + +// ServiceImportListerExpansion allows custom methods to be added to +// ServiceImportLister. +type ServiceImportListerExpansion interface{} + +// ServiceImportNamespaceListerExpansion allows custom methods to be added to +// ServiceImportNamespaceLister. +type ServiceImportNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/apis/v1alpha2/serviceexport.go b/pkg/client/listers/apis/v1alpha2/serviceexport.go new file mode 100644 index 0000000..e973050 --- /dev/null +++ b/pkg/client/listers/apis/v1alpha2/serviceexport.go @@ -0,0 +1,99 @@ +/* +Copyright 2020 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 v1alpha2 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" +) + +// ServiceExportLister helps list ServiceExports. +// All objects returned here must be treated as read-only. +type ServiceExportLister interface { + // List lists all ServiceExports in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ServiceExport, err error) + // ServiceExports returns an object that can list and get ServiceExports. + ServiceExports(namespace string) ServiceExportNamespaceLister + ServiceExportListerExpansion +} + +// serviceExportLister implements the ServiceExportLister interface. +type serviceExportLister struct { + indexer cache.Indexer +} + +// NewServiceExportLister returns a new ServiceExportLister. +func NewServiceExportLister(indexer cache.Indexer) ServiceExportLister { + return &serviceExportLister{indexer: indexer} +} + +// List lists all ServiceExports in the indexer. +func (s *serviceExportLister) List(selector labels.Selector) (ret []*v1alpha2.ServiceExport, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ServiceExport)) + }) + return ret, err +} + +// ServiceExports returns an object that can list and get ServiceExports. +func (s *serviceExportLister) ServiceExports(namespace string) ServiceExportNamespaceLister { + return serviceExportNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ServiceExportNamespaceLister helps list and get ServiceExports. +// All objects returned here must be treated as read-only. +type ServiceExportNamespaceLister interface { + // List lists all ServiceExports in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ServiceExport, err error) + // Get retrieves the ServiceExport from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ServiceExport, error) + ServiceExportNamespaceListerExpansion +} + +// serviceExportNamespaceLister implements the ServiceExportNamespaceLister +// interface. +type serviceExportNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ServiceExports in the indexer for a given namespace. +func (s serviceExportNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ServiceExport, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ServiceExport)) + }) + return ret, err +} + +// Get retrieves the ServiceExport from the indexer for a given namespace and name. +func (s serviceExportNamespaceLister) Get(name string) (*v1alpha2.ServiceExport, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("serviceexport"), name) + } + return obj.(*v1alpha2.ServiceExport), nil +} diff --git a/pkg/client/listers/apis/v1alpha2/serviceimport.go b/pkg/client/listers/apis/v1alpha2/serviceimport.go new file mode 100644 index 0000000..c579c80 --- /dev/null +++ b/pkg/client/listers/apis/v1alpha2/serviceimport.go @@ -0,0 +1,99 @@ +/* +Copyright 2020 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 v1alpha2 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" + v1alpha2 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha2" +) + +// ServiceImportLister helps list ServiceImports. +// All objects returned here must be treated as read-only. +type ServiceImportLister interface { + // List lists all ServiceImports in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ServiceImport, err error) + // ServiceImports returns an object that can list and get ServiceImports. + ServiceImports(namespace string) ServiceImportNamespaceLister + ServiceImportListerExpansion +} + +// serviceImportLister implements the ServiceImportLister interface. +type serviceImportLister struct { + indexer cache.Indexer +} + +// NewServiceImportLister returns a new ServiceImportLister. +func NewServiceImportLister(indexer cache.Indexer) ServiceImportLister { + return &serviceImportLister{indexer: indexer} +} + +// List lists all ServiceImports in the indexer. +func (s *serviceImportLister) List(selector labels.Selector) (ret []*v1alpha2.ServiceImport, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ServiceImport)) + }) + return ret, err +} + +// ServiceImports returns an object that can list and get ServiceImports. +func (s *serviceImportLister) ServiceImports(namespace string) ServiceImportNamespaceLister { + return serviceImportNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ServiceImportNamespaceLister helps list and get ServiceImports. +// All objects returned here must be treated as read-only. +type ServiceImportNamespaceLister interface { + // List lists all ServiceImports in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ServiceImport, err error) + // Get retrieves the ServiceImport from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ServiceImport, error) + ServiceImportNamespaceListerExpansion +} + +// serviceImportNamespaceLister implements the ServiceImportNamespaceLister +// interface. +type serviceImportNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ServiceImports in the indexer for a given namespace. +func (s serviceImportNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ServiceImport, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ServiceImport)) + }) + return ret, err +} + +// Get retrieves the ServiceImport from the indexer for a given namespace and name. +func (s serviceImportNamespaceLister) Get(name string) (*v1alpha2.ServiceImport, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("serviceimport"), name) + } + return obj.(*v1alpha2.ServiceImport), nil +} From 63207d654d97c23d3674cd249c900143b8de251b Mon Sep 17 00:00:00 2001 From: Arthur Outhenin-Chalandre Date: Tue, 3 Dec 2024 13:50:29 +0100 Subject: [PATCH 6/7] Fix generation of crd with v1alpha2 Signed-off-by: Arthur Outhenin-Chalandre --- Makefile | 2 +- .../multicluster.x-k8s.io_serviceexports.yaml | 132 ++++- .../multicluster.x-k8s.io_serviceimports.yaml | 175 ++++++- .../multicluster.x-k8s.io_serviceexports.yaml | 358 ++++++++----- .../multicluster.x-k8s.io_serviceimports.yaml | 486 ++++++++++++------ 5 files changed, 826 insertions(+), 327 deletions(-) diff --git a/Makefile b/Makefile index 837a38a..c24ff91 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ generate: # Generate manifests e.g. CRD, RBAC etc. .PHONY: manifests manifests: - $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=mcs-derived-service-manager output:rbac:dir="$(ROOT)/config/rbac" webhook schemapatch:manifests="$(ROOT)/config/crd-base" paths="$(ROOT)/..." output:crd:none output:schemapatch:dir="$(ROOT)/config/crd" + $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=mcs-derived-service-manager output:rbac:dir="$(ROOT)/config/rbac" webhook schemapatch:manifests="$(ROOT)/config/crd-base" paths="$(ROOT)/..." output:crd:dir="$(ROOT)/config/crd" output:schemapatch:dir="$(ROOT)/config/crd-base" # Run tests .PHONY: test diff --git a/config/crd-base/multicluster.x-k8s.io_serviceexports.yaml b/config/crd-base/multicluster.x-k8s.io_serviceexports.yaml index de1943a..21e291d 100644 --- a/config/crd-base/multicluster.x-k8s.io_serviceexports.yaml +++ b/config/crd-base/multicluster.x-k8s.io_serviceexports.yaml @@ -23,14 +23,126 @@ spec: singular: serviceexport kind: ServiceExport shortNames: - - svcex + - svcex versions: - - name: v1alpha1 - served: true - storage: true - subresources: - status: {} - additionalPrinterColumns: - - name: Age - type: date - jsonPath: .metadata.creationTimestamp + - name: v1alpha1 + served: true + storage: true + subresources: + status: {} + additionalPrinterColumns: + - name: Age + type: date + jsonPath: .metadata.creationTimestamp + "schema": + "openAPIV3Schema": + description: |- + ServiceExport declares that the Service with the same name and namespace + as this export should be consumable from other clusters. + 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 + status: + description: |- + status describes the current state of an exported service. + Service configuration comes from the Service that had the same + name and namespace as this ServiceExport. + Populated by the multi-cluster service implementation's controller. + type: object + properties: + conditions: + 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"` + + + // 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])$ + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map diff --git a/config/crd-base/multicluster.x-k8s.io_serviceimports.yaml b/config/crd-base/multicluster.x-k8s.io_serviceimports.yaml index 22943e9..7ea4f81 100644 --- a/config/crd-base/multicluster.x-k8s.io_serviceimports.yaml +++ b/config/crd-base/multicluster.x-k8s.io_serviceimports.yaml @@ -23,22 +23,161 @@ spec: singular: serviceimport kind: ServiceImport shortNames: - - svcim + - svcim versions: - - name: v1alpha1 - served: true - storage: true - subresources: - status: {} - additionalPrinterColumns: - - name: Type - type: string - description: The type of this ServiceImport - jsonPath: .spec.type - - name: IP - type: string - description: The VIP for this ServiceImport - jsonPath: .spec.ips - - name: Age - type: date - jsonPath: .metadata.creationTimestamp + - name: v1alpha1 + served: true + storage: true + subresources: + status: {} + additionalPrinterColumns: + - name: Type + type: string + description: The type of this ServiceImport + jsonPath: .spec.type + - name: IP + type: string + description: The VIP for this ServiceImport + jsonPath: .spec.ips + - name: Age + type: date + jsonPath: .metadata.creationTimestamp + "schema": + "openAPIV3Schema": + description: ServiceImport describes a service imported from clusters in a ClusterSet. + 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 behavior of a ServiceImport. + type: object + required: + - ports + - type + properties: + ips: + description: ip will be used as the VIP for this service when type is ClusterSetIP. + type: array + maxItems: 1 + items: + type: string + ports: + type: array + items: + description: ServicePort represents the port on which the service is exposed + type: object + required: + - port + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + Field can be enabled with ServiceAppProtocol feature gate. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + port: + description: The port that will be exposed by this service. + type: integer + format: int32 + protocol: + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + default: TCP + x-kubernetes-list-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + Ignored when type is Headless + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains session affinity configuration. + type: object + properties: + clientIP: + description: clientIP contains the configurations of Client IP based session affinity. + type: object + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + type: integer + format: int32 + type: + description: |- + type defines the type of this service. + Must be ClusterSetIP or Headless. + type: string + enum: + - ClusterSetIP + - Headless + status: + description: |- + status contains information about the exported services that form + the multi-cluster service referenced by this ServiceImport. + type: object + properties: + clusters: + description: |- + clusters is the list of exporting clusters from which this service + was derived. + type: array + items: + description: ClusterStatus contains service configuration mapped to a specific source cluster + type: object + required: + - cluster + properties: + cluster: + description: |- + cluster is the name of the exporting cluster. Must be a valid RFC-1123 DNS + label. + type: string + x-kubernetes-list-map-keys: + - cluster + x-kubernetes-list-type: map diff --git a/config/crd/multicluster.x-k8s.io_serviceexports.yaml b/config/crd/multicluster.x-k8s.io_serviceexports.yaml index 21e291d..01d6df9 100644 --- a/config/crd/multicluster.x-k8s.io_serviceexports.yaml +++ b/config/crd/multicluster.x-k8s.io_serviceexports.yaml @@ -1,148 +1,230 @@ -# Copyright 2020 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. +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 name: serviceexports.multicluster.x-k8s.io spec: group: multicluster.x-k8s.io - scope: Namespaced names: + kind: ServiceExport + listKind: ServiceExportList plural: serviceexports singular: serviceexport - kind: ServiceExport - shortNames: - - svcex + scope: Namespaced versions: - - name: v1alpha1 - served: true - storage: true - subresources: - status: {} - additionalPrinterColumns: - - name: Age - type: date - jsonPath: .metadata.creationTimestamp - "schema": - "openAPIV3Schema": - description: |- - ServiceExport declares that the Service with the same name and namespace - as this export should be consumable from other clusters. - 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 - status: - description: |- - status describes the current state of an exported service. - Service configuration comes from the Service that had the same - name and namespace as this ServiceExport. - Populated by the multi-cluster service implementation's controller. - type: object - properties: - conditions: - 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"` - - - // 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])$ - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ServiceExport declares that the Service with the same name and namespace + as this export should be consumable from other clusters. + 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 + status: + description: |- + status describes the current state of an exported service. + Service configuration comes from the Service that had the same + name and namespace as this ServiceExport. + Populated by the multi-cluster service implementation's controller. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + 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. + format: int64 + minimum: 0 + type: integer + 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. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + 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) + 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])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + - name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + ServiceExport declares that the Service with the same name and namespace + as this export should be consumable from other clusters. + 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 + status: + description: |- + status describes the current state of an exported service. + Service configuration comes from the Service that had the same + name and namespace as this ServiceExport. + Populated by the multi-cluster service implementation's controller. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + 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. + format: int64 + minimum: 0 + type: integer + 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. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + 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) + 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])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: false diff --git a/config/crd/multicluster.x-k8s.io_serviceimports.yaml b/config/crd/multicluster.x-k8s.io_serviceimports.yaml index 7ea4f81..6b9c2c5 100644 --- a/config/crd/multicluster.x-k8s.io_serviceimports.yaml +++ b/config/crd/multicluster.x-k8s.io_serviceimports.yaml @@ -1,183 +1,349 @@ -# Copyright 2020 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. +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 name: serviceimports.multicluster.x-k8s.io spec: group: multicluster.x-k8s.io - scope: Namespaced names: + kind: ServiceImport + listKind: ServiceImportList plural: serviceimports singular: serviceimport - kind: ServiceImport - shortNames: - - svcim + scope: Namespaced versions: - - name: v1alpha1 - served: true - storage: true - subresources: - status: {} - additionalPrinterColumns: - - name: Type - type: string - description: The type of this ServiceImport - jsonPath: .spec.type - - name: IP - type: string - description: The VIP for this ServiceImport - jsonPath: .spec.ips - - name: Age - type: date - jsonPath: .metadata.creationTimestamp - "schema": - "openAPIV3Schema": - description: ServiceImport describes a service imported from clusters in a ClusterSet. - 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 behavior of a ServiceImport. - type: object - required: - - ports - - type - properties: - ips: - description: ip will be used as the VIP for this service when type is ClusterSetIP. - type: array - maxItems: 1 - items: - type: string - ports: - type: array - items: - description: ServicePort represents the port on which the service is exposed - type: object - required: - - port - properties: - appProtocol: - description: |- - The application protocol for this port. - This is used as a hint for implementations to offer richer behavior for protocols that they understand. - This field follows standard Kubernetes label syntax. - Valid values are either: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ServiceImport describes a service imported from clusters in a + ClusterSet. + 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 behavior of a ServiceImport. + properties: + ips: + description: ip will be used as the VIP for this service when type + is ClusterSetIP. + items: + type: string + maxItems: 1 + type: array + ports: + items: + description: ServicePort represents the port on which the service + is exposed + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: - * Un-prefixed protocol names - reserved for IANA standard service names (as per - RFC-6335 and https://www.iana.org/assignments/service-names). + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). - * Kubernetes-defined prefixed names: - * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 - * Other protocols should use implementation-defined prefixed names such as - mycompany.com/my-custom-protocol. - Field can be enabled with ServiceAppProtocol feature gate. - type: string - name: + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + Field can be enabled with ServiceAppProtocol feature gate. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + Ignored when type is Headless + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains session affinity configuration. + properties: + clientIP: + description: clientIP contains the configurations of Client IP + based session affinity. + properties: + timeoutSeconds: description: |- - The name of this port within the service. This must be a DNS_LABEL. - All ports within a ServiceSpec must have unique names. When considering - the endpoints for a Service, this must match the 'name' field in the - EndpointPort. - Optional if only one ServicePort is defined on this service. - type: string - port: - description: The port that will be exposed by this service. - type: integer + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). format: int32 - protocol: - description: |- - The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". - Default is TCP. - type: string - default: TCP - x-kubernetes-list-type: atomic - sessionAffinity: - description: |- - Supports "ClientIP" and "None". Used to maintain session affinity. - Enable client IP based session affinity. - Must be ClientIP or None. - Defaults to None. - Ignored when type is Headless - More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies - type: string - sessionAffinityConfig: - description: sessionAffinityConfig contains session affinity configuration. - type: object + type: integer + type: object + type: object + type: + description: |- + type defines the type of this service. + Must be ClusterSetIP or Headless. + enum: + - ClusterSetIP + - Headless + type: string + required: + - ports + - type + type: object + status: + description: |- + status contains information about the exported services that form + the multi-cluster service referenced by this ServiceImport. + properties: + clusters: + description: |- + clusters is the list of exporting clusters from which this service + was derived. + items: + description: ClusterStatus contains service configuration mapped + to a specific source cluster properties: - clientIP: - description: clientIP contains the configurations of Client IP based session affinity. - type: object - properties: - timeoutSeconds: - description: |- - timeoutSeconds specifies the seconds of ClientIP type session sticky time. - The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". - Default value is 10800(for 3 hours). - type: integer - format: int32 - type: - description: |- - type defines the type of this service. - Must be ClusterSetIP or Headless. + cluster: + description: |- + cluster is the name of the exporting cluster. Must be a valid RFC-1123 DNS + label. + type: string + required: + - cluster + type: object + type: array + x-kubernetes-list-map-keys: + - cluster + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + - name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + ServiceImport describes a service imported from clusters in a ClusterSet and + the information necessary to consume it. ServiceImport is managed by an MCS + controller and should be updated automatically to show derived state as IP + addresses or ServiceExport resources change. + 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 + clusters: + description: |- + clusters is the list of exporting clusters from which this service + was derived. + items: + description: ClusterStatus contains service configuration mapped to + a specific source cluster + properties: + cluster: + description: cluster is the name of the exporting cluster. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string - enum: - - ClusterSetIP - - Headless - status: - description: |- - status contains information about the exported services that form - the multi-cluster service referenced by this ServiceImport. + required: + - cluster type: object + type: array + x-kubernetes-list-map-keys: + - cluster + x-kubernetes-list-type: map + ips: + description: ips will be used as the VIP(s) for this service when type + is ClusterSetIP. + items: + type: string + maxItems: 2 + type: array + 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 + ports: + items: + description: ServicePort contains information on service's port. properties: - clusters: + appProtocol: description: |- - clusters is the list of exporting clusters from which this service - was derived. - type: array - items: - description: ClusterStatus contains service configuration mapped to a specific source cluster - type: object - required: - - cluster - properties: - cluster: - description: |- - cluster is the name of the exporting cluster. Must be a valid RFC-1123 DNS - label. - type: string - x-kubernetes-list-map-keys: - - cluster - x-kubernetes-list-type: map + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + sessionAffinity: + description: |- + sessionAffinity is used to maintain client IP based session affinity. + Supports "ClientIP" and "None". Defaults to "None". + Reflects the `.spec.sessionAffinity` configuration of the underlying + exported Service. Ignored when exported Service type is Headless. If + exported Services of the same name and namespace in a given ClusterSet have + differing session affinity configuration, a "Conflict" status condition + SHOULD be reported in ServiceExport status. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: |- + sessionAffinityConfig contains session affinity configuration. + Reflects the `.spec.sessionAffinityConfig` configuration of the underlying + exported Service. Ignored when exported Service type is "Headless". If + exported Services of the same name and namespace in a given ClusterSet have + differing session affinity configuration, a "Conflict" status condition + SHOULD be reported in ServiceExport status. + properties: + clientIP: + description: clientIP contains the configurations of Client IP based + session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type defines the type of this service. + Must be "ClusterSetIP" or "Headless". + The "ClusterSetIP" type reflects exported Service(s) with type ClusterIP + and the "Headless" type reflects exported Service(s) with type Headless. + A ServiceImport with type ClusterSetIP SHOULD populate `.ips` + with virtual IP address(es) where the service can be reached from within + the importing cluster. These addresses MAY be endpoints directly reachable + over a "flat" network between clusters, or MAY direct traffic through + topology such as an intermediate east-west gateway. + If exported Services of the same name and namespace in a given ClusterSet + have differing types, a "Conflict" status condition SHOULD be reported in + ServiceExport status. + enum: + - ClusterSetIP + - Headless + type: string + required: + - ports + - type + type: object + served: true + storage: false From 0e449b4c09eb92c0823756a3bd93ebaf7b8f5dd8 Mon Sep 17 00:00:00 2001 From: Arthur Outhenin-Chalandre Date: Tue, 3 Dec 2024 14:22:59 +0100 Subject: [PATCH 7/7] add convenient short name Signed-off-by: Arthur Outhenin-Chalandre --- config/crd/multicluster.x-k8s.io_serviceexports.yaml | 3 +++ config/crd/multicluster.x-k8s.io_serviceimports.yaml | 3 +++ pkg/apis/v1alpha1/serviceexport.go | 1 + pkg/apis/v1alpha1/serviceimport.go | 1 + pkg/apis/v1alpha2/serviceexport.go | 1 + pkg/apis/v1alpha2/serviceimport.go | 1 + 6 files changed, 10 insertions(+) diff --git a/config/crd/multicluster.x-k8s.io_serviceexports.yaml b/config/crd/multicluster.x-k8s.io_serviceexports.yaml index 01d6df9..d13b7da 100644 --- a/config/crd/multicluster.x-k8s.io_serviceexports.yaml +++ b/config/crd/multicluster.x-k8s.io_serviceexports.yaml @@ -11,6 +11,9 @@ spec: kind: ServiceExport listKind: ServiceExportList plural: serviceexports + shortNames: + - svcexport + - svcex singular: serviceexport scope: Namespaced versions: diff --git a/config/crd/multicluster.x-k8s.io_serviceimports.yaml b/config/crd/multicluster.x-k8s.io_serviceimports.yaml index 6b9c2c5..ab4bd07 100644 --- a/config/crd/multicluster.x-k8s.io_serviceimports.yaml +++ b/config/crd/multicluster.x-k8s.io_serviceimports.yaml @@ -11,6 +11,9 @@ spec: kind: ServiceImport listKind: ServiceImportList plural: serviceimports + shortNames: + - svcimport + - svcim singular: serviceimport scope: Namespaced versions: diff --git a/pkg/apis/v1alpha1/serviceexport.go b/pkg/apis/v1alpha1/serviceexport.go index 874df26..2f7b407 100644 --- a/pkg/apis/v1alpha1/serviceexport.go +++ b/pkg/apis/v1alpha1/serviceexport.go @@ -23,6 +23,7 @@ import ( // +genclient // +kubebuilder:object:root=true // +kubebuilder:storageversion +// +kubebuilder:resource:shortName={svcexport,svcex} // ServiceExport declares that the Service with the same name and namespace // as this export should be consumable from other clusters. diff --git a/pkg/apis/v1alpha1/serviceimport.go b/pkg/apis/v1alpha1/serviceimport.go index 238d612..82fafd0 100644 --- a/pkg/apis/v1alpha1/serviceimport.go +++ b/pkg/apis/v1alpha1/serviceimport.go @@ -24,6 +24,7 @@ import ( // +genclient // +kubebuilder:object:root=true // +kubebuilder:storageversion +// +kubebuilder:resource:shortName={svcimport,svcim} // ServiceImport describes a service imported from clusters in a ClusterSet. type ServiceImport struct { diff --git a/pkg/apis/v1alpha2/serviceexport.go b/pkg/apis/v1alpha2/serviceexport.go index d081fcd..25cc255 100644 --- a/pkg/apis/v1alpha2/serviceexport.go +++ b/pkg/apis/v1alpha2/serviceexport.go @@ -22,6 +22,7 @@ import ( // +genclient // +kubebuilder:object:root=true +// +kubebuilder:resource:shortName={svcexport,svcex} // ServiceExport declares that the Service with the same name and namespace // as this export should be consumable from other clusters. diff --git a/pkg/apis/v1alpha2/serviceimport.go b/pkg/apis/v1alpha2/serviceimport.go index e859e8c..4ca240e 100644 --- a/pkg/apis/v1alpha2/serviceimport.go +++ b/pkg/apis/v1alpha2/serviceimport.go @@ -23,6 +23,7 @@ import ( // +genclient // +kubebuilder:object:root=true +// +kubebuilder:resource:shortName={svcimport,svcim} // ServiceImport describes a service imported from clusters in a ClusterSet and // the information necessary to consume it. ServiceImport is managed by an MCS