Merge pull request #70031 from nrfox/requeue-on-error

Sample Controller: requeue work item on syncHandler error

Kubernetes-commit: b7b0aae4358065b98a3db04411bec65a11eb166e
This commit is contained in:
Kubernetes Publisher
2018-10-27 03:19:59 -07:00
39 changed files with 969 additions and 1637 deletions
+244 -244
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -219,7 +219,9 @@ func (c *Controller) processNextWorkItem() bool {
// Run the syncHandler, passing it the namespace/name string of the // Run the syncHandler, passing it the namespace/name string of the
// Foo resource to be synced. // Foo resource to be synced.
if err := c.syncHandler(key); err != nil { if err := c.syncHandler(key); err != nil {
return fmt.Errorf("error syncing '%s': %s", key, err.Error()) // Put the item back on the workqueue to handle any transient errors.
c.workqueue.AddRateLimited(key)
return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error())
} }
// Finally, if no error occurs we Forget this item so it does not // Finally, if no error occurs we Forget this item so it does not
// get queued again until another change happens. // get queued again until another change happens.
+3 -3
View File
@@ -88,7 +88,7 @@ message Rule {
repeated string apiVersions = 2; repeated string apiVersions = 2;
// Resources is a list of resources this rule applies to. // Resources is a list of resources this rule applies to.
// //
// For example: // For example:
// 'pods' means pods. // 'pods' means pods.
// 'pods/log' means the log subresource of pods. // 'pods/log' means the log subresource of pods.
@@ -96,10 +96,10 @@ message Rule {
// 'pods/*' means all subresources of pods. // 'pods/*' means all subresources of pods.
// '*/scale' means all scale subresources. // '*/scale' means all scale subresources.
// '*/*' means all resources and their subresources. // '*/*' means all resources and their subresources.
// //
// If wildcard is present, the validation rule will ensure resources do not // If wildcard is present, the validation rule will ensure resources do not
// overlap with each other. // overlap with each other.
// //
// Depending on the enclosing object, subresources might not be allowed. // Depending on the enclosing object, subresources might not be allowed.
// Required. // Required.
repeated string resources = 3; repeated string resources = 3;
+19 -19
View File
@@ -66,7 +66,7 @@ message Rule {
repeated string apiVersions = 2; repeated string apiVersions = 2;
// Resources is a list of resources this rule applies to. // Resources is a list of resources this rule applies to.
// //
// For example: // For example:
// 'pods' means pods. // 'pods' means pods.
// 'pods/log' means the log subresource of pods. // 'pods/log' means the log subresource of pods.
@@ -74,10 +74,10 @@ message Rule {
// 'pods/*' means all subresources of pods. // 'pods/*' means all subresources of pods.
// '*/scale' means all scale subresources. // '*/scale' means all scale subresources.
// '*/*' means all resources and their subresources. // '*/*' means all resources and their subresources.
// //
// If wildcard is present, the validation rule will ensure resources do not // If wildcard is present, the validation rule will ensure resources do not
// overlap with each other. // overlap with each other.
// //
// Depending on the enclosing object, subresources might not be allowed. // Depending on the enclosing object, subresources might not be allowed.
// Required. // Required.
repeated string resources = 3; repeated string resources = 3;
@@ -168,7 +168,7 @@ message Webhook {
// object itself is a namespace, the matching is performed on // object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource, // object.metadata.labels. If the object is another cluster scoped resource,
// it never skips the webhook. // it never skips the webhook.
// //
// For example, to run the webhook on any objects whose namespace is not // For example, to run the webhook on any objects whose namespace is not
// associated with "runlevel" of "0" or "1"; you will set the selector as // associated with "runlevel" of "0" or "1"; you will set the selector as
// follows: // follows:
@@ -184,7 +184,7 @@ message Webhook {
// } // }
// ] // ]
// } // }
// //
// If instead you want to only run the webhook on any objects whose // If instead you want to only run the webhook on any objects whose
// namespace is associated with the "environment" of "prod" or "staging"; // namespace is associated with the "environment" of "prod" or "staging";
// you will set the selector as follows: // you will set the selector as follows:
@@ -200,11 +200,11 @@ message Webhook {
// } // }
// ] // ]
// } // }
// //
// See // See
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
// for more examples of label selectors. // for more examples of label selectors.
// //
// Default to the empty LabelSelector, which matches everything. // Default to the empty LabelSelector, which matches everything.
// +optional // +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5; optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5;
@@ -225,45 +225,45 @@ message WebhookClientConfig {
// `url` gives the location of the webhook, in standard URL form // `url` gives the location of the webhook, in standard URL form
// (`[scheme://]host:port/path`). Exactly one of `url` or `service` // (`[scheme://]host:port/path`). Exactly one of `url` or `service`
// must be specified. // must be specified.
// //
// The `host` should not refer to a service running in the cluster; use // The `host` should not refer to a service running in the cluster; use
// the `service` field instead. The host might be resolved via external // the `service` field instead. The host might be resolved via external
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve // DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
// in-cluster DNS as that would be a layering violation). `host` may // in-cluster DNS as that would be a layering violation). `host` may
// also be an IP address. // also be an IP address.
// //
// Please note that using `localhost` or `127.0.0.1` as a `host` is // Please note that using `localhost` or `127.0.0.1` as a `host` is
// risky unless you take great care to run this webhook on all hosts // risky unless you take great care to run this webhook on all hosts
// which run an apiserver which might need to make calls to this // which run an apiserver which might need to make calls to this
// webhook. Such installs are likely to be non-portable, i.e., not easy // webhook. Such installs are likely to be non-portable, i.e., not easy
// to turn up in a new cluster. // to turn up in a new cluster.
// //
// The scheme must be "https"; the URL must begin with "https://". // The scheme must be "https"; the URL must begin with "https://".
// //
// A path is optional, and if present may be any string permissible in // A path is optional, and if present may be any string permissible in
// a URL. You may use the path to pass an arbitrary string to the // a URL. You may use the path to pass an arbitrary string to the
// webhook, for example, a cluster identifier. // webhook, for example, a cluster identifier.
// //
// Attempting to use a user or basic auth e.g. "user:password@" is not // Attempting to use a user or basic auth e.g. "user:password@" is not
// allowed. Fragments ("#...") and query parameters ("?...") are not // allowed. Fragments ("#...") and query parameters ("?...") are not
// allowed, either. // allowed, either.
// //
// +optional // +optional
optional string url = 3; optional string url = 3;
// `service` is a reference to the service for this webhook. Either // `service` is a reference to the service for this webhook. Either
// `service` or `url` must be specified. // `service` or `url` must be specified.
// //
// If the webhook is running within the cluster, then you should use `service`. // If the webhook is running within the cluster, then you should use `service`.
// //
// Port 443 will be used if it is open, otherwise it is an error. // Port 443 will be used if it is open, otherwise it is an error.
// //
// +optional // +optional
optional ServiceReference service = 1; optional ServiceReference service = 1;
// `caBundle` is a PEM encoded CA bundle which will be used to validate // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used.
// Required. // +optional
optional bytes caBundle = 2; optional bytes caBundle = 2;
} }
+5 -5
View File
@@ -282,12 +282,12 @@ type WebhookClientConfig struct {
// Port 443 will be used if it is open, otherwise it is an error. // Port 443 will be used if it is open, otherwise it is an error.
// //
// +optional // +optional
Service *ServiceReference `json:"service" protobuf:"bytes,1,opt,name=service"` Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"`
// `caBundle` is a PEM encoded CA bundle which will be used to validate // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used.
// Required. // +optional
CABundle []byte `json:"caBundle" protobuf:"bytes,2,opt,name=caBundle"` CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"`
} }
// ServiceReference holds a reference to Service.legacy.k8s.io // ServiceReference holds a reference to Service.legacy.k8s.io
@@ -116,7 +116,7 @@ var map_WebhookClientConfig = map[string]string{
"": "WebhookClientConfig contains the information to make a TLS connection with the webhook", "": "WebhookClientConfig contains the information to make a TLS connection with the webhook",
"url": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", "url": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.",
"service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.\n\nPort 443 will be used if it is open, otherwise it is an error.", "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.\n\nPort 443 will be used if it is open, otherwise it is an error.",
"caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. Required.", "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.",
} }
func (WebhookClientConfig) SwaggerDoc() map[string]string { func (WebhookClientConfig) SwaggerDoc() map[string]string {
+11 -12
View File
@@ -101,45 +101,44 @@ message WebhookClientConfig {
// `url` gives the location of the webhook, in standard URL form // `url` gives the location of the webhook, in standard URL form
// (`[scheme://]host:port/path`). Exactly one of `url` or `service` // (`[scheme://]host:port/path`). Exactly one of `url` or `service`
// must be specified. // must be specified.
// //
// The `host` should not refer to a service running in the cluster; use // The `host` should not refer to a service running in the cluster; use
// the `service` field instead. The host might be resolved via external // the `service` field instead. The host might be resolved via external
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve // DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
// in-cluster DNS as that would be a layering violation). `host` may // in-cluster DNS as that would be a layering violation). `host` may
// also be an IP address. // also be an IP address.
// //
// Please note that using `localhost` or `127.0.0.1` as a `host` is // Please note that using `localhost` or `127.0.0.1` as a `host` is
// risky unless you take great care to run this webhook on all hosts // risky unless you take great care to run this webhook on all hosts
// which run an apiserver which might need to make calls to this // which run an apiserver which might need to make calls to this
// webhook. Such installs are likely to be non-portable, i.e., not easy // webhook. Such installs are likely to be non-portable, i.e., not easy
// to turn up in a new cluster. // to turn up in a new cluster.
// //
// The scheme must be "https"; the URL must begin with "https://". // The scheme must be "https"; the URL must begin with "https://".
// //
// A path is optional, and if present may be any string permissible in // A path is optional, and if present may be any string permissible in
// a URL. You may use the path to pass an arbitrary string to the // a URL. You may use the path to pass an arbitrary string to the
// webhook, for example, a cluster identifier. // webhook, for example, a cluster identifier.
// //
// Attempting to use a user or basic auth e.g. "user:password@" is not // Attempting to use a user or basic auth e.g. "user:password@" is not
// allowed. Fragments ("#...") and query parameters ("?...") are not // allowed. Fragments ("#...") and query parameters ("?...") are not
// allowed, either. // allowed, either.
// //
// +optional // +optional
optional string url = 1; optional string url = 1;
// `service` is a reference to the service for this webhook. Either // `service` is a reference to the service for this webhook. Either
// `service` or `url` must be specified. // `service` or `url` must be specified.
// //
// If the webhook is running within the cluster, then you should use `service`. // If the webhook is running within the cluster, then you should use `service`.
// //
// Port 443 will be used if it is open, otherwise it is an error. // Port 443 will be used if it is open, otherwise it is an error.
// //
// +optional // +optional
optional ServiceReference service = 2; optional ServiceReference service = 2;
// `caBundle` is a PEM encoded CA bundle which will be used to validate // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used.
// defaults to the apiservers CA bundle for the endpoint type
// +optional // +optional
optional bytes caBundle = 3; optional bytes caBundle = 3;
} }
+4 -5
View File
@@ -169,13 +169,12 @@ type WebhookClientConfig struct {
// Port 443 will be used if it is open, otherwise it is an error. // Port 443 will be used if it is open, otherwise it is an error.
// //
// +optional // +optional
Service *ServiceReference `json:"service" protobuf:"bytes,2,opt,name=service"` Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,2,opt,name=service"`
// `caBundle` is a PEM encoded CA bundle which will be used to validate // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used.
// defaults to the apiservers CA bundle for the endpoint type
// +optional // +optional
CABundle []byte `json:"caBundle" protobuf:"bytes,3,opt,name=caBundle"` CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,3,opt,name=caBundle"`
} }
// ServiceReference holds a reference to Service.legacy.k8s.io // ServiceReference holds a reference to Service.legacy.k8s.io
@@ -90,7 +90,7 @@ var map_WebhookClientConfig = map[string]string{
"": "WebhookClientConfig contains the information to make a connection with the webhook", "": "WebhookClientConfig contains the information to make a connection with the webhook",
"url": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", "url": "`url` gives the location of the webhook, in standard URL form (`[scheme://]host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.",
"service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.\n\nPort 443 will be used if it is open, otherwise it is an error.", "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.\n\nPort 443 will be used if it is open, otherwise it is an error.",
"caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. defaults to the apiservers CA bundle for the endpoint type", "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.",
} }
func (WebhookClientConfig) SwaggerDoc() map[string]string { func (WebhookClientConfig) SwaggerDoc() map[string]string {
+19
View File
@@ -78,4 +78,23 @@ const (
// //
// Not all cloud providers support this annotation, though AWS & GCE do. // Not all cloud providers support this annotation, though AWS & GCE do.
AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges" AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges"
// EndpointsLastChangeTriggerTime is the annotation key, set for endpoints objects, that
// represents the timestamp (stored as RFC 3339 date-time string, e.g. '2018-10-22T19:32:52.1Z')
// of the last change, of some Pod or Service object, that triggered the endpoints object change.
// In other words, if a Pod / Service changed at time T0, that change was observed by endpoints
// controller at T1, and the Endpoints object was changed at T2, the
// EndpointsLastChangeTriggerTime would be set to T0.
//
// The "endpoints change trigger" here means any Pod or Service change that resulted in the
// Endpoints object change.
//
// Given the definition of the "endpoints change trigger", please note that this annotation will
// be set ONLY for endpoints object changes triggered by either Pod or Service change. If the
// Endpoints object changes due to other reasons, this annotation won't be set (or updated if it's
// already set).
//
// This annotation will be used to compute the in-cluster network programming latency SLI, see
// https://github.com/kubernetes/community/blob/master/sig-scalability/slos/network_programming_latency.md
EndpointsLastChangeTriggerTime = "endpoints.kubernetes.io/last-change-trigger-time"
) )
+16 -13
View File
@@ -31,7 +31,7 @@ import "k8s.io/apimachinery/pkg/util/intstr/generated.proto";
option go_package = "v1"; option go_package = "v1";
// Represents a Persistent Disk resource in AWS. // Represents a Persistent Disk resource in AWS.
// //
// An AWS EBS disk must exist before mounting to a container. The disk // An AWS EBS disk must exist before mounting to a container. The disk
// must also be in the same AWS zone as the kubelet. An AWS EBS disk // must also be in the same AWS zone as the kubelet. An AWS EBS disk
// can only be mounted as read/write once. AWS EBS volumes support // can only be mounted as read/write once. AWS EBS volumes support
@@ -436,7 +436,7 @@ message ConfigMap {
// ConfigMapEnvSource selects a ConfigMap to populate the environment // ConfigMapEnvSource selects a ConfigMap to populate the environment
// variables with. // variables with.
// //
// The contents of the target ConfigMap's Data field will represent the // The contents of the target ConfigMap's Data field will represent the
// key-value pairs as environment variables. // key-value pairs as environment variables.
message ConfigMapEnvSource { message ConfigMapEnvSource {
@@ -497,7 +497,7 @@ message ConfigMapNodeConfigSource {
} }
// Adapts a ConfigMap into a projected volume. // Adapts a ConfigMap into a projected volume.
// //
// The contents of the target ConfigMap's Data field will be presented in a // The contents of the target ConfigMap's Data field will be presented in a
// projected volume as files using the keys in the Data field as the file names, // projected volume as files using the keys in the Data field as the file names,
// unless the items element is populated with specific mappings of keys to paths. // unless the items element is populated with specific mappings of keys to paths.
@@ -522,7 +522,7 @@ message ConfigMapProjection {
} }
// Adapts a ConfigMap into a volume. // Adapts a ConfigMap into a volume.
// //
// The contents of the target ConfigMap's Data field will be presented in a // The contents of the target ConfigMap's Data field will be presented in a
// volume as files using the keys in the Data field as the file names, unless // volume as files using the keys in the Data field as the file names, unless
// the items element is populated with specific mappings of keys to paths. // the items element is populated with specific mappings of keys to paths.
@@ -606,6 +606,9 @@ message Container {
// +optional // +optional
// +patchMergeKey=containerPort // +patchMergeKey=containerPort
// +patchStrategy=merge // +patchStrategy=merge
// +listType=map
// +listMapKey=containerPort
// +listMapKey=protocol
repeated ContainerPort ports = 6; repeated ContainerPort ports = 6;
// List of sources to populate environment variables in the container. // List of sources to populate environment variables in the container.
@@ -1314,7 +1317,7 @@ message FlockerVolumeSource {
} }
// Represents a Persistent Disk resource in Google Compute Engine. // Represents a Persistent Disk resource in Google Compute Engine.
// //
// A GCE PD must exist before mounting to a container. The disk must // A GCE PD must exist before mounting to a container. The disk must
// also be in the same GCE project and zone as the kubelet. A GCE PD // also be in the same GCE project and zone as the kubelet. A GCE PD
// can only be mounted as read/write once or read-only many times. GCE // can only be mounted as read/write once or read-only many times. GCE
@@ -1350,7 +1353,7 @@ message GCEPersistentDiskVolumeSource {
// Represents a volume that is populated with the contents of a git repository. // Represents a volume that is populated with the contents of a git repository.
// Git repo volumes do not support ownership management. // Git repo volumes do not support ownership management.
// Git repo volumes support SELinux relabeling. // Git repo volumes support SELinux relabeling.
// //
// DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an // DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an
// EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir // EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir
// into the Pod's container. // into the Pod's container.
@@ -2899,11 +2902,11 @@ message PodSecurityContext {
// A special supplemental group that applies to all containers in a pod. // A special supplemental group that applies to all containers in a pod.
// Some volume types allow the Kubelet to change the ownership of that volume // Some volume types allow the Kubelet to change the ownership of that volume
// to be owned by the pod: // to be owned by the pod:
// //
// 1. The owning GID will be the FSGroup // 1. The owning GID will be the FSGroup
// 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) // 2. The setgid bit is set (new files created in the volume will be owned by FSGroup)
// 3. The permission bits are OR'd with rw-rw---- // 3. The permission bits are OR'd with rw-rw----
// //
// If unset, the Kubelet will not modify the ownership and permissions of any volume. // If unset, the Kubelet will not modify the ownership and permissions of any volume.
// +optional // +optional
optional int64 fsGroup = 5; optional int64 fsGroup = 5;
@@ -3141,7 +3144,7 @@ message PodStatus {
// The conditions array, the reason and message fields, and the individual container status // The conditions array, the reason and message fields, and the individual container status
// arrays contain more detail about the pod's status. // arrays contain more detail about the pod's status.
// There are five possible phase values: // There are five possible phase values:
// //
// Pending: The pod has been accepted by the Kubernetes system, but one or more of the // Pending: The pod has been accepted by the Kubernetes system, but one or more of the
// container images has not been created. This includes time before being scheduled as // container images has not been created. This includes time before being scheduled as
// well as time spent downloading images over the network, which could take a while. // well as time spent downloading images over the network, which could take a while.
@@ -3153,7 +3156,7 @@ message PodStatus {
// by the system. // by the system.
// Unknown: For some reason the state of the pod could not be obtained, typically due to an // Unknown: For some reason the state of the pod could not be obtained, typically due to an
// error in communicating with the host of the pod. // error in communicating with the host of the pod.
// //
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase
// +optional // +optional
optional string phase = 1; optional string phase = 1;
@@ -3884,7 +3887,7 @@ message Secret {
// SecretEnvSource selects a Secret to populate the environment // SecretEnvSource selects a Secret to populate the environment
// variables with. // variables with.
// //
// The contents of the target Secret's Data field will represent the // The contents of the target Secret's Data field will represent the
// key-value pairs as environment variables. // key-value pairs as environment variables.
message SecretEnvSource { message SecretEnvSource {
@@ -3922,7 +3925,7 @@ message SecretList {
} }
// Adapts a secret into a projected volume. // Adapts a secret into a projected volume.
// //
// The contents of the target Secret's Data field will be presented in a // The contents of the target Secret's Data field will be presented in a
// projected volume as files using the keys in the Data field as the file names. // projected volume as files using the keys in the Data field as the file names.
// Note that this is identical to a secret volume source without the default // Note that this is identical to a secret volume source without the default
@@ -3958,7 +3961,7 @@ message SecretReference {
} }
// Adapts a Secret into a volume. // Adapts a Secret into a volume.
// //
// The contents of the target Secret's Data field will be presented in a volume // The contents of the target Secret's Data field will be presented in a volume
// as files using the keys in the Data field as the file names. // as files using the keys in the Data field as the file names.
// Secret volumes support ownership management and SELinux relabeling. // Secret volumes support ownership management and SELinux relabeling.
+7
View File
@@ -2060,6 +2060,9 @@ type Container struct {
// +optional // +optional
// +patchMergeKey=containerPort // +patchMergeKey=containerPort
// +patchStrategy=merge // +patchStrategy=merge
// +listType=map
// +listMapKey=containerPort
// +listMapKey=protocol
Ports []ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` Ports []ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"`
// List of sources to populate environment variables in the container. // List of sources to populate environment variables in the container.
// The keys defined within a source must be a C_IDENTIFIER. All invalid keys // The keys defined within a source must be a C_IDENTIFIER. All invalid keys
@@ -4996,6 +4999,10 @@ const (
TLSCertKey = "tls.crt" TLSCertKey = "tls.crt"
// TLSPrivateKeyKey is the key for the private key field in a TLS secret. // TLSPrivateKeyKey is the key for the private key field in a TLS secret.
TLSPrivateKeyKey = "tls.key" TLSPrivateKeyKey = "tls.key"
// SecretTypeBootstrapToken is used during the automated bootstrap process (first
// implemented by kubeadm). It stores tokens that are used to sign well known
// ConfigMaps. They are used for authn.
SecretTypeBootstrapToken SecretType = "bootstrap.kubernetes.io/token"
) )
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+470 -1094
View File
File diff suppressed because it is too large Load Diff
+5 -31
View File
@@ -22,7 +22,6 @@ syntax = 'proto2';
package k8s.io.api.extensions.v1beta1; package k8s.io.api.extensions.v1beta1;
import "k8s.io/api/core/v1/generated.proto"; import "k8s.io/api/core/v1/generated.proto";
import "k8s.io/apimachinery/pkg/api/resource/generated.proto";
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto";
import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
@@ -45,7 +44,7 @@ message AllowedHostPath {
// pathPrefix is the path prefix that the host volume must match. // pathPrefix is the path prefix that the host volume must match.
// It does not support `*`. // It does not support `*`.
// Trailing slashes are trimmed when validating the path prefix with a host path. // Trailing slashes are trimmed when validating the path prefix with a host path.
// //
// Examples: // Examples:
// `/foo` would allow `/foo`, `/foo/` and `/foo/bar` // `/foo` would allow `/foo`, `/foo/` and `/foo/bar`
// `/foo` would not allow `/food` or `/etc/foo` // `/foo` would not allow `/food` or `/etc/foo`
@@ -56,31 +55,6 @@ message AllowedHostPath {
optional bool readOnly = 2; optional bool readOnly = 2;
} }
message CustomMetricCurrentStatus {
// Custom Metric name.
optional string name = 1;
// Custom Metric value (average).
optional k8s.io.apimachinery.pkg.api.resource.Quantity value = 2;
}
message CustomMetricCurrentStatusList {
repeated CustomMetricCurrentStatus items = 1;
}
// Alpha-level support for Custom Metrics in HPA (as annotations).
message CustomMetricTarget {
// Custom Metric name.
optional string name = 1;
// Custom Metric value (average).
optional k8s.io.apimachinery.pkg.api.resource.Quantity value = 2;
}
message CustomMetricTargetList {
repeated CustomMetricTarget items = 1;
}
// DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for // DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for
// more information. // more information.
// DaemonSet represents the configuration of a daemon set. // DaemonSet represents the configuration of a daemon set.
@@ -690,7 +664,7 @@ message NetworkPolicyList {
message NetworkPolicyPeer { message NetworkPolicyPeer {
// This is a label selector which selects Pods. This field follows standard label // This is a label selector which selects Pods. This field follows standard label
// selector semantics; if present but empty, it selects all pods. // selector semantics; if present but empty, it selects all pods.
// //
// If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.
@@ -699,7 +673,7 @@ message NetworkPolicyPeer {
// Selects Namespaces using cluster-scoped labels. This field follows standard label // Selects Namespaces using cluster-scoped labels. This field follows standard label
// selector semantics; if present but empty, it selects all namespaces. // selector semantics; if present but empty, it selects all namespaces.
// //
// If PodSelector is also set, then the NetworkPolicyPeer as a whole selects // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.
@@ -894,7 +868,7 @@ message PodSecurityPolicySpec {
// Each entry is either a plain sysctl name or ends in "*" in which case it is considered // Each entry is either a plain sysctl name or ends in "*" in which case it is considered
// as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed.
// Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection. // Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection.
// //
// Examples: // Examples:
// e.g. "foo/*" allows "foo/bar", "foo/baz", etc. // e.g. "foo/*" allows "foo/bar", "foo/baz", etc.
// e.g. "foo.*" allows "foo.bar", "foo.baz", etc. // e.g. "foo.*" allows "foo.bar", "foo.baz", etc.
@@ -904,7 +878,7 @@ message PodSecurityPolicySpec {
// forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none.
// Each entry is either a plain sysctl name or ends in "*" in which case it is considered // Each entry is either a plain sysctl name or ends in "*" in which case it is considered
// as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.
// //
// Examples: // Examples:
// e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc.
// e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc.
-24
View File
@@ -19,7 +19,6 @@ package v1beta1
import ( import (
appsv1beta1 "k8s.io/api/apps/v1beta1" appsv1beta1 "k8s.io/api/apps/v1beta1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
) )
@@ -77,29 +76,6 @@ type ReplicationControllerDummy struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
} }
// Alpha-level support for Custom Metrics in HPA (as annotations).
type CustomMetricTarget struct {
// Custom Metric name.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// Custom Metric value (average).
TargetValue resource.Quantity `json:"value" protobuf:"bytes,2,opt,name=value"`
}
type CustomMetricTargetList struct {
Items []CustomMetricTarget `json:"items" protobuf:"bytes,1,rep,name=items"`
}
type CustomMetricCurrentStatus struct {
// Custom Metric name.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// Custom Metric value (average).
CurrentValue resource.Quantity `json:"value" protobuf:"bytes,2,opt,name=value"`
}
type CustomMetricCurrentStatusList struct {
Items []CustomMetricCurrentStatus `json:"items" protobuf:"bytes,1,rep,name=items"`
}
// +genclient // +genclient
// +genclient:method=GetScale,verb=get,subresource=scale,result=Scale // +genclient:method=GetScale,verb=get,subresource=scale,result=Scale
// +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale // +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale
-19
View File
@@ -46,25 +46,6 @@ func (AllowedHostPath) SwaggerDoc() map[string]string {
return map_AllowedHostPath return map_AllowedHostPath
} }
var map_CustomMetricCurrentStatus = map[string]string{
"name": "Custom Metric name.",
"value": "Custom Metric value (average).",
}
func (CustomMetricCurrentStatus) SwaggerDoc() map[string]string {
return map_CustomMetricCurrentStatus
}
var map_CustomMetricTarget = map[string]string{
"": "Alpha-level support for Custom Metrics in HPA (as annotations).",
"name": "Custom Metric name.",
"value": "Custom Metric value (average).",
}
func (CustomMetricTarget) SwaggerDoc() map[string]string {
return map_CustomMetricTarget
}
var map_DaemonSet = map[string]string{ var map_DaemonSet = map[string]string{
"": "DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for more information. DaemonSet represents the configuration of a daemon set.", "": "DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for more information. DaemonSet represents the configuration of a daemon set.",
"metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata",
-80
View File
@@ -59,86 +59,6 @@ func (in *AllowedHostPath) DeepCopy() *AllowedHostPath {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomMetricCurrentStatus) DeepCopyInto(out *CustomMetricCurrentStatus) {
*out = *in
out.CurrentValue = in.CurrentValue.DeepCopy()
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricCurrentStatus.
func (in *CustomMetricCurrentStatus) DeepCopy() *CustomMetricCurrentStatus {
if in == nil {
return nil
}
out := new(CustomMetricCurrentStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomMetricCurrentStatusList) DeepCopyInto(out *CustomMetricCurrentStatusList) {
*out = *in
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]CustomMetricCurrentStatus, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricCurrentStatusList.
func (in *CustomMetricCurrentStatusList) DeepCopy() *CustomMetricCurrentStatusList {
if in == nil {
return nil
}
out := new(CustomMetricCurrentStatusList)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomMetricTarget) DeepCopyInto(out *CustomMetricTarget) {
*out = *in
out.TargetValue = in.TargetValue.DeepCopy()
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricTarget.
func (in *CustomMetricTarget) DeepCopy() *CustomMetricTarget {
if in == nil {
return nil
}
out := new(CustomMetricTarget)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomMetricTargetList) DeepCopyInto(out *CustomMetricTargetList) {
*out = *in
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]CustomMetricTarget, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMetricTargetList.
func (in *CustomMetricTargetList) DeepCopy() *CustomMetricTargetList {
if in == nil {
return nil
}
out := new(CustomMetricTargetList)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DaemonSet) DeepCopyInto(out *DaemonSet) { func (in *DaemonSet) DeepCopyInto(out *DaemonSet) {
*out = *in *out = *in
+2 -2
View File
@@ -114,7 +114,7 @@ message NetworkPolicyList {
message NetworkPolicyPeer { message NetworkPolicyPeer {
// This is a label selector which selects Pods. This field follows standard label // This is a label selector which selects Pods. This field follows standard label
// selector semantics; if present but empty, it selects all pods. // selector semantics; if present but empty, it selects all pods.
// //
// If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.
@@ -123,7 +123,7 @@ message NetworkPolicyPeer {
// Selects Namespaces using cluster-scoped labels. This field follows standard label // Selects Namespaces using cluster-scoped labels. This field follows standard label
// selector semantics; if present but empty, it selects all namespaces. // selector semantics; if present but empty, it selects all namespaces.
// //
// If PodSelector is also set, then the NetworkPolicyPeer as a whole selects // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.
+12 -3
View File
@@ -42,7 +42,7 @@ message AllowedHostPath {
// pathPrefix is the path prefix that the host volume must match. // pathPrefix is the path prefix that the host volume must match.
// It does not support `*`. // It does not support `*`.
// Trailing slashes are trimmed when validating the path prefix with a host path. // Trailing slashes are trimmed when validating the path prefix with a host path.
// //
// Examples: // Examples:
// `/foo` would allow `/foo`, `/foo/` and `/foo/bar` // `/foo` would allow `/foo`, `/foo/` and `/foo/bar`
// `/foo` would not allow `/food` or `/etc/foo` // `/foo` would not allow `/food` or `/etc/foo`
@@ -58,9 +58,11 @@ message AllowedHostPath {
// created by POSTing to .../pods/<pod name>/evictions. // created by POSTing to .../pods/<pod name>/evictions.
message Eviction { message Eviction {
// ObjectMeta describes the pod that is being evicted. // ObjectMeta describes the pod that is being evicted.
// +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
// DeleteOptions may be provided // DeleteOptions may be provided
// +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.DeleteOptions deleteOptions = 2; optional k8s.io.apimachinery.pkg.apis.meta.v1.DeleteOptions deleteOptions = 2;
} }
@@ -97,17 +99,21 @@ message IDRange {
// PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods // PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods
message PodDisruptionBudget { message PodDisruptionBudget {
// +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
// Specification of the desired behavior of the PodDisruptionBudget. // Specification of the desired behavior of the PodDisruptionBudget.
// +optional
optional PodDisruptionBudgetSpec spec = 2; optional PodDisruptionBudgetSpec spec = 2;
// Most recently observed status of the PodDisruptionBudget. // Most recently observed status of the PodDisruptionBudget.
// +optional
optional PodDisruptionBudgetStatus status = 3; optional PodDisruptionBudgetStatus status = 3;
} }
// PodDisruptionBudgetList is a collection of PodDisruptionBudgets. // PodDisruptionBudgetList is a collection of PodDisruptionBudgets.
message PodDisruptionBudgetList { message PodDisruptionBudgetList {
// +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
repeated PodDisruptionBudget items = 2; repeated PodDisruptionBudget items = 2;
@@ -119,16 +125,19 @@ message PodDisruptionBudgetSpec {
// "selector" will still be available after the eviction, i.e. even in the // "selector" will still be available after the eviction, i.e. even in the
// absence of the evicted pod. So for example you can prevent all voluntary // absence of the evicted pod. So for example you can prevent all voluntary
// evictions by specifying "100%". // evictions by specifying "100%".
// +optional
optional k8s.io.apimachinery.pkg.util.intstr.IntOrString minAvailable = 1; optional k8s.io.apimachinery.pkg.util.intstr.IntOrString minAvailable = 1;
// Label query over pods whose evictions are managed by the disruption // Label query over pods whose evictions are managed by the disruption
// budget. // budget.
// +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2;
// An eviction is allowed if at most "maxUnavailable" pods selected by // An eviction is allowed if at most "maxUnavailable" pods selected by
// "selector" are unavailable after the eviction, i.e. even in absence of // "selector" are unavailable after the eviction, i.e. even in absence of
// the evicted pod. For example, one can prevent all voluntary evictions // the evicted pod. For example, one can prevent all voluntary evictions
// by specifying 0. This is a mutually exclusive setting with "minAvailable". // by specifying 0. This is a mutually exclusive setting with "minAvailable".
// +optional
optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxUnavailable = 3; optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxUnavailable = 3;
} }
@@ -287,7 +296,7 @@ message PodSecurityPolicySpec {
// Each entry is either a plain sysctl name or ends in "*" in which case it is considered // Each entry is either a plain sysctl name or ends in "*" in which case it is considered
// as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed.
// Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection. // Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection.
// //
// Examples: // Examples:
// e.g. "foo/*" allows "foo/bar", "foo/baz", etc. // e.g. "foo/*" allows "foo/bar", "foo/baz", etc.
// e.g. "foo.*" allows "foo.bar", "foo.baz", etc. // e.g. "foo.*" allows "foo.bar", "foo.baz", etc.
@@ -297,7 +306,7 @@ message PodSecurityPolicySpec {
// forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none.
// Each entry is either a plain sysctl name or ends in "*" in which case it is considered // Each entry is either a plain sysctl name or ends in "*" in which case it is considered
// as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.
// //
// Examples: // Examples:
// e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc.
// e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc.
+13 -4
View File
@@ -28,16 +28,19 @@ type PodDisruptionBudgetSpec struct {
// "selector" will still be available after the eviction, i.e. even in the // "selector" will still be available after the eviction, i.e. even in the
// absence of the evicted pod. So for example you can prevent all voluntary // absence of the evicted pod. So for example you can prevent all voluntary
// evictions by specifying "100%". // evictions by specifying "100%".
// +optional
MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty" protobuf:"bytes,1,opt,name=minAvailable"` MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty" protobuf:"bytes,1,opt,name=minAvailable"`
// Label query over pods whose evictions are managed by the disruption // Label query over pods whose evictions are managed by the disruption
// budget. // budget.
// +optional
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"` Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"`
// An eviction is allowed if at most "maxUnavailable" pods selected by // An eviction is allowed if at most "maxUnavailable" pods selected by
// "selector" are unavailable after the eviction, i.e. even in absence of // "selector" are unavailable after the eviction, i.e. even in absence of
// the evicted pod. For example, one can prevent all voluntary evictions // the evicted pod. For example, one can prevent all voluntary evictions
// by specifying 0. This is a mutually exclusive setting with "minAvailable". // by specifying 0. This is a mutually exclusive setting with "minAvailable".
// +optional
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,3,opt,name=maxUnavailable"` MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,3,opt,name=maxUnavailable"`
} }
@@ -81,12 +84,15 @@ type PodDisruptionBudgetStatus struct {
// PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods // PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods
type PodDisruptionBudget struct { type PodDisruptionBudget struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Specification of the desired behavior of the PodDisruptionBudget. // Specification of the desired behavior of the PodDisruptionBudget.
// +optional
Spec PodDisruptionBudgetSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` Spec PodDisruptionBudgetSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
// Most recently observed status of the PodDisruptionBudget. // Most recently observed status of the PodDisruptionBudget.
// +optional
Status PodDisruptionBudgetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` Status PodDisruptionBudgetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
} }
@@ -95,6 +101,7 @@ type PodDisruptionBudget struct {
// PodDisruptionBudgetList is a collection of PodDisruptionBudgets. // PodDisruptionBudgetList is a collection of PodDisruptionBudgets.
type PodDisruptionBudgetList struct { type PodDisruptionBudgetList struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []PodDisruptionBudget `json:"items" protobuf:"bytes,2,rep,name=items"` Items []PodDisruptionBudget `json:"items" protobuf:"bytes,2,rep,name=items"`
} }
@@ -110,9 +117,11 @@ type Eviction struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
// ObjectMeta describes the pod that is being evicted. // ObjectMeta describes the pod that is being evicted.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// DeleteOptions may be provided // DeleteOptions may be provided
// +optional
DeleteOptions *metav1.DeleteOptions `json:"deleteOptions,omitempty" protobuf:"bytes,2,opt,name=deleteOptions"` DeleteOptions *metav1.DeleteOptions `json:"deleteOptions,omitempty" protobuf:"bytes,2,opt,name=deleteOptions"`
} }
@@ -250,13 +259,13 @@ type AllowedHostPath struct {
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,2,opt,name=readOnly"` ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,2,opt,name=readOnly"`
} }
// FSType gives strong typing to different file systems that are used by volumes.
type FSType string
// AllowAllCapabilities can be used as a value for the PodSecurityPolicy.AllowAllCapabilities // AllowAllCapabilities can be used as a value for the PodSecurityPolicy.AllowAllCapabilities
// field and means that any capabilities are allowed to be requested. // field and means that any capabilities are allowed to be requested.
var AllowAllCapabilities v1.Capability = "*" var AllowAllCapabilities v1.Capability = "*"
// FSType gives strong typing to different file systems that are used by volumes.
type FSType string
var ( var (
AzureFile FSType = "azureFile" AzureFile FSType = "azureFile"
Flocker FSType = "flocker" Flocker FSType = "flocker"
+1 -1
View File
@@ -31,7 +31,7 @@ option go_package = "v1";
// StorageClass describes the parameters for a class of storage for // StorageClass describes the parameters for a class of storage for
// which PersistentVolumes can be dynamically provisioned. // which PersistentVolumes can be dynamically provisioned.
// //
// StorageClasses are non-namespaced; the name of the storage class // StorageClasses are non-namespaced; the name of the storage class
// according to etcd is in ObjectMeta.Name. // according to etcd is in ObjectMeta.Name.
message StorageClass { message StorageClass {
+1 -1
View File
@@ -30,7 +30,7 @@ option go_package = "v1alpha1";
// VolumeAttachment captures the intent to attach or detach the specified volume // VolumeAttachment captures the intent to attach or detach the specified volume
// to/from the specified node. // to/from the specified node.
// //
// VolumeAttachment objects are non-namespaced. // VolumeAttachment objects are non-namespaced.
message VolumeAttachment { message VolumeAttachment {
// Standard object metadata. // Standard object metadata.
+2 -2
View File
@@ -31,7 +31,7 @@ option go_package = "v1beta1";
// StorageClass describes the parameters for a class of storage for // StorageClass describes the parameters for a class of storage for
// which PersistentVolumes can be dynamically provisioned. // which PersistentVolumes can be dynamically provisioned.
// //
// StorageClasses are non-namespaced; the name of the storage class // StorageClasses are non-namespaced; the name of the storage class
// according to etcd is in ObjectMeta.Name. // according to etcd is in ObjectMeta.Name.
message StorageClass { message StorageClass {
@@ -90,7 +90,7 @@ message StorageClassList {
// VolumeAttachment captures the intent to attach or detach the specified volume // VolumeAttachment captures the intent to attach or detach the specified volume
// to/from the specified node. // to/from the specified node.
// //
// VolumeAttachment objects are non-namespaced. // VolumeAttachment objects are non-namespaced.
message VolumeAttachment { message VolumeAttachment {
// Standard object metadata. // Standard object metadata.
+15 -1
View File
@@ -20,6 +20,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"reflect"
"strings" "strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -82,7 +83,20 @@ func (u *UnexpectedObjectError) Error() string {
func FromObject(obj runtime.Object) error { func FromObject(obj runtime.Object) error {
switch t := obj.(type) { switch t := obj.(type) {
case *metav1.Status: case *metav1.Status:
return &StatusError{*t} return &StatusError{ErrStatus: *t}
case runtime.Unstructured:
var status metav1.Status
obj := t.UnstructuredContent()
if !reflect.DeepEqual(obj["kind"], "Status") {
break
}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(t.UnstructuredContent(), &status); err != nil {
return err
}
if status.APIVersion != "v1" && status.APIVersion != "meta.k8s.io/v1" {
break
}
return &StatusError{ErrStatus: status}
} }
return &UnexpectedObjectError{obj} return &UnexpectedObjectError{obj}
} }
+10 -10
View File
@@ -27,9 +27,9 @@ option go_package = "resource";
// Quantity is a fixed-point representation of a number. // Quantity is a fixed-point representation of a number.
// It provides convenient marshaling/unmarshaling in JSON and YAML, // It provides convenient marshaling/unmarshaling in JSON and YAML,
// in addition to String() and Int64() accessors. // in addition to String() and Int64() accessors.
// //
// The serialization format is: // The serialization format is:
// //
// <quantity> ::= <signedNumber><suffix> // <quantity> ::= <signedNumber><suffix>
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.) // (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
// <digit> ::= 0 | 1 | ... | 9 // <digit> ::= 0 | 1 | ... | 9
@@ -43,16 +43,16 @@ option go_package = "resource";
// <decimalSI> ::= m | "" | k | M | G | T | P | E // <decimalSI> ::= m | "" | k | M | G | T | P | E
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) // (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber> // <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
// //
// No matter which of the three exponent forms is used, no quantity may represent // No matter which of the three exponent forms is used, no quantity may represent
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal // a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
// places. Numbers larger or more precise will be capped or rounded up. // places. Numbers larger or more precise will be capped or rounded up.
// (E.g.: 0.1m will rounded up to 1m.) // (E.g.: 0.1m will rounded up to 1m.)
// This may be extended in the future if we require larger or smaller quantities. // This may be extended in the future if we require larger or smaller quantities.
// //
// When a Quantity is parsed from a string, it will remember the type of suffix // When a Quantity is parsed from a string, it will remember the type of suffix
// it had, and will use the same type again when it is serialized. // it had, and will use the same type again when it is serialized.
// //
// Before serializing, Quantity will be put in "canonical form". // Before serializing, Quantity will be put in "canonical form".
// This means that Exponent/suffix will be adjusted up or down (with a // This means that Exponent/suffix will be adjusted up or down (with a
// corresponding increase or decrease in Mantissa) such that: // corresponding increase or decrease in Mantissa) such that:
@@ -60,22 +60,22 @@ option go_package = "resource";
// b. No fractional digits will be emitted // b. No fractional digits will be emitted
// c. The exponent (or suffix) is as large as possible. // c. The exponent (or suffix) is as large as possible.
// The sign will be omitted unless the number is negative. // The sign will be omitted unless the number is negative.
// //
// Examples: // Examples:
// 1.5 will be serialized as "1500m" // 1.5 will be serialized as "1500m"
// 1.5Gi will be serialized as "1536Mi" // 1.5Gi will be serialized as "1536Mi"
// //
// Note that the quantity will NEVER be internally represented by a // Note that the quantity will NEVER be internally represented by a
// floating point number. That is the whole point of this exercise. // floating point number. That is the whole point of this exercise.
// //
// Non-canonical values will still parse as long as they are well formed, // Non-canonical values will still parse as long as they are well formed,
// but will be re-emitted in their canonical form. (So always use canonical // but will be re-emitted in their canonical form. (So always use canonical
// form, or don't diff.) // form, or don't diff.)
// //
// This format is intended to make it difficult to use these numbers without // This format is intended to make it difficult to use these numbers without
// writing some sort of special handling code in the hopes that that will // writing some sort of special handling code in the hopes that that will
// cause implementors to also use a fixed point implementation. // cause implementors to also use a fixed point implementation.
// //
// +protobuf=true // +protobuf=true
// +protobuf.embed=string // +protobuf.embed=string
// +protobuf.options.marshal=false // +protobuf.options.marshal=false
+22 -22
View File
@@ -107,7 +107,7 @@ message APIResourceList {
// APIVersions lists the versions that are available, to allow clients to // APIVersions lists the versions that are available, to allow clients to
// discover the API at /api, which is the root path of the legacy v1 API. // discover the API at /api, which is the root path of the legacy v1 API.
// //
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message APIVersions { message APIVersions {
@@ -211,7 +211,7 @@ message GetOptions {
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying // GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types // concepts during lookup stages without having partially valid types
// //
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupKind { message GroupKind {
optional string group = 1; optional string group = 1;
@@ -221,7 +221,7 @@ message GroupKind {
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying // GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types // concepts during lookup stages without having partially valid types
// //
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupResource { message GroupResource {
optional string group = 1; optional string group = 1;
@@ -230,7 +230,7 @@ message GroupResource {
} }
// GroupVersion contains the "group" and the "version", which uniquely identifies the API. // GroupVersion contains the "group" and the "version", which uniquely identifies the API.
// //
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupVersion { message GroupVersion {
optional string group = 1; optional string group = 1;
@@ -251,7 +251,7 @@ message GroupVersionForDiscovery {
// GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion // GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling // to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
// //
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupVersionKind { message GroupVersionKind {
optional string group = 1; optional string group = 1;
@@ -263,7 +263,7 @@ message GroupVersionKind {
// GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion // GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling // to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
// //
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
message GroupVersionResource { message GroupVersionResource {
optional string group = 1; optional string group = 1;
@@ -411,7 +411,7 @@ message ListOptions {
// more results are available. Servers may choose not to support the limit argument and will return // more results are available. Servers may choose not to support the limit argument and will return
// all of the available results. If limit is specified and the continue field is empty, clients may // all of the available results. If limit is specified and the continue field is empty, clients may
// assume that no more results are available. This field is not supported if watch is true. // assume that no more results are available. This field is not supported if watch is true.
// //
// The server guarantees that the objects returned when using continue will be identical to issuing // The server guarantees that the objects returned when using continue will be identical to issuing
// a single list call without a limit - that is, no objects created, modified, or deleted after the // a single list call without a limit - that is, no objects created, modified, or deleted after the
// first request is issued will be included in any subsequent continued requests. This is sometimes // first request is issued will be included in any subsequent continued requests. This is sometimes
@@ -432,14 +432,14 @@ message ListOptions {
// a list starting from the next key, but from the latest snapshot, which is inconsistent from the // a list starting from the next key, but from the latest snapshot, which is inconsistent from the
// previous list results - objects that are created, modified, or deleted after the first list request // previous list results - objects that are created, modified, or deleted after the first list request
// will be included in the response, as long as their keys are after the "next key". // will be included in the response, as long as their keys are after the "next key".
// //
// This field is not supported when watch is true. Clients may start a watch from the last // This field is not supported when watch is true. Clients may start a watch from the last
// resourceVersion value returned by the server and not miss any modifications. // resourceVersion value returned by the server and not miss any modifications.
optional string continue = 8; optional string continue = 8;
} }
// MicroTime is version of Time with microsecond level precision. // MicroTime is version of Time with microsecond level precision.
// //
// +protobuf.options.marshal=false // +protobuf.options.marshal=false
// +protobuf.as=Timestamp // +protobuf.as=Timestamp
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
@@ -475,12 +475,12 @@ message ObjectMeta {
// The provided value has the same validation rules as the Name field, // The provided value has the same validation rules as the Name field,
// and may be truncated by the length of the suffix required to make the value // and may be truncated by the length of the suffix required to make the value
// unique on the server. // unique on the server.
// //
// If this field is specified and the generated name exists, the server will // If this field is specified and the generated name exists, the server will
// NOT return a 409 - instead, it will either return 201 Created or 500 with Reason // NOT return a 409 - instead, it will either return 201 Created or 500 with Reason
// ServerTimeout indicating a unique name could not be found in the time allotted, and the client // ServerTimeout indicating a unique name could not be found in the time allotted, and the client
// should retry (optionally after the time indicated in the Retry-After header). // should retry (optionally after the time indicated in the Retry-After header).
// //
// Applied only if Name is not specified. // Applied only if Name is not specified.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency
// +optional // +optional
@@ -490,7 +490,7 @@ message ObjectMeta {
// equivalent to the "default" namespace, but "default" is the canonical representation. // equivalent to the "default" namespace, but "default" is the canonical representation.
// Not all objects are required to be scoped to a namespace - the value of this field for // Not all objects are required to be scoped to a namespace - the value of this field for
// those objects will be empty. // those objects will be empty.
// //
// Must be a DNS_LABEL. // Must be a DNS_LABEL.
// Cannot be updated. // Cannot be updated.
// More info: http://kubernetes.io/docs/user-guide/namespaces // More info: http://kubernetes.io/docs/user-guide/namespaces
@@ -506,7 +506,7 @@ message ObjectMeta {
// UID is the unique in time and space value for this object. It is typically generated by // UID is the unique in time and space value for this object. It is typically generated by
// the server on successful creation of a resource and is not allowed to change on PUT // the server on successful creation of a resource and is not allowed to change on PUT
// operations. // operations.
// //
// Populated by the system. // Populated by the system.
// Read-only. // Read-only.
// More info: http://kubernetes.io/docs/user-guide/identifiers#uids // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
@@ -518,7 +518,7 @@ message ObjectMeta {
// concurrency, change detection, and the watch operation on a resource or set of resources. // concurrency, change detection, and the watch operation on a resource or set of resources.
// Clients must treat these values as opaque and passed unmodified back to the server. // Clients must treat these values as opaque and passed unmodified back to the server.
// They may only be valid for a particular resource or set of resources. // They may only be valid for a particular resource or set of resources.
// //
// Populated by the system. // Populated by the system.
// Read-only. // Read-only.
// Value must be treated as opaque by clients and . // Value must be treated as opaque by clients and .
@@ -534,7 +534,7 @@ message ObjectMeta {
// CreationTimestamp is a timestamp representing the server time when this object was // CreationTimestamp is a timestamp representing the server time when this object was
// created. It is not guaranteed to be set in happens-before order across separate operations. // created. It is not guaranteed to be set in happens-before order across separate operations.
// Clients may not set this value. It is represented in RFC3339 form and is in UTC. // Clients may not set this value. It is represented in RFC3339 form and is in UTC.
// //
// Populated by the system. // Populated by the system.
// Read-only. // Read-only.
// Null for lists. // Null for lists.
@@ -556,7 +556,7 @@ message ObjectMeta {
// exist after this timestamp, until an administrator or automated process can determine the // exist after this timestamp, until an administrator or automated process can determine the
// resource is fully terminated. // resource is fully terminated.
// If not set, graceful deletion of the object has not been requested. // If not set, graceful deletion of the object has not been requested.
// //
// Populated by the system when a graceful deletion is requested. // Populated by the system when a graceful deletion is requested.
// Read-only. // Read-only.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
@@ -598,7 +598,7 @@ message ObjectMeta {
// this object has been completely initialized. Otherwise, the object is considered uninitialized // this object has been completely initialized. Otherwise, the object is considered uninitialized
// and is hidden (in list/watch and get calls) from clients that haven't explicitly asked to // and is hidden (in list/watch and get calls) from clients that haven't explicitly asked to
// observe uninitialized objects. // observe uninitialized objects.
// //
// When an object is created, the system will populate this list with the current set of initializers. // When an object is created, the system will populate this list with the current set of initializers.
// Only privileged users may set or modify this list. Once it is empty, it may not be modified further // Only privileged users may set or modify this list. Once it is empty, it may not be modified further
// by any user. // by any user.
@@ -734,7 +734,7 @@ message StatusCause {
// Arrays are zero-indexed. Fields may appear more than once in an array of // Arrays are zero-indexed. Fields may appear more than once in an array of
// causes due to fields having multiple errors. // causes due to fields having multiple errors.
// Optional. // Optional.
// //
// Examples: // Examples:
// "name" - the field "name" on the current resource // "name" - the field "name" on the current resource
// "items[0].name" - the field "name" on the first array entry in "items" // "items[0].name" - the field "name" on the first array entry in "items"
@@ -785,7 +785,7 @@ message StatusDetails {
// Time is a wrapper around time.Time which supports correct // Time is a wrapper around time.Time which supports correct
// marshaling to YAML and JSON. Wrappers are provided for many // marshaling to YAML and JSON. Wrappers are provided for many
// of the factory methods that the time package offers. // of the factory methods that the time package offers.
// //
// +protobuf.options.marshal=false // +protobuf.options.marshal=false
// +protobuf.as=Timestamp // +protobuf.as=Timestamp
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
@@ -821,7 +821,7 @@ message Timestamp {
// TypeMeta describes an individual object in an API response or request // TypeMeta describes an individual object in an API response or request
// with strings representing the type of the object and its API schema version. // with strings representing the type of the object and its API schema version.
// Structures that are versioned or persisted should inline TypeMeta. // Structures that are versioned or persisted should inline TypeMeta.
// //
// +k8s:deepcopy-gen=false // +k8s:deepcopy-gen=false
message TypeMeta { message TypeMeta {
// Kind is a string value representing the REST resource this object represents. // Kind is a string value representing the REST resource this object represents.
@@ -852,7 +852,7 @@ message UpdateOptions {
} }
// Verbs masks the value so protobuf can generate // Verbs masks the value so protobuf can generate
// //
// +protobuf.nullable=true // +protobuf.nullable=true
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
message Verbs { message Verbs {
@@ -862,7 +862,7 @@ message Verbs {
} }
// Event represents a single event to a watched resource. // Event represents a single event to a watched resource.
// //
// +protobuf=true // +protobuf=true
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+10 -10
View File
@@ -25,11 +25,11 @@ package k8s.io.apimachinery.pkg.runtime;
option go_package = "runtime"; option go_package = "runtime";
// RawExtension is used to hold extensions in external versions. // RawExtension is used to hold extensions in external versions.
// //
// To use this, make a field which has RawExtension as its type in your external, versioned // To use this, make a field which has RawExtension as its type in your external, versioned
// struct, and Object in your internal struct. You also need to register your // struct, and Object in your internal struct. You also need to register your
// various plugin types. // various plugin types.
// //
// // Internal package: // // Internal package:
// type MyAPIObject struct { // type MyAPIObject struct {
// runtime.TypeMeta `json:",inline"` // runtime.TypeMeta `json:",inline"`
@@ -38,7 +38,7 @@ option go_package = "runtime";
// type PluginA struct { // type PluginA struct {
// AOption string `json:"aOption"` // AOption string `json:"aOption"`
// } // }
// //
// // External package: // // External package:
// type MyAPIObject struct { // type MyAPIObject struct {
// runtime.TypeMeta `json:",inline"` // runtime.TypeMeta `json:",inline"`
@@ -47,7 +47,7 @@ option go_package = "runtime";
// type PluginA struct { // type PluginA struct {
// AOption string `json:"aOption"` // AOption string `json:"aOption"`
// } // }
// //
// // On the wire, the JSON will look something like this: // // On the wire, the JSON will look something like this:
// { // {
// "kind":"MyAPIObject", // "kind":"MyAPIObject",
@@ -57,7 +57,7 @@ option go_package = "runtime";
// "aOption":"foo", // "aOption":"foo",
// }, // },
// } // }
// //
// So what happens? Decode first uses json or yaml to unmarshal the serialized data into // So what happens? Decode first uses json or yaml to unmarshal the serialized data into
// your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. // your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked.
// The next step is to copy (using pkg/conversion) into the internal struct. The runtime // The next step is to copy (using pkg/conversion) into the internal struct. The runtime
@@ -65,13 +65,13 @@ option go_package = "runtime";
// JSON stored in RawExtension, turning it into the correct object type, and storing it // JSON stored in RawExtension, turning it into the correct object type, and storing it
// in the Object. (TODO: In the case where the object is of an unknown type, a // in the Object. (TODO: In the case where the object is of an unknown type, a
// runtime.Unknown object will be created and stored.) // runtime.Unknown object will be created and stored.)
// //
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +protobuf=true // +protobuf=true
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
message RawExtension { message RawExtension {
// Raw is the underlying serialization of this object. // Raw is the underlying serialization of this object.
// //
// TODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data. // TODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data.
optional bytes raw = 1; optional bytes raw = 1;
} }
@@ -83,10 +83,10 @@ message RawExtension {
// ... // other fields // ... // other fields
// } // }
// func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind // func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind
// //
// TypeMeta is provided here for convenience. You may use it directly from this package or define // TypeMeta is provided here for convenience. You may use it directly from this package or define
// your own with the same fields. // your own with the same fields.
// //
// +k8s:deepcopy-gen=false // +k8s:deepcopy-gen=false
// +protobuf=true // +protobuf=true
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
@@ -103,7 +103,7 @@ message TypeMeta {
// TypeMeta features-- kind, version, etc. // TypeMeta features-- kind, version, etc.
// TODO: Make this object have easy access to field based accessors and settors for // TODO: Make this object have easy access to field based accessors and settors for
// metadata and field mutatation. // metadata and field mutatation.
// //
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +protobuf=true // +protobuf=true
+11 -1
View File
@@ -18,6 +18,7 @@ package versioning
import ( import (
"io" "io"
"reflect"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@@ -90,7 +91,16 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
into = versioned.Last() into = versioned.Last()
} }
obj, gvk, err := c.decoder.Decode(data, defaultGVK, into) // If the into object is unstructured and expresses an opinion about its group/version,
// create a new instance of the type so we always exercise the conversion path (skips short-circuiting on `into == obj`)
decodeInto := into
if into != nil {
if _, ok := into.(runtime.Unstructured); ok && !into.GetObjectKind().GroupVersionKind().GroupVersion().Empty() {
decodeInto = reflect.New(reflect.TypeOf(into).Elem()).Interface().(runtime.Object)
}
}
obj, gvk, err := c.decoder.Decode(data, defaultGVK, decodeInto)
if err != nil { if err != nil {
return nil, gvk, err return nil, gvk, err
} }
+1 -1
View File
@@ -29,7 +29,7 @@ option go_package = "intstr";
// inner type. This allows you to have, for example, a JSON field that can // inner type. This allows you to have, for example, a JSON field that can
// accept a name or number. // accept a name or number.
// TODO: Rename to Int32OrString // TODO: Rename to Int32OrString
// //
// +protobuf=true // +protobuf=true
// +protobuf.options.(gogoproto.goproto_stringer)=false // +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
+13
View File
@@ -94,6 +94,8 @@ func (d *CachedDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, er
return ServerResources(d) return ServerResources(d)
} }
// ServerGroups returns the supported groups, with information like supported versions and the
// preferred version.
func (d *CachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) { func (d *CachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
filename := filepath.Join(d.cacheDirectory, "servergroups.json") filename := filepath.Join(d.cacheDirectory, "servergroups.json")
cachedBytes, err := d.getCachedFile(filename) cachedBytes, err := d.getCachedFile(filename)
@@ -202,26 +204,36 @@ func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Obj
return err return err
} }
// RESTClient returns a RESTClient that is used to communicate with API server
// by this client implementation.
func (d *CachedDiscoveryClient) RESTClient() restclient.Interface { func (d *CachedDiscoveryClient) RESTClient() restclient.Interface {
return d.delegate.RESTClient() return d.delegate.RESTClient()
} }
// ServerPreferredResources returns the supported resources with the version preferred by the
// server.
func (d *CachedDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) { func (d *CachedDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
return ServerPreferredResources(d) return ServerPreferredResources(d)
} }
// ServerPreferredNamespacedResources returns the supported namespaced resources with the
// version preferred by the server.
func (d *CachedDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) { func (d *CachedDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
return ServerPreferredNamespacedResources(d) return ServerPreferredNamespacedResources(d)
} }
// ServerVersion retrieves and parses the server's version (git version).
func (d *CachedDiscoveryClient) ServerVersion() (*version.Info, error) { func (d *CachedDiscoveryClient) ServerVersion() (*version.Info, error) {
return d.delegate.ServerVersion() return d.delegate.ServerVersion()
} }
// OpenAPISchema retrieves and parses the swagger API schema the server supports.
func (d *CachedDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) { func (d *CachedDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
return d.delegate.OpenAPISchema() return d.delegate.OpenAPISchema()
} }
// Fresh is supposed to tell the caller whether or not to retry if the cache
// fails to find something (false = retry, true = no need to retry).
func (d *CachedDiscoveryClient) Fresh() bool { func (d *CachedDiscoveryClient) Fresh() bool {
d.mutex.Lock() d.mutex.Lock()
defer d.mutex.Unlock() defer d.mutex.Unlock()
@@ -229,6 +241,7 @@ func (d *CachedDiscoveryClient) Fresh() bool {
return d.fresh return d.fresh
} }
// Invalidate enforces that no cached data is used in the future that is older than the current time.
func (d *CachedDiscoveryClient) Invalidate() { func (d *CachedDiscoveryClient) Invalidate() {
d.mutex.Lock() d.mutex.Lock()
defer d.mutex.Unlock() defer d.mutex.Unlock()
+12 -12
View File
@@ -263,8 +263,8 @@ func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList,
result := []*metav1.APIResourceList{} result := []*metav1.APIResourceList{}
grVersions := map[schema.GroupResource]string{} // selected version of a GroupResource grVersions := map[schema.GroupResource]string{} // selected version of a GroupResource
grApiResources := map[schema.GroupResource]*metav1.APIResource{} // selected APIResource for a GroupResource grAPIResources := map[schema.GroupResource]*metav1.APIResource{} // selected APIResource for a GroupResource
gvApiResourceLists := map[schema.GroupVersion]*metav1.APIResourceList{} // blueprint for a APIResourceList for later grouping gvAPIResourceLists := map[schema.GroupVersion]*metav1.APIResourceList{} // blueprint for a APIResourceList for later grouping
for _, apiGroup := range serverGroupList.Groups { for _, apiGroup := range serverGroupList.Groups {
for _, version := range apiGroup.Versions { for _, version := range apiGroup.Versions {
@@ -276,11 +276,11 @@ func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList,
} }
// create empty list which is filled later in another loop // create empty list which is filled later in another loop
emptyApiResourceList := metav1.APIResourceList{ emptyAPIResourceList := metav1.APIResourceList{
GroupVersion: version.GroupVersion, GroupVersion: version.GroupVersion,
} }
gvApiResourceLists[groupVersion] = &emptyApiResourceList gvAPIResourceLists[groupVersion] = &emptyAPIResourceList
result = append(result, &emptyApiResourceList) result = append(result, &emptyAPIResourceList)
for i := range apiResourceList.APIResources { for i := range apiResourceList.APIResources {
apiResource := &apiResourceList.APIResources[i] apiResource := &apiResourceList.APIResources[i]
@@ -288,21 +288,21 @@ func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList,
continue continue
} }
gv := schema.GroupResource{Group: apiGroup.Name, Resource: apiResource.Name} gv := schema.GroupResource{Group: apiGroup.Name, Resource: apiResource.Name}
if _, ok := grApiResources[gv]; ok && version.Version != apiGroup.PreferredVersion.Version { if _, ok := grAPIResources[gv]; ok && version.Version != apiGroup.PreferredVersion.Version {
// only override with preferred version // only override with preferred version
continue continue
} }
grVersions[gv] = version.Version grVersions[gv] = version.Version
grApiResources[gv] = apiResource grAPIResources[gv] = apiResource
} }
} }
} }
// group selected APIResources according to GroupVersion into APIResourceLists // group selected APIResources according to GroupVersion into APIResourceLists
for groupResource, apiResource := range grApiResources { for groupResource, apiResource := range grAPIResources {
version := grVersions[groupResource] version := grVersions[groupResource]
groupVersion := schema.GroupVersion{Group: groupResource.Group, Version: version} groupVersion := schema.GroupVersion{Group: groupResource.Group, Version: version}
apiResourceList := gvApiResourceLists[groupVersion] apiResourceList := gvAPIResourceLists[groupVersion]
apiResourceList.APIResources = append(apiResourceList.APIResources, *apiResource) apiResourceList.APIResources = append(apiResourceList.APIResources, *apiResource)
} }
@@ -464,9 +464,9 @@ func NewDiscoveryClient(c restclient.Interface) *DiscoveryClient {
// RESTClient returns a RESTClient that is used to communicate // RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation. // with API server by this client implementation.
func (c *DiscoveryClient) RESTClient() restclient.Interface { func (d *DiscoveryClient) RESTClient() restclient.Interface {
if c == nil { if d == nil {
return nil return nil
} }
return c.restClient return d.restClient
} }
+13
View File
@@ -36,6 +36,8 @@ type FakeDiscovery struct {
FakedServerVersion *version.Info FakedServerVersion *version.Info
} }
// ServerResourcesForGroupVersion returns the supported resources for a group
// and version.
func (c *FakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) { func (c *FakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
action := testing.ActionImpl{ action := testing.ActionImpl{
Verb: "get", Verb: "get",
@@ -50,6 +52,7 @@ func (c *FakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*me
return nil, fmt.Errorf("GroupVersion %q not found", groupVersion) return nil, fmt.Errorf("GroupVersion %q not found", groupVersion)
} }
// ServerResources returns the supported resources for all groups and versions.
func (c *FakeDiscovery) ServerResources() ([]*metav1.APIResourceList, error) { func (c *FakeDiscovery) ServerResources() ([]*metav1.APIResourceList, error) {
action := testing.ActionImpl{ action := testing.ActionImpl{
Verb: "get", Verb: "get",
@@ -59,14 +62,20 @@ func (c *FakeDiscovery) ServerResources() ([]*metav1.APIResourceList, error) {
return c.Resources, nil return c.Resources, nil
} }
// ServerPreferredResources returns the supported resources with the version
// preferred by the server.
func (c *FakeDiscovery) ServerPreferredResources() ([]*metav1.APIResourceList, error) { func (c *FakeDiscovery) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
return nil, nil return nil, nil
} }
// ServerPreferredNamespacedResources returns the supported namespaced resources
// with the version preferred by the server.
func (c *FakeDiscovery) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) { func (c *FakeDiscovery) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
return nil, nil return nil, nil
} }
// ServerGroups returns the supported groups, with information like supported
// versions and the preferred version.
func (c *FakeDiscovery) ServerGroups() (*metav1.APIGroupList, error) { func (c *FakeDiscovery) ServerGroups() (*metav1.APIGroupList, error) {
action := testing.ActionImpl{ action := testing.ActionImpl{
Verb: "get", Verb: "get",
@@ -108,6 +117,7 @@ func (c *FakeDiscovery) ServerGroups() (*metav1.APIGroupList, error) {
} }
// ServerVersion retrieves and parses the server's version.
func (c *FakeDiscovery) ServerVersion() (*version.Info, error) { func (c *FakeDiscovery) ServerVersion() (*version.Info, error) {
action := testing.ActionImpl{} action := testing.ActionImpl{}
action.Verb = "get" action.Verb = "get"
@@ -122,10 +132,13 @@ func (c *FakeDiscovery) ServerVersion() (*version.Info, error) {
return &versionInfo, nil return &versionInfo, nil
} }
// OpenAPISchema retrieves and parses the swagger API schema the server supports.
func (c *FakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) { func (c *FakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) {
return &openapi_v2.Document{}, nil return &openapi_v2.Document{}, nil
} }
// RESTClient returns a RESTClient that is used to communicate with API server
// by this client implementation.
func (c *FakeDiscovery) RESTClient() restclient.Interface { func (c *FakeDiscovery) RESTClient() restclient.Interface {
return nil return nil
} }
+6 -2
View File
@@ -31,11 +31,11 @@ import (
func MatchesServerVersion(clientVersion apimachineryversion.Info, client DiscoveryInterface) error { func MatchesServerVersion(clientVersion apimachineryversion.Info, client DiscoveryInterface) error {
sVer, err := client.ServerVersion() sVer, err := client.ServerVersion()
if err != nil { if err != nil {
return fmt.Errorf("couldn't read version from server: %v\n", err) return fmt.Errorf("couldn't read version from server: %v", err)
} }
// GitVersion includes GitCommit and GitTreeState, but best to be safe? // GitVersion includes GitCommit and GitTreeState, but best to be safe?
if clientVersion.GitVersion != sVer.GitVersion || clientVersion.GitCommit != sVer.GitCommit || clientVersion.GitTreeState != sVer.GitTreeState { if clientVersion.GitVersion != sVer.GitVersion || clientVersion.GitCommit != sVer.GitCommit || clientVersion.GitTreeState != sVer.GitTreeState {
return fmt.Errorf("server version (%#v) differs from client version (%#v)!\n", sVer, clientVersion) return fmt.Errorf("server version (%#v) differs from client version (%#v)", sVer, clientVersion)
} }
return nil return nil
@@ -101,12 +101,15 @@ func FilteredBy(pred ResourcePredicate, rls []*metav1.APIResourceList) []*metav1
return result return result
} }
// ResourcePredicate has a method to check if a resource matches a given condition.
type ResourcePredicate interface { type ResourcePredicate interface {
Match(groupVersion string, r *metav1.APIResource) bool Match(groupVersion string, r *metav1.APIResource) bool
} }
// ResourcePredicateFunc returns true if it matches a resource based on a custom condition.
type ResourcePredicateFunc func(groupVersion string, r *metav1.APIResource) bool type ResourcePredicateFunc func(groupVersion string, r *metav1.APIResource) bool
// Match is a wrapper around ResourcePredicateFunc.
func (fn ResourcePredicateFunc) Match(groupVersion string, r *metav1.APIResource) bool { func (fn ResourcePredicateFunc) Match(groupVersion string, r *metav1.APIResource) bool {
return fn(groupVersion, r) return fn(groupVersion, r)
} }
@@ -116,6 +119,7 @@ type SupportsAllVerbs struct {
Verbs []string Verbs []string
} }
// Match checks if a resource contains all the given verbs.
func (p SupportsAllVerbs) Match(groupVersion string, r *metav1.APIResource) bool { func (p SupportsAllVerbs) Match(groupVersion string, r *metav1.APIResource) bool {
return sets.NewString([]string(r.Verbs)...).HasAll(p.Verbs...) return sets.NewString([]string(r.Verbs)...).HasAll(p.Verbs...)
} }
+1 -1
View File
@@ -179,7 +179,7 @@ func (c *ExpirationCache) Delete(obj interface{}) error {
func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error { func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error {
c.expirationLock.Lock() c.expirationLock.Lock()
defer c.expirationLock.Unlock() defer c.expirationLock.Unlock()
items := map[string]interface{}{} items := make(map[string]interface{}, len(list))
ts := c.clock.Now() ts := c.clock.Now()
for _, item := range list { for _, item := range list {
key, err := c.keyFunc(item) key, err := c.keyFunc(item)
+1 -1
View File
@@ -297,7 +297,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) {
// after calling this function. f's queue is reset, too; upon return, it // after calling this function. f's queue is reset, too; upon return, it
// will contain the items in the map, in no particular order. // will contain the items in the map, in no particular order.
func (f *FIFO) Replace(list []interface{}, resourceVersion string) error { func (f *FIFO) Replace(list []interface{}, resourceVersion string) error {
items := map[string]interface{}{} items := make(map[string]interface{}, len(list))
for _, item := range list { for _, item := range list {
key, err := f.keyFunc(item) key, err := f.keyFunc(item)
if err != nil { if err != nil {
+1 -1
View File
@@ -210,7 +210,7 @@ func (c *cache) GetByKey(key string) (item interface{}, exists bool, err error)
// 'c' takes ownership of the list, you should not reference the list again // 'c' takes ownership of the list, you should not reference the list again
// after calling this function. // after calling this function.
func (c *cache) Replace(list []interface{}, resourceVersion string) error { func (c *cache) Replace(list []interface{}, resourceVersion string) error {
items := map[string]interface{}{} items := make(map[string]interface{}, len(list))
for _, item := range list { for _, item := range list {
key, err := c.keyFunc(item) key, err := c.keyFunc(item)
if err != nil { if err != nil {
@@ -724,6 +724,10 @@ func genComment(out io.Writer, lines []string, indent string) {
lines = lines[:l-1] lines = lines[:l-1]
} }
for _, c := range lines { for _, c := range lines {
if len(c) == 0 {
fmt.Fprintf(out, "%s//\n", indent) // avoid trailing whitespace
continue
}
fmt.Fprintf(out, "%s// %s\n", indent, c) fmt.Fprintf(out, "%s// %s\n", indent, c)
} }
} }
+4 -4
View File
@@ -50,7 +50,7 @@ shift 4
# To support running this script from anywhere, we have to first cd into this directory # To support running this script from anywhere, we have to first cd into this directory
# so we can install the tools. # so we can install the tools.
cd $(dirname "${0}") cd $(dirname "${0}")
go install ./cmd/{defaulter-gen,client-gen,lister-gen,informer-gen,deepcopy-gen} go install ${GOFLAGS:-} ./cmd/{defaulter-gen,client-gen,lister-gen,informer-gen,deepcopy-gen}
) )
function codegen::join() { local IFS="$1"; shift; echo "$*"; } function codegen::join() { local IFS="$1"; shift; echo "$*"; }
@@ -72,8 +72,8 @@ if [ "${GENS}" = "all" ] || grep -qw "deepcopy" <<<"${GENS}"; then
fi fi
if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then
echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset" echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}"
${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/clientset "$@" ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset} "$@"
fi fi
if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then
@@ -85,7 +85,7 @@ if [ "${GENS}" = "all" ] || grep -qw "informer" <<<"${GENS}"; then
echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers" echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers"
${GOPATH}/bin/informer-gen \ ${GOPATH}/bin/informer-gen \
--input-dirs $(codegen::join , "${FQ_APIS[@]}") \ --input-dirs $(codegen::join , "${FQ_APIS[@]}") \
--versioned-clientset-package ${OUTPUT_PKG}/clientset/${CLIENTSET_NAME_VERSIONED:-versioned} \ --versioned-clientset-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_VERSIONED:-versioned} \
--listers-package ${OUTPUT_PKG}/listers \ --listers-package ${OUTPUT_PKG}/listers \
--output-package ${OUTPUT_PKG}/informers \ --output-package ${OUTPUT_PKG}/informers \
"$@" "$@"
+6 -6
View File
@@ -47,7 +47,7 @@ EXT_APIS_PKG="$4"
GROUPS_WITH_VERSIONS="$5" GROUPS_WITH_VERSIONS="$5"
shift 5 shift 5
go install ./$(dirname "${0}")/cmd/{defaulter-gen,conversion-gen,client-gen,lister-gen,informer-gen,deepcopy-gen} go install ${GOFLAGS:-} ./$(dirname "${0}")/cmd/{defaulter-gen,conversion-gen,client-gen,lister-gen,informer-gen,deepcopy-gen}
function codegen::join() { local IFS="$1"; shift; echo "$*"; } function codegen::join() { local IFS="$1"; shift; echo "$*"; }
# enumerate group versions # enumerate group versions
@@ -85,11 +85,11 @@ if [ "${GENS}" = "all" ] || grep -qw "conversion" <<<"${GENS}"; then
fi fi
if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then
echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset" echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}"
if [ -n "${INT_APIS_PKG}" ]; then if [ -n "${INT_APIS_PKG}" ]; then
${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_INTERNAL:-internalversion} --input-base "" --input $(codegen::join , $(printf '%s/ ' "${INT_FQ_APIS[@]}")) --output-package ${OUTPUT_PKG}/clientset "$@" ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_INTERNAL:-internalversion} --input-base "" --input $(codegen::join , $(printf '%s/ ' "${INT_FQ_APIS[@]}")) --output-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset} "$@"
fi fi
${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${EXT_FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/clientset "$@" ${GOPATH}/bin/client-gen --clientset-name ${CLIENTSET_NAME_VERSIONED:-versioned} --input-base "" --input $(codegen::join , "${EXT_FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset} "$@"
fi fi
if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then
@@ -101,8 +101,8 @@ if [ "${GENS}" = "all" ] || grep -qw "informer" <<<"${GENS}"; then
echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers" echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers"
${GOPATH}/bin/informer-gen \ ${GOPATH}/bin/informer-gen \
--input-dirs $(codegen::join , "${ALL_FQ_APIS[@]}") \ --input-dirs $(codegen::join , "${ALL_FQ_APIS[@]}") \
--versioned-clientset-package ${OUTPUT_PKG}/clientset/${CLIENTSET_NAME_VERSIONED:-versioned} \ --versioned-clientset-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_VERSIONED:-versioned} \
--internal-clientset-package ${OUTPUT_PKG}/clientset/${CLIENTSET_NAME_INTERNAL:-internalversion} \ --internal-clientset-package ${OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_INTERNAL:-internalversion} \
--listers-package ${OUTPUT_PKG}/listers \ --listers-package ${OUTPUT_PKG}/listers \
--output-package ${OUTPUT_PKG}/informers \ --output-package ${OUTPUT_PKG}/informers \
"$@" "$@"