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.
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. */
// This package imports things required by build scripts, to force `go mod` to see them as dependencies package tools
[root@master controller-tools-demo]# type-scaffold --kind=App // AppSpec defines the desired state of App type AppSpec struct { // INSERT ADDITIONAL SPEC FIELDS -- desired state of cluster }
// AppStatus defines the observed state of App. // It should always be reconstructable from the state of the cluster and/or outside world. type AppStatus struct { // INSERT ADDITIONAL STATUS FIELDS -- observed state of cluster }
// App is the Schema for the apps API // +k8s:openapi-gen=true type App struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"`
Spec AppSpec `json:"spec,omitempty"` Status AppStatus `json:"status,omitempty"` }
// AppList contains a list of App type AppList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []App `json:"items"` }
// AppSpec defines the desired state of App type AppSpec struct { // INSERT ADDITIONAL SPEC FIELDS -- desired state of cluster }
// AppStatus defines the observed state of App. // It should always be reconstructable from the state of the cluster and/or outside world. type AppStatus struct { // INSERT ADDITIONAL STATUS FIELDS -- observed state of cluster }
// App is the Schema for the apps API // +k8s:openapi-gen=true type App struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"`
Spec AppSpec `json:"spec,omitempty"` Status AppStatus `json:"status,omitempty"` }
// AppList contains a list of App type AppList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []App `json:"items"` }
// App is the Schema for the apps API type App struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"`
Spec AppSpec `json:"spec,omitempty"` Status AppStatus `json:"status,omitempty"` }
// AppSpec defines the desired state of App type AppSpec struct { DeploymentSpec DeploymentTemplate `json:"deploymentTemplate,omitempty"` ServiceSpec ServiceTemplate `json:"serviceTemplate,omitempty"` }
type DeploymentTemplate struct { Name string `json:"name"` Image string `json:"image"` Replicas int32 `json:"replicas"` }
type ServiceTemplate struct { Name string `json:"name"` }
// AppStatus defines the observed state of App. // It should always be reconstructable from the state of the cluster and/or outside world. type AppStatus struct { DeploymentStatus *appsv1.DeploymentStatus `json:"deploymentStatus,omitempty"` ServiceStatus *corev1.ServiceStatus `json:"serviceStatus,omitempty"` }
// AppList contains a list of App type AppList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []App `json:"items"` }
使用controller-gen生成 deepcopy 文件
执行命令
1 2
cd crd-controller-demo controller-gen object paths=pkg/apis/appcontroller/v1/types.go
# Copyright 2017 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.
# 设置脚本在执行过程中遇到任何错误时立即退出 set -o errexit # 设置脚本在使用未定义的变量时立即退出 set -o nounset # 设置脚本在管道命令中任意一条命令失败时立即退出 set -o pipefail
# 调用脚本生成代码 $ cd hack && ./update-codegen.sh Generating clientset for appcontroller:v1 at crd-controller-demo/pkg/generated/clientset Generating listers for appcontroller:v1 at crd-controller-demo/pkg/generated/listers Generating informers for appcontroller:v1 at crd-controller-demo/pkg/generated/informers
--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: (devel) api-approved.kubernetes.io: "https://github.com/kubernetes/kubernetes/pull/78458" creationTimestamp: null name: apps.appcontroller.k8s.io spec: group: appcontroller.k8s.io names: kind: App listKind: AppList plural: apps singular: app scope: Namespaced versions: - name: v1 schema: openAPIV3Schema: description: App is the Schema for the apps API properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object spec: description: AppSpec defines the desired state of App properties: deploymentTemplate: properties: image: type: string name: type: string replicas: format: int32 type: integer required: - image - name - replicas type: object serviceTemplate: properties: name: type: string required: - name type: object type: object status: description: AppStatus defines the observed state of App. It should always be reconstructable from the state of the cluster and/or outside world. properties: deploymentStatus: description: DeploymentStatus is the most recently observed status of the Deployment. properties: availableReplicas: description: Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. format: int32 type: integer collisionCount: description: Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet. format: int32 type: integer conditions: description: Represents the latest available observations of a deployment's current state. items: description: DeploymentCondition describes the state of a deployment at a certain point. properties: lastTransitionTime: description: Last time the condition transitioned from one status to another. format: date-time type: string lastUpdateTime: description: The last time this condition was updated. format: date-time type: string message: description: A human readable message indicating details about the transition. type: string reason: description: The reason for the condition's last transition. type: string status: description: Status of the condition, one of True, False, Unknown. type: string type: description: Type of deployment condition. type: string required: - status - type type: object type: array observedGeneration: description: The generation observed by the deployment controller. format: int64 type: integer readyReplicas: description: readyReplicas is the number of pods targeted by this Deployment with a Ready Condition. format: int32 type: integer replicas: description: Total number of non-terminated pods targeted by this deployment (their labels match the selector). format: int32 type: integer unavailableReplicas: description: Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created. format: int32 type: integer updatedReplicas: description: Total number of non-terminated pods targeted by this deployment that have the desired template spec. format: int32 type: integer type: object serviceStatus: description: ServiceStatus represents the current status of a service. properties: conditions: description: Current service state 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, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" 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 loadBalancer: description: LoadBalancer contains the current status of the load-balancer, if one is present. properties: ingress: description: Ingress is a list containing ingress points for the load-balancer. Traffic intended for the service should be sent to these ingress points. items: description: 'LoadBalancerIngress represents the status of a load-balancer ingress point: traffic intended for the service should be sent to an ingress point.' properties: hostname: description: Hostname is set for load-balancer ingress points that are DNS based (typically AWS load-balancers) type: string ip: description: IP is set for load-balancer ingress points that are IP based (typically GCE or OpenStack load-balancers) type: string ipMode: description: IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified. Setting this to "VIP" indicates that traffic is delivered to the node with the destination set to the load-balancer's IP and port. Setting this to "Proxy" indicates that traffic is delivered to the node or pod with the destination set to the node's IP and node port or the pod's IP and port. Service implementations may use this information to adjust traffic routing. type: string ports: description: Ports is a list of records of service ports If used, every port defined in the service should have an entry in it items: properties: error: description: 'Error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use CamelCase names - cloud provider specific error values must have names that comply with the format foo.example.com/CamelCase. --- 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 port: description: Port is the port number of the service port of which status is recorded here format: int32 type: integer protocol: default: TCP description: 'Protocol is the protocol of the service port of which status is recorded here The supported values are: "TCP", "UDP", "SCTP"' type: string required: - port - protocol type: object type: array x-kubernetes-list-type: atomic type: object type: array type: object type: object type: object type: object served: true storage: true
// SchemeGroupVersion is group version used to register these objects var SchemeGroupVersion = schema.GroupVersion{Group: appcontroller.GroupName, Version: "v1"}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind func Kind(kind string) schema.GroupKind { return SchemeGroupVersion.WithKind(kind).GroupKind() }
// Resource takes an unqualified resource and returns a Group qualified GroupResource func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() }
var ( // SchemeBuilder initializes a scheme builder SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) // AddToScheme is a global function that registers this API group & version to a scheme AddToScheme = SchemeBuilder.AddToScheme )
// Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &App{}, &AppList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil }