diff --git a/cmd/kubernetes-discovery/BUILD b/cmd/kubernetes-discovery/BUILD index 7fe3d422530..29bba2b0bde 100644 --- a/cmd/kubernetes-discovery/BUILD +++ b/cmd/kubernetes-discovery/BUILD @@ -15,7 +15,13 @@ go_binary( srcs = ["main.go"], tags = ["automanaged"], deps = [ - "//cmd/kubernetes-discovery/discoverysummarizer:go_default_library", - "//vendor:github.com/golang/glog", + "//cmd/kubernetes-discovery/pkg/apis/apiregistration/install:go_default_library", + "//cmd/kubernetes-discovery/pkg/apis/apiregistration/validation:go_default_library", + "//cmd/kubernetes-discovery/pkg/client/clientset_generated/internalclientset:go_default_library", + "//cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion:go_default_library", + "//cmd/kubernetes-discovery/pkg/client/listers/apiregistration/v1alpha1:go_default_library", + "//cmd/kubernetes-discovery/pkg/cmd/server:go_default_library", + "//pkg/kubectl/cmd/util:go_default_library", + "//pkg/util/logs:go_default_library", ], ) diff --git a/cmd/kubernetes-discovery/hack/update-codegen.sh b/cmd/kubernetes-discovery/hack/update-codegen.sh new file mode 100755 index 00000000000..8558646735c --- /dev/null +++ b/cmd/kubernetes-discovery/hack/update-codegen.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# Copyright 2016 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../../.. +APIFEDERATOR_ROOT=$(dirname "${BASH_SOURCE}")/.. +source "${KUBE_ROOT}/hack/lib/init.sh" + +# Register function to be called on EXIT to remove generated binary. +function cleanup { + rm -f "${CLIENTGEN:-}" + rm -f "${listergen:-}" +} +trap cleanup EXIT + +echo "Building client-gen" +CLIENTGEN="${PWD}/client-gen-binary" +go build -o "${CLIENTGEN}" ./cmd/libs/go2idl/client-gen + +PREFIX=k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis +INPUT_BASE="--input-base ${PREFIX}" +INPUT_APIS=( +apiregistration/ +apiregistration/v1alpha1 +) +INPUT="--input ${INPUT_APIS[@]}" +CLIENTSET_PATH="--clientset-path k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated" + +${CLIENTGEN} ${INPUT_BASE} ${INPUT} ${CLIENTSET_PATH} +${CLIENTGEN} --clientset-name="release_1_5" ${INPUT_BASE} --input apiregistration/v1alpha1 ${CLIENTSET_PATH} + + +echo "Building lister-gen" +listergen="${PWD}/lister-gen" +go build -o "${listergen}" ./cmd/libs/go2idl/lister-gen + +LISTER_INPUT="--input-dirs k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration --input-dirs k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1" +LISTER_PATH="--output-package k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers" +${listergen} ${LISTER_INPUT} ${LISTER_PATH} + + +# TODO generated code has the wrong internal package name +# echo "Building informer-gen" +# informergen="${PWD}/informer-gen" +# go build -o "${informergen}" ./cmd/libs/go2idl/informer-gen + +# ${informergen} \ +# --input-dirs k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration --input-dirs k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1 \ +# --versioned-clientset-package k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/release_1_5 \ +# --internal-clientset-package k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/internalclientset \ +# --listers-package k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers \ +# --output-package k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/informers +# "$@" diff --git a/cmd/kubernetes-discovery/hack/verify-codegen.sh b/cmd/kubernetes-discovery/hack/verify-codegen.sh new file mode 100755 index 00000000000..22a074a3355 --- /dev/null +++ b/cmd/kubernetes-discovery/hack/verify-codegen.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Copyright 2016 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../../.. +APIFEDERATOR_ROOT=$(dirname "${BASH_SOURCE}")/.. +source "${KUBE_ROOT}/hack/lib/init.sh" + +DIFFROOT="${APIFEDERATOR_ROOT}/pkg" +TMP_DIFFROOT="${APIFEDERATOR_ROOT}/_tmp/pkg" +_tmp="${APIFEDERATOR_ROOT}/_tmp" + +cleanup() { + rm -rf "${_tmp}" +} +trap "cleanup" EXIT SIGINT + +cleanup + +mkdir -p "${_tmp}" +cp -a -T "${DIFFROOT}" "${TMP_DIFFROOT}" + +"${APIFEDERATOR_ROOT}/hack/update-codegen.sh" +echo "diffing ${DIFFROOT} against freshly generated codegen" +ret=0 +diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$? +cp -a -T "${TMP_DIFFROOT}" "${DIFFROOT}" +if [[ $ret -eq 0 ]] +then + echo "${DIFFROOT} up to date." +else + echo "${DIFFROOT} is out of date. Please run hack/update-codegen.sh" + exit 1 +fi diff --git a/cmd/kubernetes-discovery/main.go b/cmd/kubernetes-discovery/main.go index 2bde47a0d2f..6c39db6fb1e 100644 --- a/cmd/kubernetes-discovery/main.go +++ b/cmd/kubernetes-discovery/main.go @@ -23,6 +23,13 @@ import ( "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/cmd/server" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/logs" + + // force compilation of packages we'll later rely upon + _ "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration/install" + _ "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration/validation" + _ "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/internalclientset" + _ "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion" + _ "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers/apiregistration/v1alpha1" ) func main() { diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/doc.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/doc.go new file mode 100644 index 00000000000..b6339838e5e --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package,register + +// Package api is the internal version of the API. +// +groupName=apiregistration.k8s.io +package apiregistration diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/helpers.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/helpers.go new file mode 100644 index 00000000000..64527bdf674 --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/helpers.go @@ -0,0 +1,59 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiregistration + +import ( + "sort" + "strings" +) + +func SortedByGroup(servers []*APIService) [][]*APIService { + serversByPriority := ByPriority(servers) + sort.Sort(serversByPriority) + + ret := [][]*APIService{} + for _, curr := range serversByPriority { + // check to see if we already have an entry for this group + existingIndex := -1 + for j, groupInReturn := range ret { + if groupInReturn[0].Spec.Group == curr.Spec.Group { + existingIndex = j + break + } + } + + if existingIndex >= 0 { + ret[existingIndex] = append(ret[existingIndex], curr) + continue + } + + ret = append(ret, []*APIService{curr}) + } + + return ret +} + +type ByPriority []*APIService + +func (s ByPriority) Len() int { return len(s) } +func (s ByPriority) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s ByPriority) Less(i, j int) bool { + if s[i].Spec.Priority == s[j].Spec.Priority { + return strings.Compare(s[i].Name, s[j].Name) < 0 + } + return s[i].Spec.Priority < s[j].Spec.Priority +} diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/install/install.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/install/install.go new file mode 100644 index 00000000000..27c80a42bee --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/install/install.go @@ -0,0 +1,41 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package install + +import ( + "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration" + "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1" + "k8s.io/kubernetes/pkg/apimachinery/announced" + "k8s.io/kubernetes/pkg/util/sets" +) + +func init() { + if err := announced.NewGroupMetaFactory( + &announced.GroupMetaFactoryArgs{ + GroupName: apiregistration.GroupName, + RootScopedKinds: sets.NewString("APIService"), + VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version}, + ImportPrefix: "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration", + AddInternalObjectsToScheme: apiregistration.AddToScheme, + }, + announced.VersionToSchemeFunc{ + v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme, + }, + ).Announce().RegisterAndEnable(); err != nil { + panic(err) + } +} diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/register.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/register.go new file mode 100644 index 00000000000..a2d080973ef --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/register.go @@ -0,0 +1,59 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiregistration + +import ( + kapi "k8s.io/kubernetes/pkg/api" + metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/watch/versioned" +) + +const GroupName = "apiregistration.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns back a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &APIService{}, + &APIServiceList{}, + + &kapi.ListOptions{}, + &kapi.DeleteOptions{}, + &metav1.GetOptions{}, + ) + versioned.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/types.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/types.go new file mode 100644 index 00000000000..9162f2cafbf --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/types.go @@ -0,0 +1,84 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiregistration + +import ( + kapi "k8s.io/kubernetes/pkg/api" + metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" +) + +// APIServiceList is a list of APIService objects. +type APIServiceList struct { + metav1.TypeMeta + metav1.ListMeta + + Items []APIService +} + +// ServiceReference holds a reference to Service.legacy.k8s.io +type ServiceReference struct { + // Namespace is the namespace of the service + Namespace string + // Name is the name of the service + Name string +} + +// APIServiceSpec contains information for locating and communicating with a server. +// Only https is supported, though you are able to disable certificate verification. +type APIServiceSpec struct { + // Service is a reference to the service for this API server. It must communicate + // on port 443 + Service ServiceReference + // Group is the API group name this server hosts + Group string + // Version is the API version this server hosts. For example, "v1" + Version string + + // InsecureSkipTLSVerify disables TLS certificate verification when communicating with this server. + // This is strongly discouraged. You should use the CABundle instead. + InsecureSkipTLSVerify bool + // CABundle is a PEM encoded CA bundle which will be used to validate an API server's serving certificate. + CABundle []byte + + // Priority controls the ordering of this API group in the overall discovery document that gets served. + // Client tools like `kubectl` use this ordering to derive preference, so this ordering mechanism is important. + // Values must be between 1 and 1000 + // The primary sort is based on priority, ordered lowest number to highest (10 before 20). + // The secondary sort is based on the alphabetical comparison of the name of the object. (v1.bar before v1.foo) + // We'd recommend something like: *.k8s.io (except extensions) at 100, extensions at 150 + // PaaSes (OpenShift, Deis) are recommended to be in the 200s + Priority int64 +} + +// APIServiceStatus contains derived information about an API server +type APIServiceStatus struct { +} + +// +genclient=true +// +nonNamespaced=true + +// APIService represents a server for a particular GroupVersion. +// Name must be "version.group". +type APIService struct { + metav1.TypeMeta + kapi.ObjectMeta + + // Spec contains information for locating and communicating with a server + Spec APIServiceSpec + // Status contains derived information about an API server + Status APIServiceStatus +} diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/doc.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/doc.go new file mode 100644 index 00000000000..7381304c2ef --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration + +// Package v1alpha1 is the v1alpha1 version of the API. +// +groupName=apiregistration.k8s.io +package v1alpha1 diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/register.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/register.go new file mode 100644 index 00000000000..984e5e44c10 --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/register.go @@ -0,0 +1,49 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/kubernetes/pkg/api/v1" + metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/watch/versioned" +) + +const GroupName = "apiregistration.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &APIService{}, + &APIServiceList{}, + + &v1.ListOptions{}, + &v1.DeleteOptions{}, + &metav1.GetOptions{}, + ) + versioned.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/types.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/types.go new file mode 100644 index 00000000000..48d519d5d93 --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1/types.go @@ -0,0 +1,84 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + kapi "k8s.io/kubernetes/pkg/api/v1" + metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" +) + +// APIServiceList is a list of APIService objects. +type APIServiceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + Items []APIService `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// ServiceReference holds a reference to Service.legacy.k8s.io +type ServiceReference struct { + // Namespace is the namespace of the service + Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"` + // Name is the name of the service + Name string `json:"name,omitempty" protobuf:"bytes,2,opt,name=name"` +} + +// APIServiceSpec contains information for locating and communicating with a server. +// Only https is supported, though you are able to disable certificate verification. +type APIServiceSpec struct { + // Service is a reference to the service for this API server. It must communicate + // on port 443 + Service ServiceReference `json:"service" protobuf:"bytes,1,opt,name=service"` + // Group is the API group name this server hosts + Group string `json:"group,omitempty" protobuf:"bytes,2,opt,name=group"` + // Version is the API version this server hosts. For example, "v1" + Version string `json:"version,omitempty" protobuf:"bytes,3,opt,name=version"` + + // InsecureSkipTLSVerify disables TLS certificate verification when communicating with this server. + // This is strongly discouraged. You should use the CABundle instead. + InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty" protobuf:"varint,4,opt,name=insecureSkipTLSVerify"` + // CABundle is a PEM encoded CA bundle which will be used to validate an API server's serving certificate. + CABundle []byte `json:"caBundle" protobuf:"bytes,5,opt,name=caBundle"` + + // Priority controls the ordering of this API group in the overall discovery document that gets served. + // Client tools like `kubectl` use this ordering to derive preference, so this ordering mechanism is important. + // Values must be between 1 and 1000 + // The primary sort is based on priority, ordered lowest number to highest (10 before 20). + // The secondary sort is based on the alphabetical comparison of the name of the object. (v1.bar before v1.foo) + // We'd recommend something like: *.k8s.io (except extensions) at 100, extensions at 150 + // PaaSes (OpenShift, Deis) are recommended to be in the 200s + Priority int64 `json:"priority" protobuf:"varint,6,opt,name=priority"` +} + +// APIServiceStatus contains derived information about an API server +type APIServiceStatus struct { +} + +// +genclient=true +// +nonNamespaced=true + +// APIService represents a server for a particular GroupVersion. +// Name must be "version.group". +type APIService struct { + metav1.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec contains information for locating and communicating with a server + Spec APIServiceSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + // Status contains derived information about an API server + Status APIServiceStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} diff --git a/cmd/kubernetes-discovery/pkg/apis/apiregistration/validation/validation.go b/cmd/kubernetes-discovery/pkg/apis/apiregistration/validation/validation.go new file mode 100644 index 00000000000..60e441959bd --- /dev/null +++ b/cmd/kubernetes-discovery/pkg/apis/apiregistration/validation/validation.go @@ -0,0 +1,85 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validation + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/kubernetes/pkg/api/validation/path" + utilvalidation "k8s.io/kubernetes/pkg/util/validation" + "k8s.io/kubernetes/pkg/util/validation/field" + + discoveryapi "k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration" +) + +func ValidateAPIService(apiServer *discoveryapi.APIService) field.ErrorList { + requiredName := apiServer.Spec.Version + "." + apiServer.Spec.Group + + allErrs := validation.ValidateObjectMeta(&apiServer.ObjectMeta, false, + func(name string, prefix bool) []string { + if minimalFailures := path.IsValidPathSegmentName(name); len(minimalFailures) > 0 { + return minimalFailures + } + // the name *must* be version.group + if name != requiredName { + return []string{fmt.Sprintf("must be `spec.version+\".\"+spec.group`: %q", requiredName)} + } + + return []string{} + }, + field.NewPath("metadata")) + + // in this case we allow empty group + if len(apiServer.Spec.Group) == 0 && apiServer.Spec.Version != "v1" { + allErrs = append(allErrs, field.Required(field.NewPath("spec", "group"), "only v1 may have an empty group and it better be legacy kube")) + } + if len(apiServer.Spec.Group) > 0 { + for _, errString := range utilvalidation.IsDNS1123Subdomain(apiServer.Spec.Group) { + allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "group"), apiServer.Spec.Group, errString)) + } + } + + for _, errString := range utilvalidation.IsDNS1035Label(apiServer.Spec.Version) { + allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "version"), apiServer.Spec.Version, errString)) + } + + if apiServer.Spec.Priority <= 0 || apiServer.Spec.Priority > 1000 { + allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "priority"), apiServer.Spec.Priority, "priority must be positive and less than 1000")) + + } + + if len(apiServer.Spec.Service.Namespace) == 0 { + allErrs = append(allErrs, field.Required(field.NewPath("spec", "service", "namespace"), "")) + } + if len(apiServer.Spec.Service.Name) == 0 { + allErrs = append(allErrs, field.Required(field.NewPath("spec", "service", "name"), "")) + } + + if apiServer.Spec.InsecureSkipTLSVerify && len(apiServer.Spec.CABundle) > 0 { + allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "insecureSkipTLSVerify"), apiServer.Spec.InsecureSkipTLSVerify, "may not be true if caBundle is present")) + } + + return allErrs +} + +func ValidateAPIServiceUpdate(newAPIService *discoveryapi.APIService, oldAPIService *discoveryapi.APIService) field.ErrorList { + allErrs := validation.ValidateObjectMetaUpdate(&newAPIService.ObjectMeta, &oldAPIService.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateAPIService(newAPIService)...) + + return allErrs +} diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 6c5126a3a73..d5571ced70c 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -101,3 +101,6 @@ ${informergen} \ "$@" # You may add additional calls of code generators like set-gen above. + +# call generation on sub-project for now +cmd/kubernetes-discovery/hack/update-codegen.sh diff --git a/hack/verify-codecgen.sh b/hack/verify-codecgen.sh index aedbdd586fe..b9c031d875d 100755 --- a/hack/verify-codecgen.sh +++ b/hack/verify-codecgen.sh @@ -62,4 +62,6 @@ for generated_file in ${generated_files[@]}; do done -exit $ret +if [ "${ret}" -ne "0" ]; then + exit $ret +fi diff --git a/hack/verify-codegen.sh b/hack/verify-codegen.sh index d1e8be09e15..83013249812 100755 --- a/hack/verify-codegen.sh +++ b/hack/verify-codegen.sh @@ -23,4 +23,8 @@ source "${KUBE_ROOT}/hack/lib/init.sh" kube::golang::setup_env +# call verify on sub-project for now +cmd/kubernetes-discovery/hack/verify-codegen.sh + "${KUBE_ROOT}/hack/update-codegen.sh" --verify-only +