diff --git a/cmd/genconversion/conversion.go b/cmd/genconversion/conversion.go index 76321f57f3a..b3abc37c1b2 100644 --- a/cmd/genconversion/conversion.go +++ b/cmd/genconversion/conversion.go @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/api" _ "k8s.io/kubernetes/pkg/api/install" "k8s.io/kubernetes/pkg/api/unversioned" + _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" _ "k8s.io/kubernetes/pkg/apis/componentconfig/install" _ "k8s.io/kubernetes/pkg/apis/extensions/install" _ "k8s.io/kubernetes/pkg/apis/metrics/install" diff --git a/cmd/gendeepcopy/deep_copy.go b/cmd/gendeepcopy/deep_copy.go index 42c887f82bc..b569212608a 100644 --- a/cmd/gendeepcopy/deep_copy.go +++ b/cmd/gendeepcopy/deep_copy.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api" _ "k8s.io/kubernetes/pkg/api/install" "k8s.io/kubernetes/pkg/api/unversioned" + _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" _ "k8s.io/kubernetes/pkg/apis/componentconfig/install" _ "k8s.io/kubernetes/pkg/apis/extensions/install" _ "k8s.io/kubernetes/pkg/apis/metrics/install" diff --git a/hack/after-build/update-generated-conversions.sh b/hack/after-build/update-generated-conversions.sh index 4258ff6f824..03ddc21a8f1 100755 --- a/hack/after-build/update-generated-conversions.sh +++ b/hack/after-build/update-generated-conversions.sh @@ -43,7 +43,7 @@ EOF } # TODO(lavalamp): get this list by listing the pkg/apis/ directory? -DEFAULT_GROUP_VERSIONS="v1 authorization/v1beta1 extensions/v1beta1 componentconfig/v1alpha1 metrics/v1alpha1" +DEFAULT_GROUP_VERSIONS="v1 authorization/v1beta1 autoscaling/v1 extensions/v1beta1 componentconfig/v1alpha1 metrics/v1alpha1" VERSIONS=${VERSIONS:-$DEFAULT_GROUP_VERSIONS} for ver in $VERSIONS; do # Ensure that the version being processed is registered by setting diff --git a/hack/after-build/update-generated-deep-copies.sh b/hack/after-build/update-generated-deep-copies.sh index c3089be5e71..4fa21360c14 100755 --- a/hack/after-build/update-generated-deep-copies.sh +++ b/hack/after-build/update-generated-deep-copies.sh @@ -62,6 +62,6 @@ function generate_deep_copies() { # Currently pkg/api/deep_copy_generated.go is generated by the new go2idl generator. # All others (mentioned above) are still generated by the old reflection-based generator. # TODO: Migrate these to the new generator. -DEFAULT_VERSIONS="v1 authorization/__internal authorization/v1beta1 extensions/__internal extensions/v1beta1 componentconfig/__internal componentconfig/v1alpha1 metrics/__internal metrics/v1alpha1" +DEFAULT_VERSIONS="v1 authorization/__internal authorization/v1beta1 autoscaling/__internal autoscaling/v1 extensions/__internal extensions/v1beta1 componentconfig/__internal componentconfig/v1alpha1 metrics/__internal metrics/v1alpha1" VERSIONS=${VERSIONS:-$DEFAULT_VERSIONS} generate_deep_copies "$VERSIONS" diff --git a/hack/after-build/update-swagger-spec.sh b/hack/after-build/update-swagger-spec.sh index 18c306d98e3..f2c9194be01 100755 --- a/hack/after-build/update-swagger-spec.sh +++ b/hack/after-build/update-swagger-spec.sh @@ -50,7 +50,7 @@ kube::etcd::start # Start kube-apiserver kube::log::status "Starting kube-apiserver" -KUBE_API_VERSIONS="v1,extensions/v1beta1" "${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \ +KUBE_API_VERSIONS="v1,autoscaling/v1,extensions/v1beta1" "${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \ --address="127.0.0.1" \ --public-address-override="127.0.0.1" \ --port="${API_PORT}" \ @@ -64,7 +64,7 @@ APISERVER_PID=$! kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver: " SWAGGER_API_PATH="http://127.0.0.1:${API_PORT}/swaggerapi/" -DEFAULT_GROUP_VERSIONS="v1 extensions/v1beta1" +DEFAULT_GROUP_VERSIONS="v1 autoscaling/v1 extensions/v1beta1" VERSIONS=${VERSIONS:-$DEFAULT_GROUP_VERSIONS} kube::log::status "Updating " ${SWAGGER_ROOT_DIR} diff --git a/hack/after-build/verify-generated-conversions.sh b/hack/after-build/verify-generated-conversions.sh index 56bd73f8c83..e05197485d9 100755 --- a/hack/after-build/verify-generated-conversions.sh +++ b/hack/after-build/verify-generated-conversions.sh @@ -23,7 +23,7 @@ source "${KUBE_ROOT}/hack/lib/init.sh" kube::golang::setup_env -APIROOTS=${APIROOTS:-pkg/api pkg/apis/authorization pkg/apis/extensions pkg/apis/metrics} +APIROOTS=${APIROOTS:-pkg/api pkg/apis/authorization pkg/apis/autoscaling pkg/apis/extensions pkg/apis/metrics} _tmp="${KUBE_ROOT}/_tmp" cleanup() { diff --git a/hack/after-build/verify-generated-deep-copies.sh b/hack/after-build/verify-generated-deep-copies.sh index b8e594027b3..0ba2b2764d7 100755 --- a/hack/after-build/verify-generated-deep-copies.sh +++ b/hack/after-build/verify-generated-deep-copies.sh @@ -25,7 +25,7 @@ kube::golang::setup_env gendeepcopy=$(kube::util::find-binary "gendeepcopy") -APIROOTS=${APIROOTS:-pkg/api pkg/apis/authorization pkg/apis/extensions pkg/apis/metrics} +APIROOTS=${APIROOTS:-pkg/api pkg/apis/authorization pkg/apis/autoscaling pkg/apis/extensions pkg/apis/metrics} _tmp="${KUBE_ROOT}/_tmp" cleanup() { diff --git a/hack/update-generated-swagger-docs.sh b/hack/update-generated-swagger-docs.sh index 5bdcfedbc23..837b5c59886 100755 --- a/hack/update-generated-swagger-docs.sh +++ b/hack/update-generated-swagger-docs.sh @@ -56,7 +56,7 @@ EOF mv "$TMPFILE" "pkg/$(kube::util::group-version-to-pkg-path "${group_version}")/types_swagger_doc_generated.go" } -GROUP_VERSIONS=(unversioned v1 authorization/v1beta1 extensions/v1beta1) +GROUP_VERSIONS=(unversioned v1 authorization/v1beta1 autoscaling/v1 extensions/v1beta1) # To avoid compile errors, remove the currently existing files. for group_version in "${GROUP_VERSIONS[@]}"; do rm -f "pkg/$(kube::util::group-version-to-pkg-path "${group_version}")/types_swagger_doc_generated.go" diff --git a/pkg/apis/autoscaling/install/install.go b/pkg/apis/autoscaling/install/install.go new file mode 100644 index 00000000000..6e226a06644 --- /dev/null +++ b/pkg/apis/autoscaling/install/install.go @@ -0,0 +1,129 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package install installs the experimental API group, making it available as +// an option to all of the API encoding/decoding machinery. +package install + +import ( + "fmt" + + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apimachinery" + "k8s.io/kubernetes/pkg/apimachinery/registered" + "k8s.io/kubernetes/pkg/apis/autoscaling" + "k8s.io/kubernetes/pkg/apis/autoscaling/v1" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/sets" +) + +const importPrefix = "k8s.io/kubernetes/pkg/apis/autoscaling" + +var accessor = meta.NewAccessor() + +// availableVersions lists all known external versions for this group from most preferred to least preferred +var availableVersions = []unversioned.GroupVersion{v1.SchemeGroupVersion} + +func init() { + registered.RegisterVersions(availableVersions) + externalVersions := []unversioned.GroupVersion{} + for _, v := range availableVersions { + if registered.IsAllowedVersion(v) { + externalVersions = append(externalVersions, v) + } + } + if len(externalVersions) == 0 { + glog.V(4).Infof("No version is registered for group %v", autoscaling.GroupName) + return + } + + if err := registered.EnableVersions(externalVersions...); err != nil { + glog.V(4).Infof("%v", err) + return + } + if err := enableVersions(externalVersions); err != nil { + glog.V(4).Infof("%v", err) + return + } +} + +// TODO: enableVersions should be centralized rather than spread in each API +// group. +// We can combine registered.RegisterVersions, registered.EnableVersions and +// registered.RegisterGroup once we have moved enableVersions there. +func enableVersions(externalVersions []unversioned.GroupVersion) error { + addVersionsToScheme(externalVersions...) + preferredExternalVersion := externalVersions[0] + + groupMeta := apimachinery.GroupMeta{ + GroupVersion: preferredExternalVersion, + GroupVersions: externalVersions, + RESTMapper: newRESTMapper(externalVersions), + SelfLinker: runtime.SelfLinker(accessor), + InterfacesFor: interfacesFor, + } + + if err := registered.RegisterGroup(groupMeta); err != nil { + return err + } + api.RegisterRESTMapper(groupMeta.RESTMapper) + return nil +} + +func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { + // the list of kinds that are scoped at the root of the api hierarchy + // if a kind is not enumerated here, it is assumed to have a namespace scope + rootScoped := sets.NewString() + + ignoredKinds := sets.NewString() + + return api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) +} + +// interfacesFor returns the default Codec and ResourceVersioner for a given version +// string, or an error if the version is not known. +func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) { + switch version { + case v1.SchemeGroupVersion: + return &meta.VersionInterfaces{ + ObjectConvertor: api.Scheme, + MetadataAccessor: accessor, + }, nil + default: + g, _ := registered.Group(autoscaling.GroupName) + return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions) + } +} + +func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) { + // add the internal version to Scheme + autoscaling.AddToScheme(api.Scheme) + // add the enabled external versions to Scheme + for _, v := range externalVersions { + if !registered.IsEnabledVersion(v) { + glog.Errorf("Version %s is not enabled, so it will not be added to the Scheme.", v) + continue + } + switch v { + case v1.SchemeGroupVersion: + v1.AddToScheme(api.Scheme) + } + } +} diff --git a/pkg/apis/autoscaling/register.go b/pkg/apis/autoscaling/register.go new file mode 100644 index 00000000000..519e8f6be0b --- /dev/null +++ b/pkg/apis/autoscaling/register.go @@ -0,0 +1,54 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package autoscaling + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/runtime" +) + +// GroupName is the group name use in this package +const GroupName = "autoscaling" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) unversioned.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns back a Group qualified GroupResource +func Resource(resource string) unversioned.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +func AddToScheme(scheme *runtime.Scheme) { + // Add the API to Scheme. + addKnownTypes(scheme) +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) { + scheme.AddKnownTypes(SchemeGroupVersion, + &extensions.HorizontalPodAutoscaler{}, + &extensions.HorizontalPodAutoscalerList{}, + &api.ListOptions{}, + ) +} diff --git a/pkg/apis/autoscaling/v1/defaults.go b/pkg/apis/autoscaling/v1/defaults.go new file mode 100644 index 00000000000..846d397fff2 --- /dev/null +++ b/pkg/apis/autoscaling/v1/defaults.go @@ -0,0 +1,35 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "k8s.io/kubernetes/pkg/runtime" +) + +func addDefaultingFuncs(scheme *runtime.Scheme) { + scheme.AddDefaultingFuncs( + func(obj *HorizontalPodAutoscaler) { + if obj.Spec.MinReplicas == nil { + minReplicas := int32(1) + obj.Spec.MinReplicas = &minReplicas + } + if obj.Spec.CPUUtilization == nil { + obj.Spec.CPUUtilization = &CPUTargetUtilization{TargetPercentage: 80} + } + }, + ) +} diff --git a/pkg/apis/autoscaling/v1/register.go b/pkg/apis/autoscaling/v1/register.go new file mode 100644 index 00000000000..f95285b4c30 --- /dev/null +++ b/pkg/apis/autoscaling/v1/register.go @@ -0,0 +1,46 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/runtime" +) + +// GroupName is the group name use in this package +const GroupName = "autoscaling" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1"} + +func AddToScheme(scheme *runtime.Scheme) { + addKnownTypes(scheme) + addDefaultingFuncs(scheme) +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) { + scheme.AddKnownTypes(SchemeGroupVersion, + &HorizontalPodAutoscaler{}, + &HorizontalPodAutoscalerList{}, + &v1.ListOptions{}, + ) +} + +func (obj *HorizontalPodAutoscaler) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *HorizontalPodAutoscalerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } diff --git a/pkg/apis/autoscaling/v1/types.go b/pkg/apis/autoscaling/v1/types.go new file mode 100644 index 00000000000..025acfbfc5a --- /dev/null +++ b/pkg/apis/autoscaling/v1/types.go @@ -0,0 +1,97 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" +) + +// SubresourceReference contains enough information to let you inspect or modify the referred subresource. +type SubresourceReference struct { + // Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + Kind string `json:"kind,omitempty"` + // Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names + Name string `json:"name,omitempty"` + // API version of the referent + APIVersion string `json:"apiVersion,omitempty"` + // Subresource name of the referent + Subresource string `json:"subresource,omitempty"` +} + +type CPUTargetUtilization struct { + // fraction of the requested CPU that should be utilized/used, + // e.g. 70 means that 70% of the requested CPU should be in use. + TargetPercentage int32 `json:"targetPercentage"` +} + +// specification of a horizontal pod autoscaler. +type HorizontalPodAutoscalerSpec struct { + // reference to Scale subresource; horizontal pod autoscaler will learn the current resource consumption from its status, + // and will set the desired number of pods by modifying its spec. + ScaleRef SubresourceReference `json:"scaleRef"` + // lower limit for the number of pods that can be set by the autoscaler, default 1. + MinReplicas *int32 `json:"minReplicas,omitempty"` + // upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + MaxReplicas int32 `json:"maxReplicas"` + // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; + // if not specified it defaults to the target CPU utilization at 80% of the requested resources. + CPUUtilization *CPUTargetUtilization `json:"cpuUtilization,omitempty"` +} + +// current status of a horizontal pod autoscaler +type HorizontalPodAutoscalerStatus struct { + // most recent generation observed by this autoscaler. + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + + // last time the HorizontalPodAutoscaler scaled the number of pods; + // used by the autoscaler to control how often the number of pods is changed. + LastScaleTime *unversioned.Time `json:"lastScaleTime,omitempty"` + + // current number of replicas of pods managed by this autoscaler. + CurrentReplicas int32 `json:"currentReplicas"` + + // desired number of replicas of pods managed by this autoscaler. + DesiredReplicas int32 `json:"desiredReplicas"` + + // current average CPU utilization over all pods, represented as a percentage of requested CPU, + // e.g. 70 means that an average pod is using now 70% of its requested CPU. + CurrentCPUUtilizationPercentage *int32 `json:"currentCPUUtilizationPercentage,omitempty"` +} + +// configuration of a horizontal pod autoscaler. +type HorizontalPodAutoscaler struct { + unversioned.TypeMeta `json:",inline"` + // Standard object metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + v1.ObjectMeta `json:"metadata,omitempty"` + + // behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty"` + + // current information about the autoscaler. + Status HorizontalPodAutoscalerStatus `json:"status,omitempty"` +} + +// list of horizontal pod autoscaler objects. +type HorizontalPodAutoscalerList struct { + unversioned.TypeMeta `json:",inline"` + // Standard list metadata. + unversioned.ListMeta `json:"metadata,omitempty"` + + // list of horizontal pod autoscaler objects. + Items []HorizontalPodAutoscaler `json:"items"` +} diff --git a/pkg/client/unversioned/import_known_versions.go b/pkg/client/unversioned/import_known_versions.go index 95f6644301c..a86afb6dda0 100644 --- a/pkg/client/unversioned/import_known_versions.go +++ b/pkg/client/unversioned/import_known_versions.go @@ -23,6 +23,7 @@ import ( _ "k8s.io/kubernetes/pkg/api/install" "k8s.io/kubernetes/pkg/apimachinery/registered" _ "k8s.io/kubernetes/pkg/apis/authorization/install" + _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" _ "k8s.io/kubernetes/pkg/apis/componentconfig/install" _ "k8s.io/kubernetes/pkg/apis/extensions/install" _ "k8s.io/kubernetes/pkg/apis/metrics/install" diff --git a/pkg/master/import_known_versions.go b/pkg/master/import_known_versions.go index 8a6f71919aa..b07ebdbe663 100644 --- a/pkg/master/import_known_versions.go +++ b/pkg/master/import_known_versions.go @@ -23,6 +23,7 @@ import ( _ "k8s.io/kubernetes/pkg/api/install" "k8s.io/kubernetes/pkg/apimachinery/registered" _ "k8s.io/kubernetes/pkg/apis/authorization/install" + _ "k8s.io/kubernetes/pkg/apis/autoscaling/install" _ "k8s.io/kubernetes/pkg/apis/componentconfig/install" _ "k8s.io/kubernetes/pkg/apis/extensions/install" )