Merge pull request #6245 from tmrts/master

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2015-12-16 10:24:05 -08:00
commit e80f05d155
23 changed files with 5126 additions and 2413 deletions

View File

@ -945,6 +945,44 @@ func deepCopy_extensions_ClusterAutoscalerSpec(in ClusterAutoscalerSpec, out *Cl
return nil
}
func deepCopy_extensions_ConfigMap(in ConfigMap, out *ConfigMap, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
}
if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Data != nil {
out.Data = make(map[string]string)
for key, val := range in.Data {
out.Data[key] = val
}
} else {
out.Data = nil
}
return nil
}
func deepCopy_extensions_ConfigMapList(in ConfigMapList, out *ConfigMapList, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
}
if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil {
return err
}
if in.Items != nil {
out.Items = make([]ConfigMap, len(in.Items))
for i := range in.Items {
if err := deepCopy_extensions_ConfigMap(in.Items[i], &out.Items[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func deepCopy_extensions_DaemonSet(in DaemonSet, out *DaemonSet, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
@ -1633,6 +1671,8 @@ func init() {
deepCopy_extensions_ClusterAutoscaler,
deepCopy_extensions_ClusterAutoscalerList,
deepCopy_extensions_ClusterAutoscalerSpec,
deepCopy_extensions_ConfigMap,
deepCopy_extensions_ConfigMapList,
deepCopy_extensions_DaemonSet,
deepCopy_extensions_DaemonSetList,
deepCopy_extensions_DaemonSetSpec,

View File

@ -65,6 +65,8 @@ func addKnownTypes() {
&Ingress{},
&IngressList{},
&api.ListOptions{},
&ConfigMap{},
&ConfigMapList{},
)
}
@ -86,3 +88,5 @@ func (obj *ThirdPartyResourceData) GetObjectKind() unversioned.ObjectKind {
func (obj *ThirdPartyResourceDataList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *Ingress) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *IngressList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ConfigMap) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ConfigMapList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

File diff suppressed because it is too large Load Diff

View File

@ -691,3 +691,26 @@ const (
LabelSelectorOpExists LabelSelectorOperator = "Exists"
LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist"
)
// ConfigMap holds configuration data for components or applications to consume.
type ConfigMap struct {
unversioned.TypeMeta `json:",inline"`
// Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata.
api.ObjectMeta `json:"metadata,omitempty"`
// Data contains the configuration data.
// Each key must be a valid DNS_SUBDOMAIN with an optional leading dot.
Data map[string]string `json:"data,omitempty"`
}
// ConfigMapList is a resource containing a list of ConfigMap objects.
type ConfigMapList struct {
unversioned.TypeMeta `json:",inline"`
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
unversioned.ListMeta `json:"metadata,omitempty"`
// Items is the list of ConfigMaps.
Items []ConfigMap `json:"items,omitempty"`
}

View File

@ -2277,6 +2277,58 @@ func convert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec(i
return autoconvert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec(in, out, s)
}
func autoconvert_extensions_ConfigMap_To_v1beta1_ConfigMap(in *extensions.ConfigMap, out *ConfigMap, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*extensions.ConfigMap))(in)
}
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
return err
}
if in.Data != nil {
out.Data = make(map[string]string)
for key, val := range in.Data {
out.Data[key] = val
}
} else {
out.Data = nil
}
return nil
}
func convert_extensions_ConfigMap_To_v1beta1_ConfigMap(in *extensions.ConfigMap, out *ConfigMap, s conversion.Scope) error {
return autoconvert_extensions_ConfigMap_To_v1beta1_ConfigMap(in, out, s)
}
func autoconvert_extensions_ConfigMapList_To_v1beta1_ConfigMapList(in *extensions.ConfigMapList, out *ConfigMapList, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*extensions.ConfigMapList))(in)
}
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil {
return err
}
if in.Items != nil {
out.Items = make([]ConfigMap, len(in.Items))
for i := range in.Items {
if err := convert_extensions_ConfigMap_To_v1beta1_ConfigMap(&in.Items[i], &out.Items[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func convert_extensions_ConfigMapList_To_v1beta1_ConfigMapList(in *extensions.ConfigMapList, out *ConfigMapList, s conversion.Scope) error {
return autoconvert_extensions_ConfigMapList_To_v1beta1_ConfigMapList(in, out, s)
}
func autoconvert_extensions_DaemonSet_To_v1beta1_DaemonSet(in *extensions.DaemonSet, out *DaemonSet, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*extensions.DaemonSet))(in)
@ -3264,6 +3316,58 @@ func convert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec(i
return autoconvert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec(in, out, s)
}
func autoconvert_v1beta1_ConfigMap_To_extensions_ConfigMap(in *ConfigMap, out *extensions.ConfigMap, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*ConfigMap))(in)
}
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
return err
}
if in.Data != nil {
out.Data = make(map[string]string)
for key, val := range in.Data {
out.Data[key] = val
}
} else {
out.Data = nil
}
return nil
}
func convert_v1beta1_ConfigMap_To_extensions_ConfigMap(in *ConfigMap, out *extensions.ConfigMap, s conversion.Scope) error {
return autoconvert_v1beta1_ConfigMap_To_extensions_ConfigMap(in, out, s)
}
func autoconvert_v1beta1_ConfigMapList_To_extensions_ConfigMapList(in *ConfigMapList, out *extensions.ConfigMapList, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*ConfigMapList))(in)
}
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil {
return err
}
if in.Items != nil {
out.Items = make([]extensions.ConfigMap, len(in.Items))
for i := range in.Items {
if err := convert_v1beta1_ConfigMap_To_extensions_ConfigMap(&in.Items[i], &out.Items[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func convert_v1beta1_ConfigMapList_To_extensions_ConfigMapList(in *ConfigMapList, out *extensions.ConfigMapList, s conversion.Scope) error {
return autoconvert_v1beta1_ConfigMapList_To_extensions_ConfigMapList(in, out, s)
}
func autoconvert_v1beta1_DaemonSet_To_extensions_DaemonSet(in *DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*DaemonSet))(in)
@ -4209,6 +4313,8 @@ func init() {
autoconvert_extensions_ClusterAutoscalerList_To_v1beta1_ClusterAutoscalerList,
autoconvert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec,
autoconvert_extensions_ClusterAutoscaler_To_v1beta1_ClusterAutoscaler,
autoconvert_extensions_ConfigMapList_To_v1beta1_ConfigMapList,
autoconvert_extensions_ConfigMap_To_v1beta1_ConfigMap,
autoconvert_extensions_DaemonSetList_To_v1beta1_DaemonSetList,
autoconvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec,
autoconvert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus,
@ -4295,6 +4401,8 @@ func init() {
autoconvert_v1beta1_ClusterAutoscalerList_To_extensions_ClusterAutoscalerList,
autoconvert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec,
autoconvert_v1beta1_ClusterAutoscaler_To_extensions_ClusterAutoscaler,
autoconvert_v1beta1_ConfigMapList_To_extensions_ConfigMapList,
autoconvert_v1beta1_ConfigMap_To_extensions_ConfigMap,
autoconvert_v1beta1_DaemonSetList_To_extensions_DaemonSetList,
autoconvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec,
autoconvert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus,

View File

@ -947,6 +947,44 @@ func deepCopy_v1beta1_ClusterAutoscalerSpec(in ClusterAutoscalerSpec, out *Clust
return nil
}
func deepCopy_v1beta1_ConfigMap(in ConfigMap, out *ConfigMap, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
}
if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Data != nil {
out.Data = make(map[string]string)
for key, val := range in.Data {
out.Data[key] = val
}
} else {
out.Data = nil
}
return nil
}
func deepCopy_v1beta1_ConfigMapList(in ConfigMapList, out *ConfigMapList, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
}
if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil {
return err
}
if in.Items != nil {
out.Items = make([]ConfigMap, len(in.Items))
for i := range in.Items {
if err := deepCopy_v1beta1_ConfigMap(in.Items[i], &out.Items[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func deepCopy_v1beta1_DaemonSet(in DaemonSet, out *DaemonSet, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
@ -1672,6 +1710,8 @@ func init() {
deepCopy_v1beta1_ClusterAutoscaler,
deepCopy_v1beta1_ClusterAutoscalerList,
deepCopy_v1beta1_ClusterAutoscalerSpec,
deepCopy_v1beta1_ConfigMap,
deepCopy_v1beta1_ConfigMapList,
deepCopy_v1beta1_DaemonSet,
deepCopy_v1beta1_DaemonSetList,
deepCopy_v1beta1_DaemonSetSpec,

View File

@ -118,5 +118,10 @@ func addDefaultingFuncs() {
obj.Spec.CPUUtilization = &CPUTargetUtilization{TargetPercentage: 80}
}
},
func(obj *ConfigMap) {
if obj.Data == nil {
obj.Data = make(map[string]string)
}
},
)
}

View File

@ -58,6 +58,8 @@ func addKnownTypes() {
&Ingress{},
&IngressList{},
&ListOptions{},
&ConfigMap{},
&ConfigMapList{},
)
}
@ -80,3 +82,5 @@ func (obj *ThirdPartyResourceDataList) GetObjectKind() unversioned.ObjectKind {
func (obj *Ingress) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *IngressList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ListOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ConfigMap) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ConfigMapList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

File diff suppressed because it is too large Load Diff

View File

@ -719,3 +719,26 @@ const (
LabelSelectorOpExists LabelSelectorOperator = "Exists"
LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist"
)
// ConfigMap holds configuration data for pods to consume.
type ConfigMap 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"`
// Data contains the configuration data.
// Each key must be a valid DNS_SUBDOMAIN with an optional leading dot.
Data map[string]string `json:"data,omitempty"`
}
// ConfigMapList is a resource containing a list of ConfigMap objects.
type ConfigMapList struct {
unversioned.TypeMeta `json:",inline"`
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
unversioned.ListMeta `json:"metadata,omitempty"`
// Items is the list of ConfigMaps.
Items []ConfigMap `json:"items,omitempty"`
}

View File

@ -74,6 +74,26 @@ func (ClusterAutoscalerSpec) SwaggerDoc() map[string]string {
return map_ClusterAutoscalerSpec
}
var map_ConfigMap = map[string]string{
"": "ConfigMap holds configuration data for pods to consume.",
"metadata": "Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata.",
"data": "Data contains the configuration data. Each key must be a valid DNS_SUBDOMAIN with an optional leading dot.",
}
func (ConfigMap) SwaggerDoc() map[string]string {
return map_ConfigMap
}
var map_ConfigMapList = map[string]string{
"": "ConfigMapList is a resource containing a list of ConfigMap objects.",
"metadata": "More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",
"items": "Items is the list of ConfigMaps.",
}
func (ConfigMapList) SwaggerDoc() map[string]string {
return map_ConfigMapList
}
var map_DaemonSet = map[string]string{
"": "DaemonSet represents the configuration of a daemon set.",
"metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",

View File

@ -17,6 +17,7 @@ limitations under the License.
package validation
import (
"fmt"
"net"
"regexp"
"strconv"
@ -593,3 +594,33 @@ func ValidateScale(scale *extensions.Scale) field.ErrorList {
return allErrs
}
// ValidateConfigMapName can be used to check whether the given ConfigMap name is valid.
// Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed.
func ValidateConfigMapName(name string, prefix bool) (bool, string) {
return apivalidation.NameIsDNSSubdomain(name, prefix)
}
// ValidateConfigMap tests whether required fields in the ConfigMap are set.
func ValidateConfigMap(cfg *extensions.ConfigMap) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&cfg.ObjectMeta, true, ValidateConfigMapName, field.NewPath("metadata"))...)
for key := range cfg.Data {
if !apivalidation.IsSecretKey(key) {
allErrs = append(allErrs, field.Invalid(field.NewPath("data").Key(key), key, fmt.Sprintf("must have at most %d characters and match regex %s", validation.DNS1123SubdomainMaxLength, apivalidation.SecretKeyFmt)))
}
}
return allErrs
}
// ValidateConfigMapUpdate tests if required fields in the ConfigMap are set.
func ValidateConfigMapUpdate(newCfg, oldCfg *extensions.ConfigMap) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&newCfg.ObjectMeta, &oldCfg.ObjectMeta, field.NewPath("metadata"))...)
allErrs = append(allErrs, ValidateConfigMap(newCfg)...)
return allErrs
}

View File

@ -1300,3 +1300,105 @@ func newInt(val int) *int {
*p = val
return p
}
func TestValidateConfigMap(t *testing.T) {
newConfigMap := func(name, namespace string, data map[string]string) extensions.ConfigMap {
return extensions.ConfigMap{
ObjectMeta: api.ObjectMeta{
Name: name,
Namespace: namespace,
},
Data: data,
}
}
var (
validConfigMap = newConfigMap("validname", "validns", map[string]string{"key": "value"})
maxKeyLength = newConfigMap("validname", "validns", map[string]string{strings.Repeat("a", 253): "value"})
emptyName = newConfigMap("", "validns", nil)
invalidName = newConfigMap("NoUppercaseOrSpecialCharsLike=Equals", "validns", nil)
emptyNs = newConfigMap("validname", "", nil)
invalidNs = newConfigMap("validname", "NoUppercaseOrSpecialCharsLike=Equals", nil)
invalidKey = newConfigMap("validname", "validns", map[string]string{"a..b": "value"})
leadingDotKey = newConfigMap("validname", "validns", map[string]string{".ab": "value"})
dotKey = newConfigMap("validname", "validns", map[string]string{".": "value"})
doubleDotKey = newConfigMap("validname", "validns", map[string]string{"..": "value"})
overMaxKeyLength = newConfigMap("validname", "validns", map[string]string{strings.Repeat("a", 254): "value"})
)
tests := map[string]struct {
cfg extensions.ConfigMap
isValid bool
}{
"valid": {validConfigMap, true},
"max key length": {maxKeyLength, true},
"leading dot key": {leadingDotKey, true},
"empty name": {emptyName, false},
"invalid name": {invalidName, false},
"invalid key": {invalidKey, false},
"empty namespace": {emptyNs, false},
"invalid namespace": {invalidNs, false},
"dot key": {dotKey, false},
"double dot key": {doubleDotKey, false},
"over max key length": {overMaxKeyLength, false},
}
for name, tc := range tests {
errs := ValidateConfigMap(&tc.cfg)
if tc.isValid && len(errs) > 0 {
t.Errorf("%v: unexpected error: %v", name, errs)
}
if !tc.isValid && len(errs) == 0 {
t.Errorf("%v: unexpected non-error", name)
}
}
}
func TestValidateConfigMapUpdate(t *testing.T) {
newConfigMap := func(version, name, namespace string, data map[string]string) extensions.ConfigMap {
return extensions.ConfigMap{
ObjectMeta: api.ObjectMeta{
Name: name,
Namespace: namespace,
ResourceVersion: version,
},
Data: data,
}
}
var (
validConfigMap = newConfigMap("1", "validname", "validns", map[string]string{"key": "value"})
noVersion = newConfigMap("", "validname", "validns", map[string]string{"key": "value"})
)
cases := []struct {
name string
newCfg extensions.ConfigMap
oldCfg extensions.ConfigMap
isValid bool
}{
{
name: "valid",
newCfg: validConfigMap,
oldCfg: validConfigMap,
isValid: true,
},
{
name: "invalid",
newCfg: noVersion,
oldCfg: validConfigMap,
isValid: false,
},
}
for _, tc := range cases {
errs := ValidateConfigMapUpdate(&tc.newCfg, &tc.oldCfg)
if tc.isValid && len(errs) > 0 {
t.Errorf("%v: unexpected error: %v", tc.name, errs)
}
if !tc.isValid && len(errs) == 0 {
t.Errorf("%v: unexpected non-error", tc.name)
}
}
}

View File

@ -0,0 +1,123 @@
/*
Copyright 2015 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 unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/watch"
)
const (
ConfigMapResourceName string = "configmaps"
)
type ConfigMapsNamespacer interface {
ConfigMaps(namespace string) ConfigMapsInterface
}
type ConfigMapsInterface interface {
Get(string) (*extensions.ConfigMap, error)
List(opts api.ListOptions) (*extensions.ConfigMapList, error)
Create(*extensions.ConfigMap) (*extensions.ConfigMap, error)
Delete(string) error
Update(*extensions.ConfigMap) (*extensions.ConfigMap, error)
Watch(api.ListOptions) (watch.Interface, error)
}
type ConfigMaps struct {
client *ExtensionsClient
namespace string
}
// ConfigMaps should implement ConfigMapsInterface
var _ ConfigMapsInterface = &ConfigMaps{}
func newConfigMaps(c *ExtensionsClient, ns string) *ConfigMaps {
return &ConfigMaps{
client: c,
namespace: ns,
}
}
func (c *ConfigMaps) Get(name string) (*extensions.ConfigMap, error) {
result := &extensions.ConfigMap{}
err := c.client.Get().
Namespace(c.namespace).
Resource(ConfigMapResourceName).
Name(name).
Do().
Into(result)
return result, err
}
func (c *ConfigMaps) List(opts api.ListOptions) (*extensions.ConfigMapList, error) {
result := &extensions.ConfigMapList{}
err := c.client.Get().
Namespace(c.namespace).
Resource(ConfigMapResourceName).
VersionedParams(&opts, api.Scheme).
Do().
Into(result)
return result, err
}
func (c *ConfigMaps) Create(cfg *extensions.ConfigMap) (*extensions.ConfigMap, error) {
result := &extensions.ConfigMap{}
err := c.client.Post().
Namespace(c.namespace).
Resource(ConfigMapResourceName).
Body(cfg).
Do().
Into(result)
return result, err
}
func (c *ConfigMaps) Delete(name string) error {
return c.client.Delete().
Namespace(c.namespace).
Resource(ConfigMapResourceName).
Name(name).
Do().
Error()
}
func (c *ConfigMaps) Update(cfg *extensions.ConfigMap) (*extensions.ConfigMap, error) {
result := &extensions.ConfigMap{}
err := c.client.Put().
Namespace(c.namespace).
Resource(ConfigMapResourceName).
Name(cfg.Name).
Body(cfg).
Do().
Into(result)
return result, err
}
func (c *ConfigMaps) Watch(opts api.ListOptions) (watch.Interface, error) {
return c.client.Get().
Prefix("watch").
Namespace(c.namespace).
Resource(ConfigMapResourceName).
VersionedParams(&opts, api.Scheme).
Watch()
}

View File

@ -39,6 +39,7 @@ type ExtensionsInterface interface {
JobsNamespacer
IngressNamespacer
ThirdPartyResourceNamespacer
ConfigMapsNamespacer
}
// ExtensionsClient is used to interact with experimental Kubernetes features.
@ -101,6 +102,10 @@ func (c *ExtensionsClient) Ingress(namespace string) IngressInterface {
return newIngress(c, namespace)
}
func (c *ExtensionsClient) ConfigMaps(namespace string) ConfigMapsInterface {
return newConfigMaps(c, namespace)
}
func (c *ExtensionsClient) ThirdPartyResources(namespace string) ThirdPartyResourceInterface {
return newThirdPartyResources(c, namespace)
}

View File

@ -0,0 +1,79 @@
/*
Copyright 2015 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 testclient
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/watch"
)
const (
configMapResourceName string = "configMaps"
)
// FakeConfigMaps implements ConfigMapInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakeConfigMaps struct {
Fake *FakeExperimental
Namespace string
}
func (c *FakeConfigMaps) Get(name string) (*extensions.ConfigMap, error) {
obj, err := c.Fake.Invokes(NewGetAction(configMapResourceName, c.Namespace, name), &extensions.ConfigMap{})
if obj == nil {
return nil, err
}
return obj.(*extensions.ConfigMap), err
}
func (c *FakeConfigMaps) List(opts api.ListOptions) (*extensions.ConfigMapList, error) {
obj, err := c.Fake.Invokes(NewListAction(configMapResourceName, c.Namespace, opts), &extensions.ConfigMapList{})
if obj == nil {
return nil, err
}
return obj.(*extensions.ConfigMapList), err
}
func (c *FakeConfigMaps) Create(cfg *extensions.ConfigMap) (*extensions.ConfigMap, error) {
obj, err := c.Fake.Invokes(NewCreateAction(configMapResourceName, c.Namespace, cfg), cfg)
if obj == nil {
return nil, err
}
return obj.(*extensions.ConfigMap), err
}
func (c *FakeConfigMaps) Update(cfg *extensions.ConfigMap) (*extensions.ConfigMap, error) {
obj, err := c.Fake.Invokes(NewUpdateAction(configMapResourceName, c.Namespace, cfg), cfg)
if obj == nil {
return nil, err
}
return obj.(*extensions.ConfigMap), err
}
func (c *FakeConfigMaps) Delete(name string) error {
_, err := c.Fake.Invokes(NewDeleteAction(configMapResourceName, c.Namespace, name), &extensions.ConfigMap{})
return err
}
func (c *FakeConfigMaps) Watch(opts api.ListOptions) (watch.Interface, error) {
return c.Fake.InvokesWatch(NewWatchAction(configMapResourceName, c.Namespace, opts))
}

View File

@ -353,6 +353,10 @@ func (c *FakeExperimental) Ingress(namespace string) client.IngressInterface {
return &FakeIngress{Fake: c, Namespace: namespace}
}
func (c *FakeExperimental) ConfigMaps(namespace string) client.ConfigMapsInterface {
return &FakeConfigMaps{Fake: c, Namespace: namespace}
}
func (c *FakeExperimental) ThirdPartyResources(namespace string) client.ThirdPartyResourceInterface {
return &FakeThirdPartyResources{Fake: c, Namespace: namespace}
}

View File

@ -0,0 +1,20 @@
/*
Copyright 2015 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 configmap provides Registry interface
// and its REST implementation for storing
// ConfigMap API objects.
package configmap

View File

@ -0,0 +1,79 @@
/*
Copyright 2015 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 etcd
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/registry/configmap"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage"
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
)
// REST implements a RESTStorage for ConfigMap against etcd
type REST struct {
*etcdgeneric.Etcd
}
// NewREST returns a RESTStorage object that will work with ConfigMap objects.
func NewREST(s storage.Interface, storageDecorator generic.StorageDecorator) *REST {
prefix := "/configmaps"
newListFunc := func() runtime.Object { return &extensions.ConfigMapList{} }
storageInterface := storageDecorator(
s, 100, &extensions.ConfigMap{}, prefix, false, newListFunc)
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object {
return &extensions.ConfigMap{}
},
// NewListFunc returns an object to store results of an etcd list.
NewListFunc: newListFunc,
// Produces a path that etcd understands, to the root of the resource
// by combining the namespace in the context with the given prefix.
KeyRootFunc: func(ctx api.Context) string {
return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
},
// Produces a path that etcd understands, to the resource by combining
// the namespace in the context with the given prefix
KeyFunc: func(ctx api.Context, name string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name)
},
// Retrieves the name field of a ConfigMap object.
ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*extensions.ConfigMap).Name, nil
},
// Matches objects based on labels/fields for list and watch
PredicateFunc: configmap.MatchConfigMap,
EndpointName: "configmaps",
CreateStrategy: configmap.Strategy,
UpdateStrategy: configmap.Strategy,
Storage: storageInterface,
}
return &REST{store}
}

View File

@ -0,0 +1,149 @@
/*
Copyright 2015 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 etcd
import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime"
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
)
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
etcdStorage, server := registrytest.NewEtcdStorage(t, "extensions")
return NewREST(etcdStorage, generic.UndecoratedStorage), server
}
func validNewConfigMap() *extensions.ConfigMap {
return &extensions.ConfigMap{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Namespace: "default",
Labels: map[string]string{
"label-1": "value-1",
"label-2": "value-2",
},
},
Data: map[string]string{
"test": "data",
},
}
}
func TestCreate(t *testing.T) {
storage, server := newStorage(t)
defer server.Terminate(t)
test := registrytest.New(t, storage.Etcd)
validConfigMap := validNewConfigMap()
validConfigMap.ObjectMeta = api.ObjectMeta{
GenerateName: "foo-",
}
test.TestCreate(
validConfigMap,
&extensions.ConfigMap{
ObjectMeta: api.ObjectMeta{Name: "badName"},
Data: map[string]string{
"key": "value",
},
},
&extensions.ConfigMap{
ObjectMeta: api.ObjectMeta{Name: "name-2"},
Data: map[string]string{
"..dotfile": "do: nothing\n",
},
},
)
}
func TestUpdate(t *testing.T) {
storage, server := newStorage(t)
defer server.Terminate(t)
test := registrytest.New(t, storage.Etcd)
test.TestUpdate(
// valid
validNewConfigMap(),
// updateFunc
func(obj runtime.Object) runtime.Object {
cfg := obj.(*extensions.ConfigMap)
cfg.Data["update-test"] = "value"
return cfg
},
// invalid updateFunc
func(obj runtime.Object) runtime.Object {
cfg := obj.(*extensions.ConfigMap)
cfg.Data["badKey"] = "value"
return cfg
},
)
}
func TestDelete(t *testing.T) {
storage, server := newStorage(t)
defer server.Terminate(t)
test := registrytest.New(t, storage.Etcd)
test.TestDelete(validNewConfigMap())
}
func TestGet(t *testing.T) {
storage, server := newStorage(t)
defer server.Terminate(t)
test := registrytest.New(t, storage.Etcd)
test.TestGet(validNewConfigMap())
}
func TestList(t *testing.T) {
storage, server := newStorage(t)
defer server.Terminate(t)
test := registrytest.New(t, storage.Etcd)
test.TestList(validNewConfigMap())
}
func TestWatch(t *testing.T) {
storage, server := newStorage(t)
defer server.Terminate(t)
test := registrytest.New(t, storage.Etcd)
test.TestWatch(
validNewConfigMap(),
// matching labels
[]labels.Set{
{"label-1": "value-1"},
{"label-2": "value-2"},
},
// not matching labels
[]labels.Set{
{"foo": "bar"},
},
// matching fields
[]fields.Set{
{"metadata.namespace": "default"},
{"metadata.name": "foo"},
},
// not matching fields
[]fields.Set{
{"metadata.name": "bar"},
{"name": "foo"},
},
)
}

View File

@ -0,0 +1,92 @@
/*
Copyright 2015 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 configmap
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/watch"
)
// Registry is an interface for things that know how to store ConfigMaps.
type Registry interface {
ListConfigMaps(ctx api.Context, options *unversioned.ListOptions) (*extensions.ConfigMapList, error)
WatchConfigMaps(ctx api.Context, options *unversioned.ListOptions) (watch.Interface, error)
GetConfigMap(ctx api.Context, name string) (*extensions.ConfigMap, error)
CreateConfigMap(ctx api.Context, cfg *extensions.ConfigMap) (*extensions.ConfigMap, error)
UpdateConfigMap(ctx api.Context, cfg *extensions.ConfigMap) (*extensions.ConfigMap, error)
DeleteConfigMap(ctx api.Context, name string) error
}
// storage puts strong typing around storage calls
type storage struct {
rest.StandardStorage
}
// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
// types will panic.
func NewRegistry(s rest.StandardStorage) Registry {
return &storage{s}
}
func (s *storage) ListConfigMaps(ctx api.Context, options *unversioned.ListOptions) (*extensions.ConfigMapList, error) {
obj, err := s.List(ctx, options)
if err != nil {
return nil, err
}
return obj.(*extensions.ConfigMapList), err
}
func (s *storage) WatchConfigMaps(ctx api.Context, options *unversioned.ListOptions) (watch.Interface, error) {
return s.Watch(ctx, options)
}
func (s *storage) GetConfigMap(ctx api.Context, name string) (*extensions.ConfigMap, error) {
obj, err := s.Get(ctx, name)
if err != nil {
return nil, err
}
return obj.(*extensions.ConfigMap), nil
}
func (s *storage) CreateConfigMap(ctx api.Context, cfg *extensions.ConfigMap) (*extensions.ConfigMap, error) {
obj, err := s.Create(ctx, cfg)
if err != nil {
return nil, err
}
return obj.(*extensions.ConfigMap), nil
}
func (s *storage) UpdateConfigMap(ctx api.Context, cfg *extensions.ConfigMap) (*extensions.ConfigMap, error) {
obj, _, err := s.Update(ctx, cfg)
if err != nil {
return nil, err
}
return obj.(*extensions.ConfigMap), nil
}
func (s *storage) DeleteConfigMap(ctx api.Context, name string) error {
_, err := s.Delete(ctx, name, nil)
return err
}

View File

@ -0,0 +1,105 @@
/*
Copyright 2015 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 configmap
import (
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions/validation"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/validation/field"
)
// strategy implements behavior for ConfigMap objects
type strategy struct {
runtime.ObjectTyper
api.NameGenerator
}
// Strategy is the default logic that applies when creating and updating ConfigMap
// objects via the REST API.
var Strategy = strategy{api.Scheme, api.SimpleNameGenerator}
// Strategy should implement rest.RESTCreateStrategy
var _ rest.RESTCreateStrategy = Strategy
// Strategy should implement rest.RESTUpdateStrategy
var _ rest.RESTUpdateStrategy = Strategy
func (strategy) NamespaceScoped() bool {
return true
}
func (strategy) PrepareForCreate(obj runtime.Object) {
_ = obj.(*extensions.ConfigMap)
}
func (strategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
cfg := obj.(*extensions.ConfigMap)
return validation.ValidateConfigMap(cfg)
}
// Canonicalize normalizes the object after validation.
func (strategy) Canonicalize(obj runtime.Object) {
}
func (strategy) AllowCreateOnUpdate() bool {
return false
}
func (strategy) PrepareForUpdate(newObj, oldObj runtime.Object) {
_ = oldObj.(*extensions.ConfigMap)
_ = newObj.(*extensions.ConfigMap)
}
func (strategy) AllowUnconditionalUpdate() bool {
return true
}
func (strategy) ValidateUpdate(ctx api.Context, newObj, oldObj runtime.Object) field.ErrorList {
oldCfg, newCfg := oldObj.(*extensions.ConfigMap), newObj.(*extensions.ConfigMap)
return validation.ValidateConfigMapUpdate(newCfg, oldCfg)
}
// ConfigMapToSelectableFields returns a field set that represents the object for matching purposes.
func ConfigMapToSelectableFields(cfg *extensions.ConfigMap) fields.Set {
return generic.ObjectMetaFieldsSet(cfg.ObjectMeta, true)
}
// MatchConfigMap returns a generic matcher for a given label and field selector.
func MatchConfigMap(label labels.Selector, field fields.Selector) generic.Matcher {
return &generic.SelectionPredicate{
Label: label,
Field: field,
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
cfg, ok := obj.(*extensions.ConfigMap)
if !ok {
return nil, nil, fmt.Errorf("given object is not of type ConfigMap")
}
return labels.Set(cfg.ObjectMeta.Labels), ConfigMapToSelectableFields(cfg), nil
},
}
}

View File

@ -0,0 +1,69 @@
/*
Copyright 2015 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 configmap
import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
)
func TestConfigMapStrategy(t *testing.T) {
ctx := api.NewDefaultContext()
if !Strategy.NamespaceScoped() {
t.Errorf("ConfigMap must be namespace scoped")
}
if Strategy.AllowCreateOnUpdate() {
t.Errorf("ConfigMap should not allow create on update")
}
cfg := &extensions.ConfigMap{
ObjectMeta: api.ObjectMeta{
Name: "valid-config-data",
Namespace: api.NamespaceDefault,
},
Data: map[string]string{
"foo": "bar",
},
}
Strategy.PrepareForCreate(cfg)
errs := Strategy.Validate(ctx, cfg)
if len(errs) != 0 {
t.Errorf("unexpected error validating %v", errs)
}
newCfg := &extensions.ConfigMap{
ObjectMeta: api.ObjectMeta{
Name: "valid-config-data-2",
Namespace: api.NamespaceDefault,
ResourceVersion: "4",
},
Data: map[string]string{
"invalidKey": "updatedValue",
},
}
Strategy.PrepareForUpdate(newCfg, cfg)
errs = Strategy.ValidateUpdate(ctx, newCfg, cfg)
if len(errs) == 0 {
t.Errorf("Expected a validation error")
}
}