Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
8fa21ebd
Commit
8fa21ebd
authored
Apr 29, 2015
by
Paul Morie
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7419 from liggitt/secrets_etcd
Convert Secret registry to use update/create strategy, allow filtering by Type
parents
467d5924
ac67fff1
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
392 additions
and
525 deletions
+392
-525
conversion.go
pkg/api/v1beta1/conversion.go
+13
-0
conversion.go
pkg/api/v1beta2/conversion.go
+13
-0
conversion.go
pkg/api/v1beta3/conversion.go
+13
-0
validation.go
pkg/api/validation/validation.go
+23
-0
request.go
pkg/client/request.go
+20
-9
resource_printer.go
pkg/kubectl/resource_printer.go
+2
-2
master.go
pkg/master/master.go
+3
-3
etcd.go
pkg/registry/secret/etcd/etcd.go
+64
-0
etcd_test.go
pkg/registry/secret/etcd/etcd_test.go
+93
-0
registry.go
pkg/registry/secret/registry.go
+63
-25
registry_test.go
pkg/registry/secret/registry_test.go
+0
-110
rest.go
pkg/registry/secret/rest.go
+0
-163
rest_test.go
pkg/registry/secret/rest_test.go
+0
-213
strategy.go
pkg/registry/secret/strategy.go
+85
-0
No files found.
pkg/api/v1beta1/conversion.go
View file @
8fa21ebd
...
@@ -1648,4 +1648,17 @@ func init() {
...
@@ -1648,4 +1648,17 @@ func init() {
// If one of the conversion functions is malformed, detect it immediately.
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
panic
(
err
)
}
}
err
=
newer
.
Scheme
.
AddFieldLabelConversionFunc
(
"v1beta1"
,
"Secret"
,
func
(
label
,
value
string
)
(
string
,
string
,
error
)
{
switch
label
{
case
"type"
:
return
label
,
value
,
nil
default
:
return
""
,
""
,
fmt
.
Errorf
(
"field label not supported: %s"
,
label
)
}
})
if
err
!=
nil
{
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
}
}
}
pkg/api/v1beta2/conversion.go
View file @
8fa21ebd
...
@@ -1564,4 +1564,17 @@ func init() {
...
@@ -1564,4 +1564,17 @@ func init() {
// If one of the conversion functions is malformed, detect it immediately.
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
panic
(
err
)
}
}
err
=
newer
.
Scheme
.
AddFieldLabelConversionFunc
(
"v1beta2"
,
"Secret"
,
func
(
label
,
value
string
)
(
string
,
string
,
error
)
{
switch
label
{
case
"type"
:
return
label
,
value
,
nil
default
:
return
""
,
""
,
fmt
.
Errorf
(
"field label not supported: %s"
,
label
)
}
})
if
err
!=
nil
{
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
}
}
}
pkg/api/v1beta3/conversion.go
View file @
8fa21ebd
...
@@ -2807,4 +2807,17 @@ func init() {
...
@@ -2807,4 +2807,17 @@ func init() {
// If one of the conversion functions is malformed, detect it immediately.
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
panic
(
err
)
}
}
err
=
newer
.
Scheme
.
AddFieldLabelConversionFunc
(
"v1beta3"
,
"Secret"
,
func
(
label
,
value
string
)
(
string
,
string
,
error
)
{
switch
label
{
case
"type"
:
return
label
,
value
,
nil
default
:
return
""
,
""
,
fmt
.
Errorf
(
"field label not supported: %s"
,
label
)
}
})
if
err
!=
nil
{
// If one of the conversion functions is malformed, detect it immediately.
panic
(
err
)
}
}
}
pkg/api/validation/validation.go
View file @
8fa21ebd
...
@@ -1242,6 +1242,29 @@ func ValidateSecret(secret *api.Secret) errs.ValidationErrorList {
...
@@ -1242,6 +1242,29 @@ func ValidateSecret(secret *api.Secret) errs.ValidationErrorList {
allErrs
=
append
(
allErrs
,
errs
.
NewFieldForbidden
(
"data"
,
"Maximum secret size exceeded"
))
allErrs
=
append
(
allErrs
,
errs
.
NewFieldForbidden
(
"data"
,
"Maximum secret size exceeded"
))
}
}
switch
secret
.
Type
{
case
api
.
SecretTypeOpaque
,
""
:
// no-op
default
:
// no-op
}
return
allErrs
}
// ValidateSecretUpdate tests if required fields in the Secret are set.
func
ValidateSecretUpdate
(
oldSecret
,
newSecret
*
api
.
Secret
)
errs
.
ValidationErrorList
{
allErrs
:=
errs
.
ValidationErrorList
{}
allErrs
=
append
(
allErrs
,
ValidateObjectMetaUpdate
(
&
oldSecret
.
ObjectMeta
,
&
newSecret
.
ObjectMeta
)
.
Prefix
(
"metadata"
)
...
)
if
len
(
newSecret
.
Type
)
==
0
{
newSecret
.
Type
=
oldSecret
.
Type
}
if
newSecret
.
Type
!=
oldSecret
.
Type
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"type"
,
newSecret
.
Type
,
"field is immutable"
))
}
allErrs
=
append
(
allErrs
,
ValidateSecret
(
newSecret
)
...
)
return
allErrs
return
allErrs
}
}
...
...
pkg/client/request.go
View file @
8fa21ebd
...
@@ -20,6 +20,16 @@ import (
...
@@ -20,6 +20,16 @@ import (
"bytes"
"bytes"
"crypto/tls"
"crypto/tls"
"fmt"
"fmt"
"io"
"io/ioutil"
"mime"
"net/http"
"net/url"
"path"
"strconv"
"strings"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/metrics"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/metrics"
...
@@ -31,15 +41,6 @@ import (
...
@@ -31,15 +41,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
watchjson
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json"
watchjson
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json"
"github.com/golang/glog"
"github.com/golang/glog"
"io"
"io/ioutil"
"mime"
"net/http"
"net/url"
"path"
"strconv"
"strings"
"time"
)
)
// specialParams lists parameters that are handled specially and which users of Request
// specialParams lists parameters that are handled specially and which users of Request
...
@@ -253,6 +254,7 @@ const (
...
@@ -253,6 +254,7 @@ const (
NodeUnschedulable
=
"spec.unschedulable"
NodeUnschedulable
=
"spec.unschedulable"
ObjectNameField
=
"metadata.name"
ObjectNameField
=
"metadata.name"
PodHost
=
"spec.host"
PodHost
=
"spec.host"
SecretType
=
"type"
)
)
type
clientFieldNameToAPIVersionFieldName
map
[
string
]
string
type
clientFieldNameToAPIVersionFieldName
map
[
string
]
string
...
@@ -305,6 +307,9 @@ var fieldMappings = versionToResourceToFieldMapping{
...
@@ -305,6 +307,9 @@ var fieldMappings = versionToResourceToFieldMapping{
"pods"
:
clientFieldNameToAPIVersionFieldName
{
"pods"
:
clientFieldNameToAPIVersionFieldName
{
PodHost
:
"DesiredState.Host"
,
PodHost
:
"DesiredState.Host"
,
},
},
"secrets"
:
clientFieldNameToAPIVersionFieldName
{
SecretType
:
"type"
,
},
},
},
"v1beta2"
:
resourceTypeToFieldMapping
{
"v1beta2"
:
resourceTypeToFieldMapping
{
"nodes"
:
clientFieldNameToAPIVersionFieldName
{
"nodes"
:
clientFieldNameToAPIVersionFieldName
{
...
@@ -318,6 +323,9 @@ var fieldMappings = versionToResourceToFieldMapping{
...
@@ -318,6 +323,9 @@ var fieldMappings = versionToResourceToFieldMapping{
"pods"
:
clientFieldNameToAPIVersionFieldName
{
"pods"
:
clientFieldNameToAPIVersionFieldName
{
PodHost
:
"DesiredState.Host"
,
PodHost
:
"DesiredState.Host"
,
},
},
"secrets"
:
clientFieldNameToAPIVersionFieldName
{
SecretType
:
"type"
,
},
},
},
"v1beta3"
:
resourceTypeToFieldMapping
{
"v1beta3"
:
resourceTypeToFieldMapping
{
"nodes"
:
clientFieldNameToAPIVersionFieldName
{
"nodes"
:
clientFieldNameToAPIVersionFieldName
{
...
@@ -331,6 +339,9 @@ var fieldMappings = versionToResourceToFieldMapping{
...
@@ -331,6 +339,9 @@ var fieldMappings = versionToResourceToFieldMapping{
"pods"
:
clientFieldNameToAPIVersionFieldName
{
"pods"
:
clientFieldNameToAPIVersionFieldName
{
PodHost
:
"spec.host"
,
PodHost
:
"spec.host"
,
},
},
"secrets"
:
clientFieldNameToAPIVersionFieldName
{
SecretType
:
"type"
,
},
},
},
}
}
...
...
pkg/kubectl/resource_printer.go
View file @
8fa21ebd
...
@@ -255,7 +255,7 @@ var eventColumns = []string{"FIRSTSEEN", "LASTSEEN", "COUNT", "NAME", "KIND", "S
...
@@ -255,7 +255,7 @@ var eventColumns = []string{"FIRSTSEEN", "LASTSEEN", "COUNT", "NAME", "KIND", "S
var
limitRangeColumns
=
[]
string
{
"NAME"
}
var
limitRangeColumns
=
[]
string
{
"NAME"
}
var
resourceQuotaColumns
=
[]
string
{
"NAME"
}
var
resourceQuotaColumns
=
[]
string
{
"NAME"
}
var
namespaceColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"STATUS"
}
var
namespaceColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"STATUS"
}
var
secretColumns
=
[]
string
{
"NAME"
,
"DATA"
}
var
secretColumns
=
[]
string
{
"NAME"
,
"
TYPE"
,
"
DATA"
}
var
persistentVolumeColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"CAPACITY"
,
"ACCESSMODES"
,
"STATUS"
,
"CLAIM"
}
var
persistentVolumeColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"CAPACITY"
,
"ACCESSMODES"
,
"STATUS"
,
"CLAIM"
}
var
persistentVolumeClaimColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"STATUS"
,
"VOLUME"
}
var
persistentVolumeClaimColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"STATUS"
,
"VOLUME"
}
var
componentStatusColumns
=
[]
string
{
"NAME"
,
"STATUS"
,
"MESSAGE"
,
"ERROR"
}
var
componentStatusColumns
=
[]
string
{
"NAME"
,
"STATUS"
,
"MESSAGE"
,
"ERROR"
}
...
@@ -584,7 +584,7 @@ func printNamespaceList(list *api.NamespaceList, w io.Writer) error {
...
@@ -584,7 +584,7 @@ func printNamespaceList(list *api.NamespaceList, w io.Writer) error {
}
}
func
printSecret
(
item
*
api
.
Secret
,
w
io
.
Writer
)
error
{
func
printSecret
(
item
*
api
.
Secret
,
w
io
.
Writer
)
error
{
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%
v
\n
"
,
item
.
Nam
e
,
len
(
item
.
Data
))
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%
s
\t
%v
\n
"
,
item
.
Name
,
item
.
Typ
e
,
len
(
item
.
Data
))
return
err
return
err
}
}
...
...
pkg/master/master.go
View file @
8fa21ebd
...
@@ -61,7 +61,7 @@ import (
...
@@ -61,7 +61,7 @@ import (
podetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/etcd"
podetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/etcd"
podtemplateetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/podtemplate/etcd"
podtemplateetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/podtemplate/etcd"
resourcequotaetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/etcd"
resourcequotaetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret
"
secretetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret/etcd
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/ui"
"github.com/GoogleCloudPlatform/kubernetes/pkg/ui"
...
@@ -388,7 +388,7 @@ func (m *Master) init(c *Config) {
...
@@ -388,7 +388,7 @@ func (m *Master) init(c *Config) {
limitRangeRegistry
:=
limitrange
.
NewEtcdRegistry
(
c
.
EtcdHelper
)
limitRangeRegistry
:=
limitrange
.
NewEtcdRegistry
(
c
.
EtcdHelper
)
resourceQuotaStorage
,
resourceQuotaStatusStorage
:=
resourcequotaetcd
.
NewStorage
(
c
.
EtcdHelper
)
resourceQuotaStorage
,
resourceQuotaStatusStorage
:=
resourcequotaetcd
.
NewStorage
(
c
.
EtcdHelper
)
secret
Registry
:=
secret
.
NewEtcdRegistry
(
c
.
EtcdHelper
)
secret
Storage
:=
secretetcd
.
NewStorage
(
c
.
EtcdHelper
)
persistentVolumeStorage
,
persistentVolumeStatusStorage
:=
pvetcd
.
NewStorage
(
c
.
EtcdHelper
)
persistentVolumeStorage
,
persistentVolumeStatusStorage
:=
pvetcd
.
NewStorage
(
c
.
EtcdHelper
)
persistentVolumeClaimStorage
,
persistentVolumeClaimStatusStorage
:=
pvcetcd
.
NewStorage
(
c
.
EtcdHelper
)
persistentVolumeClaimStorage
,
persistentVolumeClaimStatusStorage
:=
pvcetcd
.
NewStorage
(
c
.
EtcdHelper
)
...
@@ -435,7 +435,7 @@ func (m *Master) init(c *Config) {
...
@@ -435,7 +435,7 @@ func (m *Master) init(c *Config) {
"namespaces"
:
namespaceStorage
,
"namespaces"
:
namespaceStorage
,
"namespaces/status"
:
namespaceStatusStorage
,
"namespaces/status"
:
namespaceStatusStorage
,
"namespaces/finalize"
:
namespaceFinalizeStorage
,
"namespaces/finalize"
:
namespaceFinalizeStorage
,
"secrets"
:
secret
.
NewStorage
(
secretRegistry
)
,
"secrets"
:
secret
Storage
,
"persistentVolumes"
:
persistentVolumeStorage
,
"persistentVolumes"
:
persistentVolumeStorage
,
"persistentVolumes/status"
:
persistentVolumeStatusStorage
,
"persistentVolumes/status"
:
persistentVolumeStatusStorage
,
"persistentVolumeClaims"
:
persistentVolumeClaimStorage
,
"persistentVolumeClaims"
:
persistentVolumeClaimStorage
,
...
...
pkg/registry/secret/etcd/etcd.go
0 → 100644
View file @
8fa21ebd
/*
Copyright 2015 Google Inc. 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
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
)
// REST implements a RESTStorage for secrets against etcd
type
REST
struct
{
*
etcdgeneric
.
Etcd
}
// NewStorage returns a registry which will store Secret in the given helper
func
NewStorage
(
h
tools
.
EtcdHelper
)
*
REST
{
prefix
:=
"/secrets"
store
:=
&
etcdgeneric
.
Etcd
{
NewFunc
:
func
()
runtime
.
Object
{
return
&
api
.
Secret
{}
},
NewListFunc
:
func
()
runtime
.
Object
{
return
&
api
.
SecretList
{}
},
KeyRootFunc
:
func
(
ctx
api
.
Context
)
string
{
return
etcdgeneric
.
NamespaceKeyRootFunc
(
ctx
,
prefix
)
},
KeyFunc
:
func
(
ctx
api
.
Context
,
id
string
)
(
string
,
error
)
{
return
etcdgeneric
.
NamespaceKeyFunc
(
ctx
,
prefix
,
id
)
},
ObjectNameFunc
:
func
(
obj
runtime
.
Object
)
(
string
,
error
)
{
return
obj
.
(
*
api
.
Secret
)
.
Name
,
nil
},
PredicateFunc
:
func
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
secret
.
Matcher
(
label
,
field
)
},
EndpointName
:
"secrets"
,
Helper
:
h
,
}
store
.
CreateStrategy
=
secret
.
Strategy
store
.
UpdateStrategy
=
secret
.
Strategy
return
&
REST
{
store
}
}
pkg/registry/secret/etcd/etcd_test.go
0 → 100644
View file @
8fa21ebd
/*
Copyright 2015 Google Inc. 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"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func
newHelper
(
t
*
testing
.
T
)
(
*
tools
.
FakeEtcdClient
,
tools
.
EtcdHelper
)
{
fakeEtcdClient
:=
tools
.
NewFakeEtcdClient
(
t
)
fakeEtcdClient
.
TestIndex
=
true
helper
:=
tools
.
NewEtcdHelper
(
fakeEtcdClient
,
testapi
.
Codec
(),
etcdtest
.
PathPrefix
())
return
fakeEtcdClient
,
helper
}
func
validNewSecret
(
name
string
)
*
api
.
Secret
{
return
&
api
.
Secret
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
name
,
Namespace
:
api
.
NamespaceDefault
,
},
Data
:
map
[
string
][]
byte
{
"test"
:
[]
byte
(
"data"
),
},
}
}
func
TestCreate
(
t
*
testing
.
T
)
{
fakeEtcdClient
,
helper
:=
newHelper
(
t
)
storage
:=
NewStorage
(
helper
)
test
:=
resttest
.
New
(
t
,
storage
,
fakeEtcdClient
.
SetError
)
secret
:=
validNewSecret
(
"foo"
)
secret
.
Name
=
""
secret
.
GenerateName
=
"foo-"
test
.
TestCreate
(
// valid
secret
,
// invalid
&
api
.
Secret
{},
&
api
.
Secret
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"name"
},
Data
:
map
[
string
][]
byte
{
"name with spaces"
:
[]
byte
(
""
)},
},
&
api
.
Secret
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"name"
},
Data
:
map
[
string
][]
byte
{
".dotfile"
:
[]
byte
(
""
)},
},
)
}
func
TestUpdate
(
t
*
testing
.
T
)
{
fakeEtcdClient
,
helper
:=
newHelper
(
t
)
storage
:=
NewStorage
(
helper
)
test
:=
resttest
.
New
(
t
,
storage
,
fakeEtcdClient
.
SetError
)
key
:=
etcdtest
.
AddPrefix
(
"secrets/default/foo"
)
fakeEtcdClient
.
ExpectNotFoundGet
(
key
)
fakeEtcdClient
.
ChangeIndex
=
2
secret
:=
validNewSecret
(
"foo"
)
existing
:=
validNewSecret
(
"exists"
)
obj
,
err
:=
storage
.
Create
(
api
.
NewDefaultContext
(),
existing
)
if
err
!=
nil
{
t
.
Fatalf
(
"unable to create object: %v"
,
err
)
}
older
:=
obj
.
(
*
api
.
Secret
)
older
.
ResourceVersion
=
"1"
test
.
TestUpdate
(
secret
,
existing
,
older
,
)
}
pkg/registry/secret/registry.go
View file @
8fa21ebd
...
@@ -18,32 +18,70 @@ package secret
...
@@ -18,32 +18,70 @@ package secret
import
(
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
registry/generic
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
api/rest
"
etcdgeneric
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
runtime
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
labels
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
tools
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
watch
"
)
)
// registry implements custom changes to generic.Etcd.
// Registry is an interface implemented by things that know how to store Secret objects.
type
registry
struct
{
type
Registry
interface
{
*
etcdgeneric
.
Etcd
// ListSecrets obtains a list of Secrets having labels which match selector.
}
ListSecrets
(
ctx
api
.
Context
,
selector
labels
.
Selector
)
(
*
api
.
SecretList
,
error
)
// Watch for new/changed/deleted secrets
// NewEtcdRegistry returns a registry which will store Secret in the given helper
WatchSecrets
(
ctx
api
.
Context
,
label
labels
.
Selector
,
field
fields
.
Selector
,
resourceVersion
string
)
(
watch
.
Interface
,
error
)
func
NewEtcdRegistry
(
h
tools
.
EtcdHelper
)
generic
.
Registry
{
// Get a specific Secret
prefix
:=
"/secrets"
GetSecret
(
ctx
api
.
Context
,
name
string
)
(
*
api
.
Secret
,
error
)
return
registry
{
// Create a Secret based on a specification.
Etcd
:
&
etcdgeneric
.
Etcd
{
CreateSecret
(
ctx
api
.
Context
,
Secret
*
api
.
Secret
)
(
*
api
.
Secret
,
error
)
NewFunc
:
func
()
runtime
.
Object
{
return
&
api
.
Secret
{}
},
// Update an existing Secret
NewListFunc
:
func
()
runtime
.
Object
{
return
&
api
.
SecretList
{}
},
UpdateSecret
(
ctx
api
.
Context
,
Secret
*
api
.
Secret
)
(
*
api
.
Secret
,
error
)
EndpointName
:
"secrets"
,
// Delete an existing Secret
KeyRootFunc
:
func
(
ctx
api
.
Context
)
string
{
DeleteSecret
(
ctx
api
.
Context
,
name
string
)
error
return
etcdgeneric
.
NamespaceKeyRootFunc
(
ctx
,
prefix
)
}
},
KeyFunc
:
func
(
ctx
api
.
Context
,
id
string
)
(
string
,
error
)
{
// storage puts strong typing around storage calls
return
etcdgeneric
.
NamespaceKeyFunc
(
ctx
,
prefix
,
id
)
type
storage
struct
{
},
rest
.
StandardStorage
Helper
:
h
,
}
},
// 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
)
ListSecrets
(
ctx
api
.
Context
,
label
labels
.
Selector
)
(
*
api
.
SecretList
,
error
)
{
obj
,
err
:=
s
.
List
(
ctx
,
label
,
fields
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
}
return
obj
.
(
*
api
.
SecretList
),
nil
}
func
(
s
*
storage
)
WatchSecrets
(
ctx
api
.
Context
,
label
labels
.
Selector
,
field
fields
.
Selector
,
resourceVersion
string
)
(
watch
.
Interface
,
error
)
{
return
s
.
Watch
(
ctx
,
label
,
field
,
resourceVersion
)
}
func
(
s
*
storage
)
GetSecret
(
ctx
api
.
Context
,
name
string
)
(
*
api
.
Secret
,
error
)
{
obj
,
err
:=
s
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
api
.
Secret
),
nil
}
func
(
s
*
storage
)
CreateSecret
(
ctx
api
.
Context
,
secret
*
api
.
Secret
)
(
*
api
.
Secret
,
error
)
{
obj
,
err
:=
s
.
Create
(
ctx
,
secret
)
return
obj
.
(
*
api
.
Secret
),
err
}
func
(
s
*
storage
)
UpdateSecret
(
ctx
api
.
Context
,
secret
*
api
.
Secret
)
(
*
api
.
Secret
,
error
)
{
obj
,
_
,
err
:=
s
.
Update
(
ctx
,
secret
)
return
obj
.
(
*
api
.
Secret
),
err
}
func
(
s
*
storage
)
DeleteSecret
(
ctx
api
.
Context
,
name
string
)
error
{
_
,
err
:=
s
.
Delete
(
ctx
,
name
,
nil
)
return
err
}
}
pkg/registry/secret/registry_test.go
deleted
100644 → 0
View file @
467d5924
/*
Copyright 2014 Google Inc. 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
secret
import
(
"reflect"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
)
func
NewTestSecretEtcdRegistry
(
t
*
testing
.
T
)
(
*
tools
.
FakeEtcdClient
,
generic
.
Registry
)
{
f
:=
tools
.
NewFakeEtcdClient
(
t
)
f
.
TestIndex
=
true
h
:=
tools
.
NewEtcdHelper
(
f
,
testapi
.
Codec
(),
etcdtest
.
PathPrefix
())
return
f
,
NewEtcdRegistry
(
h
)
}
func
TestSecretCreate
(
t
*
testing
.
T
)
{
secret
:=
&
api
.
Secret
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"abc"
,
Namespace
:
"foo"
,
},
Data
:
map
[
string
][]
byte
{
"data-1"
:
[]
byte
(
"value-1"
),
},
}
nodeWithSecret
:=
tools
.
EtcdResponseWithError
{
R
:
&
etcd
.
Response
{
Node
:
&
etcd
.
Node
{
Value
:
runtime
.
EncodeOrDie
(
testapi
.
Codec
(),
secret
),
ModifiedIndex
:
1
,
CreatedIndex
:
1
,
},
},
E
:
nil
,
}
emptyNode
:=
tools
.
EtcdResponseWithError
{
R
:
&
etcd
.
Response
{},
E
:
tools
.
EtcdErrorNotFound
,
}
ctx
:=
api
.
NewDefaultContext
()
key
:=
"foo"
path
,
err
:=
etcdgeneric
.
NamespaceKeyFunc
(
ctx
,
"/secrets"
,
key
)
path
=
etcdtest
.
AddPrefix
(
path
)
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
table
:=
map
[
string
]
struct
{
existing
tools
.
EtcdResponseWithError
expect
tools
.
EtcdResponseWithError
toCreate
runtime
.
Object
errOK
func
(
error
)
bool
}{
"normal"
:
{
existing
:
emptyNode
,
expect
:
nodeWithSecret
,
toCreate
:
secret
,
errOK
:
func
(
err
error
)
bool
{
return
err
==
nil
},
},
"preExisting"
:
{
existing
:
nodeWithSecret
,
expect
:
nodeWithSecret
,
toCreate
:
secret
,
errOK
:
errors
.
IsAlreadyExists
,
},
}
for
name
,
item
:=
range
table
{
fakeClient
,
registry
:=
NewTestSecretEtcdRegistry
(
t
)
fakeClient
.
Data
[
path
]
=
item
.
existing
err
:=
registry
.
CreateWithName
(
ctx
,
key
,
item
.
toCreate
)
if
!
item
.
errOK
(
err
)
{
t
.
Errorf
(
"%v: unexpected error: %v"
,
name
,
err
)
}
if
e
,
a
:=
item
.
expect
,
fakeClient
.
Data
[
path
];
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"%v:
\n
%s"
,
name
,
util
.
ObjectDiff
(
e
,
a
))
}
}
}
pkg/registry/secret/rest.go
deleted
100644 → 0
View file @
467d5924
/*
Copyright 2015 Google Inc. 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
secret
import
(
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// REST provides the RESTStorage access patterns to work with Secret objects.
type
REST
struct
{
registry
generic
.
Registry
}
// NewStorage returns a new REST. You must use a registry created by
// NewEtcdRegistry unless you're testing.
func
NewStorage
(
registry
generic
.
Registry
)
*
REST
{
return
&
REST
{
registry
:
registry
,
}
}
// Create a Secret object
func
(
rs
*
REST
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
secret
,
ok
:=
obj
.
(
*
api
.
Secret
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"invalid object type"
)
}
if
!
api
.
ValidNamespace
(
ctx
,
&
secret
.
ObjectMeta
)
{
return
nil
,
errors
.
NewConflict
(
"secret"
,
secret
.
Namespace
,
fmt
.
Errorf
(
"Secret.Namespace does not match the provided context"
))
}
if
len
(
secret
.
Name
)
==
0
{
secret
.
Name
=
string
(
util
.
NewUUID
())
}
if
errs
:=
validation
.
ValidateSecret
(
secret
);
len
(
errs
)
>
0
{
return
nil
,
errors
.
NewInvalid
(
"secret"
,
secret
.
Name
,
errs
)
}
api
.
FillObjectMetaSystemFields
(
ctx
,
&
secret
.
ObjectMeta
)
err
:=
rs
.
registry
.
CreateWithName
(
ctx
,
secret
.
Name
,
secret
)
if
err
!=
nil
{
return
nil
,
err
}
return
rs
.
registry
.
Get
(
ctx
,
secret
.
Name
)
}
// Update updates a Secret object.
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
runtime
.
Object
,
bool
,
error
)
{
secret
,
ok
:=
obj
.
(
*
api
.
Secret
)
if
!
ok
{
return
nil
,
false
,
fmt
.
Errorf
(
"not a secret: %#v"
,
obj
)
}
if
!
api
.
ValidNamespace
(
ctx
,
&
secret
.
ObjectMeta
)
{
return
nil
,
false
,
errors
.
NewConflict
(
"secret"
,
secret
.
Namespace
,
fmt
.
Errorf
(
"Secret.Namespace does not match the provided context"
))
}
oldObj
,
err
:=
rs
.
registry
.
Get
(
ctx
,
secret
.
Name
)
if
err
!=
nil
{
return
nil
,
false
,
err
}
editSecret
:=
oldObj
.
(
*
api
.
Secret
)
// set the editable fields on the existing object
editSecret
.
Labels
=
secret
.
Labels
editSecret
.
ResourceVersion
=
secret
.
ResourceVersion
editSecret
.
Annotations
=
secret
.
Annotations
editSecret
.
Data
=
secret
.
Data
editSecret
.
Type
=
secret
.
Type
if
errs
:=
validation
.
ValidateSecret
(
editSecret
);
len
(
errs
)
>
0
{
return
nil
,
false
,
errors
.
NewInvalid
(
"secret"
,
editSecret
.
Name
,
errs
)
}
err
=
rs
.
registry
.
UpdateWithName
(
ctx
,
editSecret
.
Name
,
editSecret
)
if
err
!=
nil
{
return
nil
,
false
,
err
}
out
,
err
:=
rs
.
registry
.
Get
(
ctx
,
editSecret
.
Name
)
return
out
,
false
,
err
}
// Delete deletes the Secret with the specified name
func
(
rs
*
REST
)
Delete
(
ctx
api
.
Context
,
name
string
)
(
runtime
.
Object
,
error
)
{
obj
,
err
:=
rs
.
registry
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
_
,
ok
:=
obj
.
(
*
api
.
Secret
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"invalid object type"
)
}
return
rs
.
registry
.
Delete
(
ctx
,
name
,
nil
)
}
// Get gets a Secret with the specified name
func
(
rs
*
REST
)
Get
(
ctx
api
.
Context
,
name
string
)
(
runtime
.
Object
,
error
)
{
obj
,
err
:=
rs
.
registry
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
secret
,
ok
:=
obj
.
(
*
api
.
Secret
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"invalid object type"
)
}
return
secret
,
err
}
func
(
rs
*
REST
)
getAttrs
(
obj
runtime
.
Object
)
(
objLabels
labels
.
Set
,
objFields
fields
.
Set
,
err
error
)
{
secret
,
ok
:=
obj
.
(
*
api
.
Secret
)
if
!
ok
{
return
nil
,
nil
,
fmt
.
Errorf
(
"invalid object type"
)
}
return
labels
.
Set
{},
fields
.
Set
{
"type"
:
string
(
secret
.
Type
),
},
nil
}
func
(
rs
*
REST
)
List
(
ctx
api
.
Context
,
label
labels
.
Selector
,
field
fields
.
Selector
)
(
runtime
.
Object
,
error
)
{
return
rs
.
registry
.
ListPredicate
(
ctx
,
&
generic
.
SelectionPredicate
{
label
,
field
,
rs
.
getAttrs
})
}
func
(
rs
*
REST
)
Watch
(
ctx
api
.
Context
,
label
labels
.
Selector
,
field
fields
.
Selector
,
resourceVersion
string
)
(
watch
.
Interface
,
error
)
{
return
rs
.
registry
.
WatchPredicate
(
ctx
,
&
generic
.
SelectionPredicate
{
label
,
field
,
rs
.
getAttrs
},
resourceVersion
)
}
// New returns a new api.Secret
func
(
*
REST
)
New
()
runtime
.
Object
{
return
&
api
.
Secret
{}
}
func
(
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
SecretList
{}
}
pkg/registry/secret/rest_test.go
deleted
100644 → 0
View file @
467d5924
/*
Copyright 2015 Google Inc. 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
secret
import
(
"reflect"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
type
testRegistry
struct
{
*
registrytest
.
GenericRegistry
}
func
NewTestREST
()
(
testRegistry
,
*
REST
)
{
reg
:=
testRegistry
{
registrytest
.
NewGeneric
(
nil
)}
return
reg
,
NewStorage
(
reg
)
}
func
testSecret
(
name
string
)
*
api
.
Secret
{
return
&
api
.
Secret
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
name
,
Namespace
:
"default"
,
},
Data
:
map
[
string
][]
byte
{
"data-1"
:
[]
byte
(
"value-1"
),
},
Type
:
api
.
SecretTypeOpaque
,
}
}
func
TestRESTCreate
(
t
*
testing
.
T
)
{
table
:=
[]
struct
{
ctx
api
.
Context
secret
*
api
.
Secret
valid
bool
}{
{
ctx
:
api
.
NewDefaultContext
(),
secret
:
testSecret
(
"foo"
),
valid
:
true
,
},
{
ctx
:
api
.
NewContext
(),
secret
:
testSecret
(
"bar"
),
valid
:
false
,
},
{
ctx
:
api
.
WithNamespace
(
api
.
NewContext
(),
"nondefault"
),
secret
:
testSecret
(
"bazzzz"
),
valid
:
false
,
},
}
for
_
,
item
:=
range
table
{
_
,
storage
:=
NewTestREST
()
c
,
err
:=
storage
.
Create
(
item
.
ctx
,
item
.
secret
)
if
!
item
.
valid
{
if
err
==
nil
{
ctxNS
:=
api
.
NamespaceValue
(
item
.
ctx
)
t
.
Errorf
(
"%v: Unexpected non-error: (%v, %v)"
,
item
.
secret
.
Name
,
ctxNS
,
item
.
secret
.
Namespace
)
}
continue
}
if
err
!=
nil
{
t
.
Errorf
(
"%v: Unexpected error: %v"
,
item
.
secret
.
Name
,
err
)
continue
}
if
!
api
.
HasObjectMetaSystemFieldValues
(
&
item
.
secret
.
ObjectMeta
)
{
t
.
Errorf
(
"storage did not populate object meta field values"
)
}
if
e
,
a
:=
item
.
secret
,
c
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
// Ensure we implement the interface
_
=
rest
.
Watcher
(
storage
)
}
}
func
TestRESTUpdate
(
t
*
testing
.
T
)
{
ctx
:=
api
.
NewDefaultContext
()
registry
,
rest
:=
NewTestREST
()
registry
.
CreateWithName
(
ctx
,
"foo"
,
testSecret
(
"foo"
))
modifiedSecret
:=
testSecret
(
"foo"
)
modifiedSecret
.
Data
=
map
[
string
][]
byte
{
"data-2"
:
[]
byte
(
"value-2"
),
}
updatedObj
,
created
,
err
:=
rest
.
Update
(
ctx
,
modifiedSecret
)
if
err
!=
nil
{
t
.
Fatalf
(
"Expected no error: %v"
,
err
)
}
if
updatedObj
==
nil
{
t
.
Errorf
(
"Expected non-nil object"
)
}
if
created
{
t
.
Errorf
(
"expected not created"
)
}
updatedSecret
:=
updatedObj
.
(
*
api
.
Secret
)
if
updatedSecret
.
Name
!=
"foo"
{
t
.
Errorf
(
"Expected foo, but got %v"
,
updatedSecret
.
Name
)
}
}
func
TestRESTDelete
(
t
*
testing
.
T
)
{
_
,
rest
:=
NewTestREST
()
secretA
:=
testSecret
(
"foo"
)
_
,
err
:=
rest
.
Create
(
api
.
NewDefaultContext
(),
secretA
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
c
,
err
:=
rest
.
Delete
(
api
.
NewDefaultContext
(),
secretA
.
Name
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
if
stat
:=
c
.
(
*
api
.
Status
);
stat
.
Status
!=
api
.
StatusSuccess
{
t
.
Errorf
(
"unexpected status: %v"
,
stat
)
}
}
func
TestRESTGet
(
t
*
testing
.
T
)
{
_
,
rest
:=
NewTestREST
()
secretA
:=
testSecret
(
"foo"
)
_
,
err
:=
rest
.
Create
(
api
.
NewDefaultContext
(),
secretA
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
got
,
err
:=
rest
.
Get
(
api
.
NewDefaultContext
(),
secretA
.
Name
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
if
e
,
a
:=
secretA
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
func
TestRESTgetAttrs
(
t
*
testing
.
T
)
{
_
,
rest
:=
NewTestREST
()
secretA
:=
testSecret
(
"foo"
)
label
,
field
,
err
:=
rest
.
getAttrs
(
secretA
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
if
e
,
a
:=
label
,
(
labels
.
Set
{});
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
expect
:=
fields
.
Set
{
"type"
:
string
(
api
.
SecretTypeOpaque
),
}
if
e
,
a
:=
expect
,
field
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
func
TestRESTList
(
t
*
testing
.
T
)
{
reg
,
rest
:=
NewTestREST
()
var
(
secretA
=
testSecret
(
"a"
)
secretB
=
testSecret
(
"b"
)
secretC
=
testSecret
(
"c"
)
)
reg
.
ObjectList
=
&
api
.
SecretList
{
Items
:
[]
api
.
Secret
{
*
secretA
,
*
secretB
,
*
secretC
},
}
got
,
err
:=
rest
.
List
(
api
.
NewContext
(),
labels
.
Everything
(),
fields
.
Everything
())
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
expect
:=
&
api
.
SecretList
{
Items
:
[]
api
.
Secret
{
*
secretA
,
*
secretB
,
*
secretC
},
}
if
e
,
a
:=
expect
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
func
TestRESTWatch
(
t
*
testing
.
T
)
{
secretA
:=
testSecret
(
"a"
)
reg
,
rest
:=
NewTestREST
()
wi
,
err
:=
rest
.
Watch
(
api
.
NewContext
(),
labels
.
Everything
(),
fields
.
Everything
(),
"0"
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
go
func
()
{
reg
.
Broadcaster
.
Action
(
watch
.
Added
,
secretA
)
}()
got
:=
<-
wi
.
ResultChan
()
if
e
,
a
:=
secretA
,
got
.
Object
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
pkg/registry/secret/strategy.go
0 → 100644
View file @
8fa21ebd
/*
Copyright 2015 Google Inc. 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
secret
import
(
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
)
// strategy implements behavior for Secret objects
type
strategy
struct
{
runtime
.
ObjectTyper
api
.
NameGenerator
}
// Strategy is the default logic that applies when creating and updating Secret
// objects via the REST API.
var
Strategy
=
strategy
{
api
.
Scheme
,
api
.
SimpleNameGenerator
}
var
_
=
rest
.
RESTCreateStrategy
(
Strategy
)
var
_
=
rest
.
RESTUpdateStrategy
(
Strategy
)
func
(
strategy
)
NamespaceScoped
()
bool
{
return
true
}
func
(
strategy
)
PrepareForCreate
(
obj
runtime
.
Object
)
{
}
func
(
strategy
)
Validate
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
fielderrors
.
ValidationErrorList
{
return
validation
.
ValidateSecret
(
obj
.
(
*
api
.
Secret
))
}
func
(
strategy
)
AllowCreateOnUpdate
()
bool
{
return
false
}
func
(
strategy
)
PrepareForUpdate
(
obj
,
old
runtime
.
Object
)
{
}
func
(
strategy
)
ValidateUpdate
(
ctx
api
.
Context
,
obj
,
old
runtime
.
Object
)
fielderrors
.
ValidationErrorList
{
return
validation
.
ValidateSecretUpdate
(
old
.
(
*
api
.
Secret
),
obj
.
(
*
api
.
Secret
))
}
// Matcher returns a generic matcher for a given label and field selector.
func
Matcher
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
generic
.
MatcherFunc
(
func
(
obj
runtime
.
Object
)
(
bool
,
error
)
{
sa
,
ok
:=
obj
.
(
*
api
.
Secret
)
if
!
ok
{
return
false
,
fmt
.
Errorf
(
"not a secret"
)
}
fields
:=
SelectableFields
(
sa
)
return
label
.
Matches
(
labels
.
Set
(
sa
.
Labels
))
&&
field
.
Matches
(
fields
),
nil
})
}
// SelectableFields returns a label set that can be used for filter selection
func
SelectableFields
(
obj
*
api
.
Secret
)
labels
.
Set
{
return
labels
.
Set
{
"type"
:
string
(
obj
.
Type
),
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment