diff --git a/pkg/api/types.go b/pkg/api/types.go index eaeb4d71667..fe152b7a4c9 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -27,7 +27,7 @@ import ( // Many fields in this API have formatting requirements. The commonly used // formats are defined here. // -// C_IDENTIFIER: This is a string that conforms the definition of an "identifier" +// C_IDENTIFIER: This is a string that conforms to the definition of an "identifier" // in the C language. This is captured by the following regex: // [A-Za-z_][A-Za-z0-9_]* // This defines the format, but not the length restriction, which should be @@ -45,15 +45,93 @@ import ( // or more simply: // DNS_LABEL(\.DNS_LABEL)* +// TypeMeta describes an individual object in an API response or request +// with strings representing the type of the object and its API schema version. +// Structures that are versioned or persisted should inline TypeMeta. +type TypeMeta struct { + // Kind is a string value representing the REST resource this object represents. + // Servers may infer this from the endpoint the client submits requests to. + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + + // APIVersion defines the versioned schema of this representation of an object. + // Servers should convert recognized schemas to the latest internal value, and + // may reject unrecognized values. + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` +} + +// ListMeta describes metadata that synthetic resources must have, including lists and +// various status objects. A resource may have only one of {ObjectMeta, ListMeta}. +type ListMeta struct { + // SelfLink is a URL representing this object. + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + + // An opaque value that represents the version of this response for use with optimistic + // concurrency and change monitoring endpoints. Clients must treat these values as opaque + // and values may only be valid for a particular resource or set of resources. Only servers + // will generate resource versions. + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` +} + +// ObjectMeta is metadata that all persisted resources must have, which includes all objects +// users must create. A resource may have only one of {ObjectMeta, ListMeta}. +type ObjectMeta struct { + // Name is unique within a namespace. Name is required when creating resources, although + // some resources may allow a client to request the generation of an appropriate name + // automatically. Name is primarily intended for creation idempotence and configuration + // definition. + Name string `json:"name,omitempty" yaml:"name,omitempty"` + + // Namespace defines the space within which name must be unique. An empty namespace is + // 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 + // those objects will be empty. + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + + // SelfLink is a URL representing this object. + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + + // 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 + // operations. + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` + + // An opaque value that represents the version of this resource. May be used for optimistic + // concurrency, change detection, and the watch operation on a resource or set of resources. + // Clients must treat these values as opaque and values may only be valid for a particular + // resource or set of resources. Only servers will generate resource versions. + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` + + // 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. + // Clients may not set this value. It is represented in RFC3339 form and is in UTC. + CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` + + // Labels are key value pairs that may be used to scope and select individual resources. + // TODO: replace map[string]string with labels.LabelSet type + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + + // Annotations are unstructured key value data stored with a resource that may be set by + // external tooling. They are not queryable and should be preserved when modifying + // objects. + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` +} + +const ( + // NamespaceDefault means the object is in the default namespace which is applied when not specified by clients + NamespaceDefault string = "default" + // NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces + NamespaceAll string = "" +) + // Volume represents a named volume in a pod that may be accessed by any containers in the pod. type Volume struct { // Required: This must be a DNS_LABEL. Each volume in a pod must have // a unique name. - Name string `yaml:"name" json:"name"` + Name string `json:"name" yaml:"name"` // Source represents the location and type of a volume to mount. // This is optional for now. If not specified, the Volume is implied to be an EmptyDir. // This implied behavior is deprecated and will be removed in a future version. - Source *VolumeSource `yaml:"source" json:"source"` + Source *VolumeSource `json:"source" yaml:"source"` } type VolumeSource struct { @@ -61,19 +139,19 @@ type VolumeSource struct { // HostDir represents a pre-existing directory on the host machine that is directly // exposed to the container. This is generally used for system agents or other privileged // things that are allowed to see the host machine. Most containers will NOT need this. - // TODO(jonesdl) We need to restrict who can use host directory mounts and - // who can/can not mount host directories as read/write. - HostDir *HostDir `yaml:"hostDir" json:"hostDir"` + // TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + // mount host directories as read/write. + HostDir *HostDir `json:"hostDir" yaml:"hostDir"` // EmptyDir represents a temporary directory that shares a pod's lifetime. - EmptyDir *EmptyDir `yaml:"emptyDir" json:"emptyDir"` + EmptyDir *EmptyDir `json:"emptyDir" yaml:"emptyDir"` // GCEPersistentDisk represents a GCE Disk resource that is attached to a // kubelet's host machine and then exposed to the pod. - GCEPersistentDisk *GCEPersistentDisk `yaml:"persistentDisk" json:"persistentDisk"` + GCEPersistentDisk *GCEPersistentDisk `json:"persistentDisk" yaml:"persistentDisk"` } // HostDir represents bare host directory volume. type HostDir struct { - Path string `yaml:"path" json:"path"` + Path string `json:"path" yaml:"path"` } type EmptyDir struct{} @@ -113,49 +191,49 @@ type GCEPersistentDisk struct { type Port struct { // Optional: If specified, this must be a DNS_LABEL. Each named port // in a pod must have a unique name. - Name string `yaml:"name,omitempty" json:"name,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` // Optional: If specified, this must be a valid port number, 0 < x < 65536. - HostPort int `yaml:"hostPort,omitempty" json:"hostPort,omitempty"` + HostPort int `json:"hostPort,omitempty" yaml:"hostPort,omitempty"` // Required: This must be a valid port number, 0 < x < 65536. - ContainerPort int `yaml:"containerPort" json:"containerPort"` - // Optional: Defaults to "TCP". - Protocol Protocol `yaml:"protocol,omitempty" json:"protocol,omitempty"` + ContainerPort int `json:"containerPort" yaml:"containerPort"` + // Optional: Supports "TCP" and "UDP". Defaults to "TCP". + Protocol Protocol `json:"protocol,omitempty" yaml:"protocol,omitempty"` // Optional: What host IP to bind the external port to. - HostIP string `yaml:"hostIP,omitempty" json:"hostIP,omitempty"` + HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"` } // VolumeMount describes a mounting of a Volume within a container. type VolumeMount struct { // Required: This must match the Name of a Volume [above]. - Name string `yaml:"name" json:"name"` + Name string `json:"name" yaml:"name"` // Optional: Defaults to false (read-write). - ReadOnly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` // Required. - MountPath string `yaml:"mountPath,omitempty" json:"mountPath,omitempty"` + MountPath string `json:"mountPath,omitempty" yaml:"mountPath,omitempty"` } // EnvVar represents an environment variable present in a Container. type EnvVar struct { // Required: This must be a C_IDENTIFIER. - Name string `yaml:"name" json:"name"` + Name string `json:"name" yaml:"name"` // Optional: defaults to "". - Value string `yaml:"value,omitempty" json:"value,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` } // HTTPGetAction describes an action based on HTTP Get requests. type HTTPGetAction struct { // Optional: Path to access on the HTTP server. - Path string `yaml:"path,omitempty" json:"path,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` // Required: Name or number of the port to access on the container. - Port util.IntOrString `yaml:"port,omitempty" json:"port,omitempty"` + Port util.IntOrString `json:"port,omitempty" yaml:"port,omitempty"` // Optional: Host name to connect to, defaults to the pod IP. - Host string `yaml:"host,omitempty" json:"host,omitempty"` + Host string `json:"host,omitempty" yaml:"host,omitempty"` } // TCPSocketAction describes an action based on opening a socket type TCPSocketAction struct { // Required: Port to connect to. - Port util.IntOrString `yaml:"port,omitempty" json:"port,omitempty"` + Port util.IntOrString `json:"port,omitempty" yaml:"port,omitempty"` } // ExecAction describes a "run in container" action. @@ -196,22 +274,22 @@ const ( type Container struct { // Required: This must be a DNS_LABEL. Each container in a pod must // have a unique name. - Name string `yaml:"name" json:"name"` + Name string `json:"name" yaml:"name"` // Required. - Image string `yaml:"image" json:"image"` + Image string `json:"image" yaml:"image"` // Optional: Defaults to whatever is defined in the image. - Command []string `yaml:"command,omitempty" json:"command,omitempty"` + Command []string `json:"command,omitempty" yaml:"command,omitempty"` // Optional: Defaults to Docker's default. - WorkingDir string `yaml:"workingDir,omitempty" json:"workingDir,omitempty"` - Ports []Port `yaml:"ports,omitempty" json:"ports,omitempty"` - Env []EnvVar `yaml:"env,omitempty" json:"env,omitempty"` + WorkingDir string `json:"workingDir,omitempty" yaml:"workingDir,omitempty"` + Ports []Port `json:"ports,omitempty" yaml:"ports,omitempty"` + Env []EnvVar `json:"env,omitempty" yaml:"env,omitempty"` // Optional: Defaults to unlimited. - Memory int `yaml:"memory,omitempty" json:"memory,omitempty"` + Memory int `json:"memory,omitempty" yaml:"memory,omitempty"` // Optional: Defaults to unlimited. - CPU int `yaml:"cpu,omitempty" json:"cpu,omitempty"` - VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"` - LivenessProbe *LivenessProbe `yaml:"livenessProbe,omitempty" json:"livenessProbe,omitempty"` - Lifecycle *Lifecycle `yaml:"lifecycle,omitempty" json:"lifecycle,omitempty"` + CPU int `json:"cpu,omitempty" yaml:"cpu,omitempty"` + VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" yaml:"volumeMounts,omitempty"` + LivenessProbe *LivenessProbe `json:"livenessProbe,omitempty" yaml:"livenessProbe,omitempty"` + Lifecycle *Lifecycle `json:"lifecycle,omitempty" yaml:"lifecycle,omitempty"` // Optional: Default to false. Privileged bool `json:"privileged,omitempty" yaml:"privileged,omitempty"` // Optional: Policy for pulling images for this container @@ -223,9 +301,9 @@ type Container struct { type Handler struct { // One and only one of the following should be specified. // Exec specifies the action to take. - Exec *ExecAction `yaml:"exec,omitempty" json:"exec,omitempty"` + Exec *ExecAction `json:"exec,omitempty" yaml:"exec,omitempty"` // HTTPGet specifies the http request to perform. - HTTPGet *HTTPGetAction `yaml:"httpGet,omitempty" json:"httpGet,omitempty"` + HTTPGet *HTTPGetAction `json:"httpGet,omitempty" yaml:"httpGet,omitempty"` } // Lifecycle describes actions that the management system should take in response to container lifecycle @@ -234,7 +312,7 @@ type Handler struct { type Lifecycle struct { // PostStart is called immediately after a container is created. If the handler fails, the container // is terminated and restarted. - PostStart *Handler `yaml:"postStart,omitempty" json:"postStart,omitempty"` + PostStart *Handler `json:"postStart,omitempty" yaml:"postStart,omitempty"` // PreStop is called immediately before a container is terminated. The reason for termination is // passed to the handler. Regardless of the outcome of the handler, the container is eventually terminated. PreStop *Handler `yaml:"preStop,omitempty" json:"preStop,omitempty"` @@ -242,30 +320,6 @@ type Lifecycle struct { // The below types are used by kube_client and api_server. -// TypeMeta is shared by all objects sent to, or returned from the client. -type TypeMeta struct { - Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` - Name string `json:"name,omitempty" yaml:"name,omitempty"` - CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` - SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` - ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` - APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` - Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` - UID string `json:"uid,omitempty" yaml:"uid,omitempty"` - - // Annotations are unstructured key value data stored with a resource that may be set by - // external tooling. They are not queryable and should be preserved when modifying - // objects. - Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` -} - -const ( - // NamespaceDefault means the object is in the default namespace which is applied when not specified by clients - NamespaceDefault string = "default" - // NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces - NamespaceAll string = "" -) - // PodStatus represents a status of a pod. type PodStatus string @@ -358,15 +412,18 @@ type PodState struct { // PodList is a list of Pods. type PodList struct { TypeMeta `json:",inline" yaml:",inline"` - Items []Pod `json:"items" yaml:"items,omitempty"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []Pod `json:"items" yaml:"items,omitempty"` } // Pod is a collection of containers, used as either input (create, update) or as output (list, get). type Pod struct { - TypeMeta `json:",inline" yaml:",inline"` - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"` - CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"` + CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"` } // ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get). @@ -379,15 +436,18 @@ type ReplicationControllerState struct { // ReplicationControllerList is a collection of replication controllers. type ReplicationControllerList struct { TypeMeta `json:",inline" yaml:",inline"` - Items []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"` } // ReplicationController represents the configuration of a replication controller. type ReplicationController struct { - TypeMeta `json:",inline" yaml:",inline"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + DesiredState ReplicationControllerState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"` CurrentState ReplicationControllerState `json:"currentState,omitempty" yaml:"currentState,omitempty"` - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` } // PodTemplate holds the information used for creating pods. @@ -399,23 +459,23 @@ type PodTemplate struct { // ServiceList holds a list of services. type ServiceList struct { TypeMeta `json:",inline" yaml:",inline"` - Items []Service `json:"items" yaml:"items"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []Service `json:"items" yaml:"items"` } // Service is a named abstraction of software service (for example, mysql) consisting of local port // (for example 3306) that the proxy listens on, and the selector that determines which pods // will answer requests sent through the proxy. type Service struct { - TypeMeta `json:",inline" yaml:",inline"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` // Required. Port int `json:"port" yaml:"port"` // Optional: Defaults to "TCP". Protocol Protocol `yaml:"protocol,omitempty" json:"protocol,omitempty"` - // This service's labels. - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - // This service will route traffic to pods having labels matching this selector. Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"` CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"` @@ -435,14 +495,18 @@ type Service struct { // Endpoints is a collection of endpoints that implement the actual service, for example: // Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"] type Endpoints struct { - TypeMeta `json:",inline" yaml:",inline"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Endpoints []string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"` } // EndpointsList is a list of endpoints. type EndpointsList struct { TypeMeta `json:",inline" yaml:",inline"` - Items []Endpoints `json:"items,omitempty" yaml:"items,omitempty"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []Endpoints `json:"items,omitempty" yaml:"items,omitempty"` } // NodeResources represents resources on a Kubernetes system node @@ -460,7 +524,9 @@ type ResourceList map[ResourceName]util.IntOrString // Minion is a worker node in Kubernetenes. // The name of the minion according to etcd is in ID. type Minion struct { - TypeMeta `json:",inline" yaml:",inline"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + // Queried from cloud provider, if available. HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"` // Resources available on the node @@ -470,21 +536,27 @@ type Minion struct { // MinionList is a list of minions. type MinionList struct { TypeMeta `json:",inline" yaml:",inline"` - Items []Minion `json:"items,omitempty" yaml:"items,omitempty"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []Minion `json:"items,omitempty" yaml:"items,omitempty"` } // Binding is written by a scheduler to cause a pod to be bound to a host. type Binding struct { - TypeMeta `json:",inline" yaml:",inline"` - PodID string `json:"podID" yaml:"podID"` - Host string `json:"host" yaml:"host"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + PodID string `json:"podID" yaml:"podID"` + Host string `json:"host" yaml:"host"` } // Status is a return value for calls that don't return other objects. // TODO: this could go in apiserver, but I'm including it here so clients needn't // import both. type Status struct { - TypeMeta `json:",inline" yaml:",inline"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + // One of: "Success", "Failure", "Working" (for operations not yet completed) Status string `json:"status,omitempty" yaml:"status,omitempty"` // A human-readable description of the status of this operation. @@ -636,13 +708,16 @@ const ( // ServerOp is an operation delivered to API clients. type ServerOp struct { - TypeMeta `yaml:",inline" json:",inline"` + TypeMeta `yaml:",inline" json:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` } // ServerOpList is a list of operations, as delivered to API clients. type ServerOpList struct { TypeMeta `yaml:",inline" json:",inline"` - Items []ServerOp `yaml:"items,omitempty" json:"items,omitempty"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []ServerOp `yaml:"items,omitempty" json:"items,omitempty"` } // ObjectReference contains enough information to let you inspect or modify the referred object. @@ -667,7 +742,8 @@ type ObjectReference struct { // Event is a report of an event somewhere in the cluster. // TODO: Decide whether to store these separately or with the object they apply to. type Event struct { - TypeMeta `yaml:",inline" json:",inline"` + TypeMeta `yaml:",inline" json:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` // Required. The object that this event is about. InvolvedObject ObjectReference `json:"involvedObject,omitempty" yaml:"involvedObject,omitempty"` @@ -702,7 +778,9 @@ type Event struct { // EventList is a list of events. type EventList struct { TypeMeta `yaml:",inline" json:",inline"` - Items []Event `yaml:"items,omitempty" json:"items,omitempty"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []Event `yaml:"items,omitempty" json:"items,omitempty"` } // ContainerManifest corresponds to the Container Manifest format, documented at: @@ -728,7 +806,9 @@ type ContainerManifest struct { // DEPRECATED: Replaced with BoundPods type ContainerManifestList struct { TypeMeta `json:",inline" yaml:",inline"` - Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"` + ListMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + + Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"` } // Included in partial form from v1beta3 to replace ContainerManifest @@ -744,7 +824,8 @@ type PodSpec struct { // defines how a Pod may change after a Binding is created. A Pod is a request to // execute a pod, whereas a BoundPod is the specification that would be run on a server. type BoundPod struct { - TypeMeta `json:",inline" yaml:",inline"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` // Spec defines the behavior of a pod. Spec PodSpec `json:"spec,omitempty" yaml:"spec,omitempty"` @@ -753,7 +834,8 @@ type BoundPod struct { // BoundPods is a list of Pods bound to a common server. The resource version of // the pod list is guaranteed to only change when the list of bound pods changes. type BoundPods struct { - TypeMeta `json:",inline" yaml:",inline"` + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` // Host is the name of a node that these pods were bound to. Host string `json:"host" yaml:"host"`