diff --git a/hack/.packages b/hack/.packages index 78ef46b2b7..9a8692b0b4 100644 --- a/hack/.packages +++ b/hack/.packages @@ -34,6 +34,7 @@ k8s.io/kops/pkg/apis/nodeup k8s.io/kops/pkg/apiserver k8s.io/kops/pkg/apiserver/cmd/server k8s.io/kops/pkg/apiserver/registry/cluster +k8s.io/kops/pkg/apiserver/registry/instancegroup k8s.io/kops/pkg/assets k8s.io/kops/pkg/client/clientset_generated/clientset k8s.io/kops/pkg/client/clientset_generated/clientset/fake diff --git a/pkg/apis/kops/install/install.go b/pkg/apis/kops/install/install.go index ab4dd83bf2..0ef154aea5 100644 --- a/pkg/apis/kops/install/install.go +++ b/pkg/apis/kops/install/install.go @@ -43,7 +43,8 @@ func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *r v1alpha2.SchemeGroupVersion.Version, v1alpha1.SchemeGroupVersion.Version, }, - RootScopedKinds: sets.NewString("Cluster"), + // RootScopedKinds are resources that are not namespaced. + RootScopedKinds: sets.NewString(), ImportPrefix: "k8s.io/kops/pkg/apis/kops", AddInternalObjectsToScheme: kops.AddToScheme, }, diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 997bfe0746..1ab1a152b6 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -17,6 +17,7 @@ limitations under the License. package apiserver import ( + "k8s.io/apimachinery/pkg/version" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/server" @@ -26,8 +27,7 @@ import ( _ "k8s.io/kops/pkg/apis/kops/install" "k8s.io/kops/pkg/apis/kops/v1alpha2" registrycluster "k8s.io/kops/pkg/apiserver/registry/cluster" - //registryinstancegroup "k8s.io/kops/pkg/apiserver/registry/instancegroup" - "k8s.io/kubernetes/pkg/version" + registryinstancegroup "k8s.io/kops/pkg/apiserver/registry/instancegroup" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -69,8 +69,10 @@ type completedConfig struct { func (c *Config) Complete() completedConfig { c.GenericConfig.Complete() - version := version.Get() - c.GenericConfig.Version = &version + c.GenericConfig.Version = &version.Info{ + Major: "1", + Minor: "0", + } return completedConfig{c} } @@ -96,7 +98,8 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) { apiGroupInfo.GroupMeta.GroupVersion = v1alpha2.SchemeGroupVersion v1alpha2storage := map[string]rest.Storage{} v1alpha2storage["clusters"] = registrycluster.NewREST(c.RESTOptionsGetter) - //v1alpha2storage["instancegroups"] = registryinstancegroup.NewREST(c.RESTOptionsGetter) + //v1alpha2storage["clusters/full"] = registrycluster.NewREST(c.RESTOptionsGetter) + v1alpha2storage["instancegroups"] = registryinstancegroup.NewREST(c.RESTOptionsGetter) apiGroupInfo.VersionedResourcesStorageMap["v1alpha2"] = v1alpha2storage if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil { diff --git a/pkg/apiserver/cmd/server/start.go b/pkg/apiserver/cmd/server/start.go index ecec0844f3..5943bdfbc8 100644 --- a/pkg/apiserver/cmd/server/start.go +++ b/pkg/apiserver/cmd/server/start.go @@ -105,7 +105,7 @@ func (o KopsServerOptions) RunKopsServer() error { serverConfig := genericapiserver.NewConfig(kops.Codecs) // 1.6: serverConfig := genericapiserver.NewConfig().WithSerializer(kops.Codecs) //if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil { - // return nil, err + // return nil, err //} serverConfig.CorsAllowedOriginList = []string{".*"} @@ -139,7 +139,6 @@ func (o KopsServerOptions) RunKopsServer() error { return err } return server.GenericAPIServer.PrepareRun().Run(wait.NeverStop) - } type restOptionsFactory struct { diff --git a/pkg/apiserver/registry/cluster/strategy.go b/pkg/apiserver/registry/cluster/strategy.go index 53f680f12e..0b1994f94f 100644 --- a/pkg/apiserver/registry/cluster/strategy.go +++ b/pkg/apiserver/registry/cluster/strategy.go @@ -39,7 +39,7 @@ type clusterStrategy struct { var Strategy = clusterStrategy{kops.Scheme, names.SimpleNameGenerator} func (clusterStrategy) NamespaceScoped() bool { - return false + return true } func (clusterStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { diff --git a/pkg/apiserver/registry/instancegroup/etcd.go b/pkg/apiserver/registry/instancegroup/etcd.go new file mode 100644 index 0000000000..c5f721c1b1 --- /dev/null +++ b/pkg/apiserver/registry/instancegroup/etcd.go @@ -0,0 +1,57 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package instancegroup + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic" + genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + + "k8s.io/kops/pkg/apis/kops" +) + +// rest implements a RESTStorage for kops InstanceGroups against etcd +type REST struct { + *genericregistry.Store +} + +// NewREST returns a RESTStorage object that will work against kops InstanceGroups. +func NewREST(optsGetter generic.RESTOptionsGetter) *REST { + store := &genericregistry.Store{ + Copier: kops.Scheme, + NewFunc: func() runtime.Object { + return &kops.InstanceGroup{} + }, + NewListFunc: func() runtime.Object { + return &kops.InstanceGroupList{} + }, + ObjectNameFunc: func(obj runtime.Object) (string, error) { + return obj.(*kops.InstanceGroup).Name, nil + }, + PredicateFunc: MatchInstanceGroup, + QualifiedResource: kops.Resource("instancegroups"), + + CreateStrategy: Strategy, + UpdateStrategy: Strategy, + DeleteStrategy: Strategy, + } + options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs} + if err := store.CompleteWithOptions(options); err != nil { + panic(err) // TODO: Propagate error up + } + return &REST{store} +} diff --git a/pkg/apiserver/registry/instancegroup/strategy.go b/pkg/apiserver/registry/instancegroup/strategy.go new file mode 100644 index 0000000000..f86314b74c --- /dev/null +++ b/pkg/apiserver/registry/instancegroup/strategy.go @@ -0,0 +1,93 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package instancegroup + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/registry/generic" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/names" + + "k8s.io/kops/pkg/apis/kops" +) + +type instanceGroupStrategy struct { + runtime.ObjectTyper + names.NameGenerator +} + +var Strategy = instanceGroupStrategy{kops.Scheme, names.SimpleNameGenerator} + +func (instanceGroupStrategy) NamespaceScoped() bool { + return true +} + +func (instanceGroupStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { +} + +func (instanceGroupStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { +} + +func (instanceGroupStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList { + return field.ErrorList{} + // return validation.ValidateServiceInjection(obj.(*serviceinjection.ServiceInjection)) +} + +func (instanceGroupStrategy) AllowCreateOnUpdate() bool { + return false +} + +func (instanceGroupStrategy) AllowUnconditionalUpdate() bool { + return false +} + +func (instanceGroupStrategy) Canonicalize(obj runtime.Object) { +} + +func (instanceGroupStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList { + return field.ErrorList{} + // return validation.ValidateServiceInjectionUpdate(obj.(*serviceinjection.ServiceInjection), old.(*serviceinjection.ServiceInjection)) +} + +func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) { + instanceGroup, ok := obj.(*kops.InstanceGroup) + if !ok { + return nil, nil, false, fmt.Errorf("given object is not an InstanceGroup.") + } + return labels.Set(instanceGroup.Labels), InstanceGroupToSelectableFields(instanceGroup), instanceGroup.Initializers != nil, nil +} + +// MatchInstanceGroup is the filter used by the generic etcd backend to watch events +// from etcd to clients of the apiserver only interested in specific labels/fields. +func MatchInstanceGroup(label labels.Selector, field fields.Selector) storage.SelectionPredicate { + return storage.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: GetAttrs, + } +} + +// InstanceGroupToSelectableFields returns a field set that represents the object. +func InstanceGroupToSelectableFields(obj *kops.InstanceGroup) fields.Set { + return generic.ObjectMetaFieldsSet(&obj.ObjectMeta, true) +} diff --git a/upup/pkg/fi/cloudup/awsup/aws_cloud.go b/upup/pkg/fi/cloudup/awsup/aws_cloud.go index 46819df543..96a222efcd 100644 --- a/upup/pkg/fi/cloudup/awsup/aws_cloud.go +++ b/upup/pkg/fi/cloudup/awsup/aws_cloud.go @@ -35,7 +35,7 @@ import ( "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/upup/pkg/fi" "k8s.io/kubernetes/federation/pkg/dnsprovider" - k8sroute53 "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53" + dnsproviderroute53 "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53" "strings" "time" ) @@ -683,7 +683,7 @@ func ValidateZones(zones []string, cloud AWSCloud) error { } func (c *awsCloudImplementation) DNS() (dnsprovider.Interface, error) { - provider, err := dnsprovider.GetDnsProvider(k8sroute53.ProviderName, nil) + provider, err := dnsprovider.GetDnsProvider(dnsproviderroute53.ProviderName, nil) if err != nil { return nil, fmt.Errorf("Error building (k8s) DNS provider: %v", err) }