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
cb604f75
Commit
cb604f75
authored
May 15, 2017
by
deads2k
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
start using customresourcedefinition.status
parent
f88c7725
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
879 additions
and
83 deletions
+879
-83
BUILD
staging/src/k8s.io/client-go/tools/cache/BUILD
+2
-0
noxu-resource-definition.yaml
...artifacts/customresource-01/noxu-resource-definition.yaml
+1
-1
BUILD
...io/kube-apiextensions-server/pkg/apis/apiextensions/BUILD
+1
-0
helpers.go
...be-apiextensions-server/pkg/apis/apiextensions/helpers.go
+78
-0
BUILD
.../src/k8s.io/kube-apiextensions-server/pkg/apiserver/BUILD
+1
-0
apiserver.go
...s.io/kube-apiextensions-server/pkg/apiserver/apiserver.go
+6
-1
customresource_discovery_controller.go
...rver/pkg/apiserver/customresource_discovery_controller.go
+24
-21
customresource_handler.go
...extensions-server/pkg/apiserver/customresource_handler.go
+52
-49
BUILD
....io/kube-apiextensions-server/pkg/controller/status/BUILD
+44
-0
naming_controller.go
...ensions-server/pkg/controller/status/naming_controller.go
+337
-0
naming_controller_test.go
...ns-server/pkg/controller/status/naming_controller_test.go
+256
-0
BUILD
...nsions-server/pkg/registry/customresourcedefinition/BUILD
+1
-0
etcd.go
...ions-server/pkg/registry/customresourcedefinition/etcd.go
+27
-0
strategy.go
...-server/pkg/registry/customresourcedefinition/strategy.go
+49
-11
No files found.
staging/src/k8s.io/client-go/tools/cache/BUILD
View file @
cb604f75
...
@@ -53,6 +53,7 @@ go_library(
...
@@ -53,6 +53,7 @@ go_library(
"index.go",
"index.go",
"listers.go",
"listers.go",
"listwatch.go",
"listwatch.go",
"mutation_cache.go",
"mutation_detector.go",
"mutation_detector.go",
"reflector.go",
"reflector.go",
"shared_informer.go",
"shared_informer.go",
...
@@ -63,6 +64,7 @@ go_library(
...
@@ -63,6 +64,7 @@ go_library(
tags = ["automanaged"],
tags = ["automanaged"],
deps = [
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
...
...
staging/src/k8s.io/kube-apiextensions-server/artifacts/customresource-01/noxu-resource-definition.yaml
View file @
cb604f75
apiVersion
:
apiextensions.k8s.io/v1alpha1
apiVersion
:
apiextensions.k8s.io/v1alpha1
kind
:
CustomResource
kind
:
CustomResource
Definition
metadata
:
metadata
:
name
:
noxus.mygroup.example.com
name
:
noxus.mygroup.example.com
spec
:
spec
:
...
...
staging/src/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/BUILD
View file @
cb604f75
...
@@ -11,6 +11,7 @@ go_library(
...
@@ -11,6 +11,7 @@ go_library(
name = "go_default_library",
name = "go_default_library",
srcs = [
srcs = [
"doc.go",
"doc.go",
"helpers.go",
"register.go",
"register.go",
"types.go",
"types.go",
"zz_generated.deepcopy.go",
"zz_generated.deepcopy.go",
...
...
staging/src/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/helpers.go
0 → 100644
View file @
cb604f75
/*
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
apiextensions
// SetCRDCondition sets the status condition. It either overwrites the existing one or
// creates a new one
func
SetCRDCondition
(
customResourceDefinition
*
CustomResourceDefinition
,
newCondition
CustomResourceDefinitionCondition
)
{
existingCondition
:=
FindCRDCondition
(
customResourceDefinition
,
newCondition
.
Type
)
if
existingCondition
==
nil
{
customResourceDefinition
.
Status
.
Conditions
=
append
(
customResourceDefinition
.
Status
.
Conditions
,
newCondition
)
return
}
if
existingCondition
.
Status
!=
newCondition
.
Status
{
existingCondition
.
Status
=
newCondition
.
Status
existingCondition
.
LastTransitionTime
=
newCondition
.
LastTransitionTime
}
existingCondition
.
Reason
=
newCondition
.
Reason
existingCondition
.
Message
=
newCondition
.
Message
}
// FindCRDCondition returns the condition you're looking for or nil
func
FindCRDCondition
(
customResourceDefinition
*
CustomResourceDefinition
,
conditionType
CustomResourceDefinitionConditionType
)
*
CustomResourceDefinitionCondition
{
for
i
:=
range
customResourceDefinition
.
Status
.
Conditions
{
if
customResourceDefinition
.
Status
.
Conditions
[
i
]
.
Type
==
conditionType
{
return
&
customResourceDefinition
.
Status
.
Conditions
[
i
]
}
}
return
nil
}
// IsCRDConditionTrue indicates if the condition is present and strictly true
func
IsCRDConditionTrue
(
customResourceDefinition
*
CustomResourceDefinition
,
conditionType
CustomResourceDefinitionConditionType
)
bool
{
return
IsCRDConditionPresentAndEqual
(
customResourceDefinition
,
conditionType
,
ConditionTrue
)
}
// IsCRDConditionFalse indicates if the condition is present and false true
func
IsCRDConditionFalse
(
customResourceDefinition
*
CustomResourceDefinition
,
conditionType
CustomResourceDefinitionConditionType
)
bool
{
return
IsCRDConditionPresentAndEqual
(
customResourceDefinition
,
conditionType
,
ConditionFalse
)
}
// IsCRDConditionPresentAndEqual indicates if the condition is present and equal to the arg
func
IsCRDConditionPresentAndEqual
(
customResourceDefinition
*
CustomResourceDefinition
,
conditionType
CustomResourceDefinitionConditionType
,
status
ConditionStatus
)
bool
{
for
_
,
condition
:=
range
customResourceDefinition
.
Status
.
Conditions
{
if
condition
.
Type
==
conditionType
{
return
condition
.
Status
==
status
}
}
return
false
}
// IsCRDConditionEquivalent returns true if the lhs and rhs are equivalent except for times
func
IsCRDConditionEquivalent
(
lhs
,
rhs
*
CustomResourceDefinitionCondition
)
bool
{
if
lhs
==
nil
&&
rhs
==
nil
{
return
true
}
if
lhs
==
nil
||
rhs
==
nil
{
return
false
}
return
lhs
.
Message
==
rhs
.
Message
&&
lhs
.
Reason
==
rhs
.
Reason
&&
lhs
.
Status
==
rhs
.
Status
&&
lhs
.
Type
==
rhs
.
Type
}
staging/src/k8s.io/kube-apiextensions-server/pkg/apiserver/BUILD
View file @
cb604f75
...
@@ -54,6 +54,7 @@ go_library(
...
@@ -54,6 +54,7 @@ go_library(
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/listers/apiextensions/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/listers/apiextensions/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/controller/status:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/registry/customresource:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/registry/customresource:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/registry/customresourcedefinition:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/registry/customresourcedefinition:go_default_library",
],
],
...
...
staging/src/k8s.io/kube-apiextensions-server/pkg/apiserver/apiserver.go
View file @
cb604f75
...
@@ -37,6 +37,7 @@ import (
...
@@ -37,6 +37,7 @@ import (
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/v1alpha1"
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/v1alpha1"
"k8s.io/kube-apiextensions-server/pkg/client/clientset/internalclientset"
"k8s.io/kube-apiextensions-server/pkg/client/clientset/internalclientset"
internalinformers
"k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion"
internalinformers
"k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion"
"k8s.io/kube-apiextensions-server/pkg/controller/status"
"k8s.io/kube-apiextensions-server/pkg/registry/customresourcedefinition"
"k8s.io/kube-apiextensions-server/pkg/registry/customresourcedefinition"
// make sure the generated client works
// make sure the generated client works
...
@@ -113,8 +114,10 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
...
@@ -113,8 +114,10 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
apiGroupInfo
:=
genericapiserver
.
NewDefaultAPIGroupInfo
(
apiextensions
.
GroupName
,
registry
,
Scheme
,
metav1
.
ParameterCodec
,
Codecs
)
apiGroupInfo
:=
genericapiserver
.
NewDefaultAPIGroupInfo
(
apiextensions
.
GroupName
,
registry
,
Scheme
,
metav1
.
ParameterCodec
,
Codecs
)
apiGroupInfo
.
GroupMeta
.
GroupVersion
=
v1alpha1
.
SchemeGroupVersion
apiGroupInfo
.
GroupMeta
.
GroupVersion
=
v1alpha1
.
SchemeGroupVersion
customResourceDefintionStorage
:=
customresourcedefinition
.
NewREST
(
Scheme
,
c
.
GenericConfig
.
RESTOptionsGetter
)
v1alpha1storage
:=
map
[
string
]
rest
.
Storage
{}
v1alpha1storage
:=
map
[
string
]
rest
.
Storage
{}
v1alpha1storage
[
"customresourcedefinitions"
]
=
customresourcedefinition
.
NewREST
(
Scheme
,
c
.
GenericConfig
.
RESTOptionsGetter
)
v1alpha1storage
[
"customresourcedefinitions"
]
=
customResourceDefintionStorage
v1alpha1storage
[
"customresourcedefinitions/status"
]
=
customresourcedefinition
.
NewStatusREST
(
Scheme
,
customResourceDefintionStorage
)
apiGroupInfo
.
VersionedResourcesStorageMap
[
"v1alpha1"
]
=
v1alpha1storage
apiGroupInfo
.
VersionedResourcesStorageMap
[
"v1alpha1"
]
=
v1alpha1storage
if
err
:=
s
.
GenericAPIServer
.
InstallAPIGroup
(
&
apiGroupInfo
);
err
!=
nil
{
if
err
:=
s
.
GenericAPIServer
.
InstallAPIGroup
(
&
apiGroupInfo
);
err
!=
nil
{
...
@@ -153,6 +156,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
...
@@ -153,6 +156,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
s
.
GenericAPIServer
.
Handler
.
PostGoRestfulMux
.
HandlePrefix
(
"/apis/"
,
customResourceDefinitionHandler
)
s
.
GenericAPIServer
.
Handler
.
PostGoRestfulMux
.
HandlePrefix
(
"/apis/"
,
customResourceDefinitionHandler
)
customResourceDefinitionController
:=
NewDiscoveryController
(
customResourceDefinitionInformers
.
Apiextensions
()
.
InternalVersion
()
.
CustomResourceDefinitions
(),
versionDiscoveryHandler
,
groupDiscoveryHandler
)
customResourceDefinitionController
:=
NewDiscoveryController
(
customResourceDefinitionInformers
.
Apiextensions
()
.
InternalVersion
()
.
CustomResourceDefinitions
(),
versionDiscoveryHandler
,
groupDiscoveryHandler
)
namingController
:=
status
.
NewNamingConditionController
(
customResourceDefinitionInformers
.
Apiextensions
()
.
InternalVersion
()
.
CustomResourceDefinitions
(),
customResourceDefinitionClient
)
s
.
GenericAPIServer
.
AddPostStartHook
(
"start-apiextensions-informers"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
s
.
GenericAPIServer
.
AddPostStartHook
(
"start-apiextensions-informers"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
customResourceDefinitionInformers
.
Start
(
context
.
StopCh
)
customResourceDefinitionInformers
.
Start
(
context
.
StopCh
)
...
@@ -160,6 +164,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
...
@@ -160,6 +164,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
})
})
s
.
GenericAPIServer
.
AddPostStartHook
(
"start-apiextensions-controllers"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
s
.
GenericAPIServer
.
AddPostStartHook
(
"start-apiextensions-controllers"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
go
customResourceDefinitionController
.
Run
(
context
.
StopCh
)
go
customResourceDefinitionController
.
Run
(
context
.
StopCh
)
go
namingController
.
Run
(
context
.
StopCh
)
return
nil
return
nil
})
})
...
...
staging/src/k8s.io/kube-apiextensions-server/pkg/apiserver/customresource_discovery_controller.go
View file @
cb604f75
...
@@ -40,8 +40,8 @@ type DiscoveryController struct {
...
@@ -40,8 +40,8 @@ type DiscoveryController struct {
versionHandler
*
versionDiscoveryHandler
versionHandler
*
versionDiscoveryHandler
groupHandler
*
groupDiscoveryHandler
groupHandler
*
groupDiscoveryHandler
c
ustomResourceDefinition
Lister
listers
.
CustomResourceDefinitionLister
c
rd
Lister
listers
.
CustomResourceDefinitionLister
c
ustomResourceDefinition
sSynced
cache
.
InformerSynced
c
rd
sSynced
cache
.
InformerSynced
// To allow injection for testing.
// To allow injection for testing.
syncFn
func
(
version
schema
.
GroupVersion
)
error
syncFn
func
(
version
schema
.
GroupVersion
)
error
...
@@ -49,17 +49,17 @@ type DiscoveryController struct {
...
@@ -49,17 +49,17 @@ type DiscoveryController struct {
queue
workqueue
.
RateLimitingInterface
queue
workqueue
.
RateLimitingInterface
}
}
func
NewDiscoveryController
(
c
ustomResourceDefinition
Informer
informers
.
CustomResourceDefinitionInformer
,
versionHandler
*
versionDiscoveryHandler
,
groupHandler
*
groupDiscoveryHandler
)
*
DiscoveryController
{
func
NewDiscoveryController
(
c
rd
Informer
informers
.
CustomResourceDefinitionInformer
,
versionHandler
*
versionDiscoveryHandler
,
groupHandler
*
groupDiscoveryHandler
)
*
DiscoveryController
{
c
:=
&
DiscoveryController
{
c
:=
&
DiscoveryController
{
versionHandler
:
versionHandler
,
versionHandler
:
versionHandler
,
groupHandler
:
groupHandler
,
groupHandler
:
groupHandler
,
c
ustomResourceDefinitionLister
:
customResourceDefinition
Informer
.
Lister
(),
c
rdLister
:
crd
Informer
.
Lister
(),
c
ustomResourceDefinitionsSynced
:
customResourceDefinition
Informer
.
Informer
()
.
HasSynced
,
c
rdsSynced
:
crd
Informer
.
Informer
()
.
HasSynced
,
queue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"DiscoveryController"
),
queue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"DiscoveryController"
),
}
}
c
ustomResourceDefinition
Informer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
c
rd
Informer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
c
.
addCustomResourceDefinition
,
AddFunc
:
c
.
addCustomResourceDefinition
,
UpdateFunc
:
c
.
updateCustomResourceDefinition
,
UpdateFunc
:
c
.
updateCustomResourceDefinition
,
DeleteFunc
:
c
.
deleteCustomResourceDefinition
,
DeleteFunc
:
c
.
deleteCustomResourceDefinition
,
...
@@ -75,36 +75,39 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
...
@@ -75,36 +75,39 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
apiVersionsForDiscovery
:=
[]
metav1
.
GroupVersionForDiscovery
{}
apiVersionsForDiscovery
:=
[]
metav1
.
GroupVersionForDiscovery
{}
apiResourcesForDiscovery
:=
[]
metav1
.
APIResource
{}
apiResourcesForDiscovery
:=
[]
metav1
.
APIResource
{}
c
ustomResourceDefinitions
,
err
:=
c
.
customResourceDefinition
Lister
.
List
(
labels
.
Everything
())
c
rds
,
err
:=
c
.
crd
Lister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
foundVersion
:=
false
foundVersion
:=
false
foundGroup
:=
false
foundGroup
:=
false
for
_
,
customResourceDefinition
:=
range
customResourceDefinitions
{
for
_
,
crd
:=
range
crds
{
// TODO add status checking
// if we can't definitively determine that our names are good, don't serve it
if
!
apiextensions
.
IsCRDConditionFalse
(
crd
,
apiextensions
.
NameConflict
)
{
continue
}
if
c
ustomResourceDefinition
.
Spec
.
Group
!=
version
.
Group
{
if
c
rd
.
Spec
.
Group
!=
version
.
Group
{
continue
continue
}
}
foundGroup
=
true
foundGroup
=
true
apiVersionsForDiscovery
=
append
(
apiVersionsForDiscovery
,
metav1
.
GroupVersionForDiscovery
{
apiVersionsForDiscovery
=
append
(
apiVersionsForDiscovery
,
metav1
.
GroupVersionForDiscovery
{
GroupVersion
:
c
ustomResourceDefinition
.
Spec
.
Group
+
"/"
+
customResourceDefinition
.
Spec
.
Version
,
GroupVersion
:
c
rd
.
Spec
.
Group
+
"/"
+
crd
.
Spec
.
Version
,
Version
:
c
ustomResourceDefinition
.
Spec
.
Version
,
Version
:
c
rd
.
Spec
.
Version
,
})
})
if
c
ustomResourceDefinition
.
Spec
.
Version
!=
version
.
Version
{
if
c
rd
.
Spec
.
Version
!=
version
.
Version
{
continue
continue
}
}
foundVersion
=
true
foundVersion
=
true
apiResourcesForDiscovery
=
append
(
apiResourcesForDiscovery
,
metav1
.
APIResource
{
apiResourcesForDiscovery
=
append
(
apiResourcesForDiscovery
,
metav1
.
APIResource
{
Name
:
c
ustomResourceDefinition
.
Spec
.
Names
.
Plural
,
Name
:
c
rd
.
Status
.
Accepted
Names
.
Plural
,
SingularName
:
c
ustomResourceDefinition
.
Spec
.
Names
.
Singular
,
SingularName
:
c
rd
.
Status
.
Accepted
Names
.
Singular
,
Namespaced
:
c
ustomResourceDefinition
.
Spec
.
Scope
==
apiextensions
.
NamespaceScoped
,
Namespaced
:
c
rd
.
Spec
.
Scope
==
apiextensions
.
NamespaceScoped
,
Kind
:
c
ustomResourceDefinition
.
Spec
.
Names
.
Kind
,
Kind
:
c
rd
.
Status
.
Accepted
Names
.
Kind
,
Verbs
:
metav1
.
Verbs
([]
string
{
"delete"
,
"deletecollection"
,
"get"
,
"list"
,
"patch"
,
"create"
,
"update"
,
"watch"
}),
Verbs
:
metav1
.
Verbs
([]
string
{
"delete"
,
"deletecollection"
,
"get"
,
"list"
,
"patch"
,
"create"
,
"update"
,
"watch"
}),
ShortNames
:
c
ustomResourceDefinition
.
Spec
.
Names
.
ShortNames
,
ShortNames
:
c
rd
.
Status
.
Accepted
Names
.
ShortNames
,
})
})
}
}
...
@@ -140,7 +143,7 @@ func (c *DiscoveryController) Run(stopCh <-chan struct{}) {
...
@@ -140,7 +143,7 @@ func (c *DiscoveryController) Run(stopCh <-chan struct{}) {
glog
.
Infof
(
"Starting DiscoveryController"
)
glog
.
Infof
(
"Starting DiscoveryController"
)
if
!
cache
.
WaitForCacheSync
(
stopCh
,
c
.
c
ustomResourceDefinition
sSynced
)
{
if
!
cache
.
WaitForCacheSync
(
stopCh
,
c
.
c
rd
sSynced
)
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"timed out waiting for caches to sync"
))
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"timed out waiting for caches to sync"
))
return
return
}
}
...
...
staging/src/k8s.io/kube-apiextensions-server/pkg/apiserver/customresource_handler.go
View file @
cb604f75
...
@@ -48,58 +48,58 @@ import (
...
@@ -48,58 +48,58 @@ import (
"k8s.io/kube-apiextensions-server/pkg/registry/customresource"
"k8s.io/kube-apiextensions-server/pkg/registry/customresource"
)
)
// c
ustomResourceDefinition
Handler serves the `/apis` endpoint.
// c
rd
Handler serves the `/apis` endpoint.
// This is registered as a filter so that it never collides with any explictly registered endpoints
// This is registered as a filter so that it never collides with any explictly registered endpoints
type
c
ustomResourceDefinition
Handler
struct
{
type
c
rd
Handler
struct
{
versionDiscoveryHandler
*
versionDiscoveryHandler
versionDiscoveryHandler
*
versionDiscoveryHandler
groupDiscoveryHandler
*
groupDiscoveryHandler
groupDiscoveryHandler
*
groupDiscoveryHandler
customStorageLock
sync
.
Mutex
customStorageLock
sync
.
Mutex
// customStorage contains a c
ustomResourceDefinition
StorageMap
// customStorage contains a c
rd
StorageMap
customStorage
atomic
.
Value
customStorage
atomic
.
Value
requestContextMapper
apirequest
.
RequestContextMapper
requestContextMapper
apirequest
.
RequestContextMapper
c
ustomResourceDefinition
Lister
listers
.
CustomResourceDefinitionLister
c
rd
Lister
listers
.
CustomResourceDefinitionLister
delegate
http
.
Handler
delegate
http
.
Handler
restOptionsGetter
generic
.
RESTOptionsGetter
restOptionsGetter
generic
.
RESTOptionsGetter
admission
admission
.
Interface
admission
admission
.
Interface
}
}
// c
ustomResourceDefinition
Info stores enough information to serve the storage for the custom resource
// c
rd
Info stores enough information to serve the storage for the custom resource
type
c
ustomResourceDefinition
Info
struct
{
type
c
rd
Info
struct
{
storage
*
customresource
.
REST
storage
*
customresource
.
REST
requestScope
handlers
.
RequestScope
requestScope
handlers
.
RequestScope
}
}
// c
ustomResourceDefinition
StorageMap goes from customresourcedefinition to its storage
// c
rd
StorageMap goes from customresourcedefinition to its storage
type
c
ustomResourceDefinitionStorageMap
map
[
types
.
UID
]
*
customResourceDefinition
Info
type
c
rdStorageMap
map
[
types
.
UID
]
*
crd
Info
func
NewCustomResourceDefinitionHandler
(
func
NewCustomResourceDefinitionHandler
(
versionDiscoveryHandler
*
versionDiscoveryHandler
,
versionDiscoveryHandler
*
versionDiscoveryHandler
,
groupDiscoveryHandler
*
groupDiscoveryHandler
,
groupDiscoveryHandler
*
groupDiscoveryHandler
,
requestContextMapper
apirequest
.
RequestContextMapper
,
requestContextMapper
apirequest
.
RequestContextMapper
,
c
ustomResourceDefinition
Lister
listers
.
CustomResourceDefinitionLister
,
c
rd
Lister
listers
.
CustomResourceDefinitionLister
,
delegate
http
.
Handler
,
delegate
http
.
Handler
,
restOptionsGetter
generic
.
RESTOptionsGetter
,
restOptionsGetter
generic
.
RESTOptionsGetter
,
admission
admission
.
Interface
)
*
c
ustomResourceDefinition
Handler
{
admission
admission
.
Interface
)
*
c
rd
Handler
{
ret
:=
&
c
ustomResourceDefinition
Handler
{
ret
:=
&
c
rd
Handler
{
versionDiscoveryHandler
:
versionDiscoveryHandler
,
versionDiscoveryHandler
:
versionDiscoveryHandler
,
groupDiscoveryHandler
:
groupDiscoveryHandler
,
groupDiscoveryHandler
:
groupDiscoveryHandler
,
customStorage
:
atomic
.
Value
{},
customStorage
:
atomic
.
Value
{},
requestContextMapper
:
requestContextMapper
,
requestContextMapper
:
requestContextMapper
,
c
ustomResourceDefinitionLister
:
customResourceDefinition
Lister
,
c
rdLister
:
crd
Lister
,
delegate
:
delegate
,
delegate
:
delegate
,
restOptionsGetter
:
restOptionsGetter
,
restOptionsGetter
:
restOptionsGetter
,
admission
:
admission
,
admission
:
admission
,
}
}
ret
.
customStorage
.
Store
(
c
ustomResourceDefinition
StorageMap
{})
ret
.
customStorage
.
Store
(
c
rd
StorageMap
{})
return
ret
return
ret
}
}
func
(
r
*
c
ustomResourceDefinition
Handler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
(
r
*
c
rd
Handler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
ctx
,
ok
:=
r
.
requestContextMapper
.
Get
(
req
)
ctx
,
ok
:=
r
.
requestContextMapper
.
Get
(
req
)
if
!
ok
{
if
!
ok
{
// programmer error
// programmer error
...
@@ -134,8 +134,8 @@ func (r *customResourceDefinitionHandler) ServeHTTP(w http.ResponseWriter, req *
...
@@ -134,8 +134,8 @@ func (r *customResourceDefinitionHandler) ServeHTTP(w http.ResponseWriter, req *
return
return
}
}
c
ustomResourceDefinition
Name
:=
requestInfo
.
Resource
+
"."
+
requestInfo
.
APIGroup
c
rd
Name
:=
requestInfo
.
Resource
+
"."
+
requestInfo
.
APIGroup
c
ustomResourceDefinition
,
err
:=
r
.
customResourceDefinitionLister
.
Get
(
customResourceDefinition
Name
)
c
rd
,
err
:=
r
.
crdLister
.
Get
(
crd
Name
)
if
apierrors
.
IsNotFound
(
err
)
{
if
apierrors
.
IsNotFound
(
err
)
{
r
.
delegate
.
ServeHTTP
(
w
,
req
)
r
.
delegate
.
ServeHTTP
(
w
,
req
)
return
return
...
@@ -144,15 +144,18 @@ func (r *customResourceDefinitionHandler) ServeHTTP(w http.ResponseWriter, req *
...
@@ -144,15 +144,18 @@ func (r *customResourceDefinitionHandler) ServeHTTP(w http.ResponseWriter, req *
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
return
}
}
if
c
ustomResourceDefinition
.
Spec
.
Version
!=
requestInfo
.
APIVersion
{
if
c
rd
.
Spec
.
Version
!=
requestInfo
.
APIVersion
{
r
.
delegate
.
ServeHTTP
(
w
,
req
)
r
.
delegate
.
ServeHTTP
(
w
,
req
)
return
return
}
}
// TODO this is the point to do the condition checks
// if we can't definitively determine that our names are good, delegate
if
!
apiextensions
.
IsCRDConditionFalse
(
crd
,
apiextensions
.
NameConflict
)
{
r
.
delegate
.
ServeHTTP
(
w
,
req
)
}
c
ustomResourceDefinitionInfo
:=
r
.
getServingInfoFor
(
customResourceDefinition
)
c
rdInfo
:=
r
.
getServingInfoFor
(
crd
)
storage
:=
c
ustomResourceDefinition
Info
.
storage
storage
:=
c
rd
Info
.
storage
requestScope
:=
c
ustomResourceDefinition
Info
.
requestScope
requestScope
:=
c
rd
Info
.
requestScope
minRequestTimeout
:=
1
*
time
.
Minute
minRequestTimeout
:=
1
*
time
.
Minute
switch
requestInfo
.
Verb
{
switch
requestInfo
.
Verb
{
...
@@ -195,12 +198,12 @@ func (r *customResourceDefinitionHandler) ServeHTTP(w http.ResponseWriter, req *
...
@@ -195,12 +198,12 @@ func (r *customResourceDefinitionHandler) ServeHTTP(w http.ResponseWriter, req *
}
}
// removeDeadStorage removes REST storage that isn't being used
// removeDeadStorage removes REST storage that isn't being used
func
(
r
*
c
ustomResourceDefinition
Handler
)
removeDeadStorage
()
{
func
(
r
*
c
rd
Handler
)
removeDeadStorage
()
{
// these don't have to be live. A snapshot is fine
// these don't have to be live. A snapshot is fine
// if we wrongly delete, that's ok. The rest storage will be recreated on the next request
// if we wrongly delete, that's ok. The rest storage will be recreated on the next request
// if we wrongly miss one, that's ok. We'll get it next time
// if we wrongly miss one, that's ok. We'll get it next time
storageMap
:=
r
.
customStorage
.
Load
()
.
(
c
ustomResourceDefinition
StorageMap
)
storageMap
:=
r
.
customStorage
.
Load
()
.
(
c
rd
StorageMap
)
allCustomResourceDefinitions
,
err
:=
r
.
c
ustomResourceDefinition
Lister
.
List
(
labels
.
Everything
())
allCustomResourceDefinitions
,
err
:=
r
.
c
rd
Lister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
if
err
!=
nil
{
utilruntime
.
HandleError
(
err
)
utilruntime
.
HandleError
(
err
)
return
return
...
@@ -208,8 +211,8 @@ func (r *customResourceDefinitionHandler) removeDeadStorage() {
...
@@ -208,8 +211,8 @@ func (r *customResourceDefinitionHandler) removeDeadStorage() {
for
uid
:=
range
storageMap
{
for
uid
:=
range
storageMap
{
found
:=
false
found
:=
false
for
_
,
c
ustomResourceDefinition
:=
range
allCustomResourceDefinitions
{
for
_
,
c
rd
:=
range
allCustomResourceDefinitions
{
if
c
ustomResourceDefinition
.
UID
==
uid
{
if
c
rd
.
UID
==
uid
{
found
=
true
found
=
true
break
break
}
}
...
@@ -225,9 +228,9 @@ func (r *customResourceDefinitionHandler) removeDeadStorage() {
...
@@ -225,9 +228,9 @@ func (r *customResourceDefinitionHandler) removeDeadStorage() {
r
.
customStorage
.
Store
(
storageMap
)
r
.
customStorage
.
Store
(
storageMap
)
}
}
func
(
r
*
c
ustomResourceDefinitionHandler
)
getServingInfoFor
(
customResourceDefinition
*
apiextensions
.
CustomResourceDefinition
)
*
customResourceDefinition
Info
{
func
(
r
*
c
rdHandler
)
getServingInfoFor
(
crd
*
apiextensions
.
CustomResourceDefinition
)
*
crd
Info
{
storageMap
:=
r
.
customStorage
.
Load
()
.
(
c
ustomResourceDefinition
StorageMap
)
storageMap
:=
r
.
customStorage
.
Load
()
.
(
c
rd
StorageMap
)
ret
,
ok
:=
storageMap
[
c
ustomResourceDefinition
.
UID
]
ret
,
ok
:=
storageMap
[
c
rd
.
UID
]
if
ok
{
if
ok
{
return
ret
return
ret
}
}
...
@@ -235,21 +238,21 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
...
@@ -235,21 +238,21 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
r
.
customStorageLock
.
Lock
()
r
.
customStorageLock
.
Lock
()
defer
r
.
customStorageLock
.
Unlock
()
defer
r
.
customStorageLock
.
Unlock
()
ret
,
ok
=
storageMap
[
c
ustomResourceDefinition
.
UID
]
ret
,
ok
=
storageMap
[
c
rd
.
UID
]
if
ok
{
if
ok
{
return
ret
return
ret
}
}
storage
:=
customresource
.
NewREST
(
storage
:=
customresource
.
NewREST
(
schema
.
GroupResource
{
Group
:
c
ustomResourceDefinition
.
Spec
.
Group
,
Resource
:
customResourceDefinition
.
Spec
.
Names
.
Plural
},
schema
.
GroupResource
{
Group
:
c
rd
.
Spec
.
Group
,
Resource
:
crd
.
Spec
.
Names
.
Plural
},
schema
.
GroupVersionKind
{
Group
:
c
ustomResourceDefinition
.
Spec
.
Group
,
Version
:
customResourceDefinition
.
Spec
.
Version
,
Kind
:
customResourceDefinition
.
Spec
.
Names
.
ListKind
},
schema
.
GroupVersionKind
{
Group
:
c
rd
.
Spec
.
Group
,
Version
:
crd
.
Spec
.
Version
,
Kind
:
crd
.
Spec
.
Names
.
ListKind
},
UnstructuredCopier
{},
UnstructuredCopier
{},
customresource
.
NewStrategy
(
discovery
.
NewUnstructuredObjectTyper
(
nil
),
c
ustomResourceDefinition
.
Spec
.
Scope
==
apiextensions
.
NamespaceScoped
),
customresource
.
NewStrategy
(
discovery
.
NewUnstructuredObjectTyper
(
nil
),
c
rd
.
Spec
.
Scope
==
apiextensions
.
NamespaceScoped
),
r
.
restOptionsGetter
,
r
.
restOptionsGetter
,
)
)
parameterScheme
:=
runtime
.
NewScheme
()
parameterScheme
:=
runtime
.
NewScheme
()
parameterScheme
.
AddUnversionedTypes
(
schema
.
GroupVersion
{
Group
:
c
ustomResourceDefinition
.
Spec
.
Group
,
Version
:
customResourceDefinition
.
Spec
.
Version
},
parameterScheme
.
AddUnversionedTypes
(
schema
.
GroupVersion
{
Group
:
c
rd
.
Spec
.
Group
,
Version
:
crd
.
Spec
.
Version
},
&
metav1
.
ListOptions
{},
&
metav1
.
ListOptions
{},
&
metav1
.
ExportOptions
{},
&
metav1
.
ExportOptions
{},
&
metav1
.
GetOptions
{},
&
metav1
.
GetOptions
{},
...
@@ -259,11 +262,11 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
...
@@ -259,11 +262,11 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
parameterCodec
:=
runtime
.
NewParameterCodec
(
parameterScheme
)
parameterCodec
:=
runtime
.
NewParameterCodec
(
parameterScheme
)
selfLinkPrefix
:=
""
selfLinkPrefix
:=
""
switch
c
ustomResourceDefinition
.
Spec
.
Scope
{
switch
c
rd
.
Spec
.
Scope
{
case
apiextensions
.
ClusterScoped
:
case
apiextensions
.
ClusterScoped
:
selfLinkPrefix
=
"/"
+
path
.
Join
(
"apis"
,
c
ustomResourceDefinition
.
Spec
.
Group
,
customResourceDefinition
.
Spec
.
Version
)
+
"/"
selfLinkPrefix
=
"/"
+
path
.
Join
(
"apis"
,
c
rd
.
Spec
.
Group
,
crd
.
Spec
.
Version
)
+
"/"
case
apiextensions
.
NamespaceScoped
:
case
apiextensions
.
NamespaceScoped
:
selfLinkPrefix
=
"/"
+
path
.
Join
(
"apis"
,
c
ustomResourceDefinition
.
Spec
.
Group
,
customResourceDefinition
.
Spec
.
Version
,
"namespaces"
)
+
"/"
selfLinkPrefix
=
"/"
+
path
.
Join
(
"apis"
,
c
rd
.
Spec
.
Group
,
crd
.
Spec
.
Version
,
"namespaces"
)
+
"/"
}
}
requestScope
:=
handlers
.
RequestScope
{
requestScope
:=
handlers
.
RequestScope
{
...
@@ -273,7 +276,7 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
...
@@ -273,7 +276,7 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
return
ret
return
ret
},
},
SelfLinker
:
meta
.
NewAccessor
(),
SelfLinker
:
meta
.
NewAccessor
(),
ClusterScoped
:
c
ustomResourceDefinition
.
Spec
.
Scope
==
apiextensions
.
ClusterScoped
,
ClusterScoped
:
c
rd
.
Spec
.
Scope
==
apiextensions
.
ClusterScoped
,
SelfLinkPathPrefix
:
selfLinkPrefix
,
SelfLinkPathPrefix
:
selfLinkPrefix
,
},
},
ContextFunc
:
func
(
req
*
http
.
Request
)
apirequest
.
Context
{
ContextFunc
:
func
(
req
*
http
.
Request
)
apirequest
.
Context
{
...
@@ -291,18 +294,18 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
...
@@ -291,18 +294,18 @@ func (r *customResourceDefinitionHandler) getServingInfoFor(customResourceDefini
Typer
:
discovery
.
NewUnstructuredObjectTyper
(
nil
),
Typer
:
discovery
.
NewUnstructuredObjectTyper
(
nil
),
UnsafeConvertor
:
unstructured
.
UnstructuredObjectConverter
{},
UnsafeConvertor
:
unstructured
.
UnstructuredObjectConverter
{},
Resource
:
schema
.
GroupVersionResource
{
Group
:
c
ustomResourceDefinition
.
Spec
.
Group
,
Version
:
customResourceDefinition
.
Spec
.
Version
,
Resource
:
customResourceDefinition
.
Spec
.
Names
.
Plural
},
Resource
:
schema
.
GroupVersionResource
{
Group
:
c
rd
.
Spec
.
Group
,
Version
:
crd
.
Spec
.
Version
,
Resource
:
crd
.
Spec
.
Names
.
Plural
},
Kind
:
schema
.
GroupVersionKind
{
Group
:
c
ustomResourceDefinition
.
Spec
.
Group
,
Version
:
customResourceDefinition
.
Spec
.
Version
,
Kind
:
customResourceDefinition
.
Spec
.
Names
.
Kind
},
Kind
:
schema
.
GroupVersionKind
{
Group
:
c
rd
.
Spec
.
Group
,
Version
:
crd
.
Spec
.
Version
,
Kind
:
crd
.
Spec
.
Names
.
Kind
},
Subresource
:
""
,
Subresource
:
""
,
MetaGroupVersion
:
metav1
.
SchemeGroupVersion
,
MetaGroupVersion
:
metav1
.
SchemeGroupVersion
,
}
}
ret
=
&
c
ustomResourceDefinition
Info
{
ret
=
&
c
rd
Info
{
storage
:
storage
,
storage
:
storage
,
requestScope
:
requestScope
,
requestScope
:
requestScope
,
}
}
storageMap
[
c
ustomResourceDefinition
.
UID
]
=
ret
storageMap
[
c
rd
.
UID
]
=
ret
r
.
customStorage
.
Store
(
storageMap
)
r
.
customStorage
.
Store
(
storageMap
)
return
ret
return
ret
}
}
...
...
staging/src/k8s.io/kube-apiextensions-server/pkg/controller/status/BUILD
0 → 100644
View file @
cb604f75
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["naming_controller_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/listers/apiextensions/internalversion:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["naming_controller.go"],
tags = ["automanaged"],
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/client-go/util/workqueue:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion/apiextensions/internalversion:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/client/listers/apiextensions/internalversion:go_default_library",
],
)
staging/src/k8s.io/kube-apiextensions-server/pkg/controller/status/naming_controller.go
0 → 100644
View file @
cb604f75
/*
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
status
import
(
"fmt"
"reflect"
"time"
"github.com/golang/glog"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/labels"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions"
client
"k8s.io/kube-apiextensions-server/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion"
informers
"k8s.io/kube-apiextensions-server/pkg/client/informers/internalversion/apiextensions/internalversion"
listers
"k8s.io/kube-apiextensions-server/pkg/client/listers/apiextensions/internalversion"
)
var
cloner
=
conversion
.
NewCloner
()
// This controller is reserving names. To avoid conflicts, be sure to run only one instance of the worker at a time.
// This could eventually be lifted, but starting simple.
type
NamingConditionController
struct
{
crdClient
client
.
CustomResourceDefinitionsGetter
crdLister
listers
.
CustomResourceDefinitionLister
crdSynced
cache
.
InformerSynced
// crdMutationCache backs our lister and keeps track of committed updates to avoid racy
// write/lookup cycles. It's got 100 slots by default, so it unlikely to overrun
// TODO to revisit this if naming conflicts are found to occur in the wild
crdMutationCache
cache
.
MutationCache
// To allow injection for testing.
syncFn
func
(
key
string
)
error
queue
workqueue
.
RateLimitingInterface
}
func
NewNamingConditionController
(
crdInformer
informers
.
CustomResourceDefinitionInformer
,
crdClient
client
.
CustomResourceDefinitionsGetter
,
)
*
NamingConditionController
{
c
:=
&
NamingConditionController
{
crdClient
:
crdClient
,
crdLister
:
crdInformer
.
Lister
(),
crdSynced
:
crdInformer
.
Informer
()
.
HasSynced
,
queue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"CustomResourceDefinition-NamingConditionController"
),
}
informerIndexer
:=
crdInformer
.
Informer
()
.
GetIndexer
()
c
.
crdMutationCache
=
cache
.
NewIntegerResourceVersionMutationCache
(
informerIndexer
,
informerIndexer
)
crdInformer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
c
.
addCustomResourceDefinition
,
UpdateFunc
:
c
.
updateCustomResourceDefinition
,
DeleteFunc
:
c
.
deleteCustomResourceDefinition
,
})
c
.
syncFn
=
c
.
sync
return
c
}
func
(
c
*
NamingConditionController
)
getAcceptedNamesForGroup
(
group
string
)
(
allResources
sets
.
String
,
allKinds
sets
.
String
)
{
allResources
=
sets
.
String
{}
allKinds
=
sets
.
String
{}
list
,
err
:=
c
.
crdLister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
panic
(
err
)
}
for
_
,
curr
:=
range
list
{
if
curr
.
Spec
.
Group
!=
group
{
continue
}
// for each item here, see if we have a mutation cache entry that is more recent
// this makes sure that if we tight loop on update and run, our mutation cache will show
// us the version of the objects we just updated to.
item
:=
curr
obj
,
exists
,
err
:=
c
.
crdMutationCache
.
GetByKey
(
curr
.
Name
)
if
exists
&&
err
==
nil
{
item
=
obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
}
allResources
.
Insert
(
item
.
Status
.
AcceptedNames
.
Plural
)
allResources
.
Insert
(
item
.
Status
.
AcceptedNames
.
Singular
)
allResources
.
Insert
(
item
.
Status
.
AcceptedNames
.
ShortNames
...
)
allKinds
.
Insert
(
item
.
Status
.
AcceptedNames
.
Kind
)
allKinds
.
Insert
(
item
.
Status
.
AcceptedNames
.
ListKind
)
}
return
allResources
,
allKinds
}
func
(
c
*
NamingConditionController
)
calculateNames
(
in
*
apiextensions
.
CustomResourceDefinition
)
(
apiextensions
.
CustomResourceDefinitionNames
,
apiextensions
.
CustomResourceDefinitionCondition
)
{
// Get the names that have already been claimed
allResources
,
allKinds
:=
c
.
getAcceptedNamesForGroup
(
in
.
Spec
.
Group
)
condition
:=
apiextensions
.
CustomResourceDefinitionCondition
{
Type
:
apiextensions
.
NameConflict
,
Status
:
apiextensions
.
ConditionUnknown
,
}
requestedNames
:=
in
.
Spec
.
Names
acceptedNames
:=
in
.
Status
.
AcceptedNames
newNames
:=
in
.
Status
.
AcceptedNames
// Check each name for mismatches. If there's a mismatch between spec and status, then try to deconflict.
// Continue on errors so that the status is the best match possible
if
err
:=
equalToAcceptedOrFresh
(
requestedNames
.
Plural
,
acceptedNames
.
Plural
,
allResources
);
err
!=
nil
{
condition
.
Status
=
apiextensions
.
ConditionTrue
condition
.
Reason
=
"Plural"
condition
.
Message
=
err
.
Error
()
}
else
{
newNames
.
Plural
=
requestedNames
.
Plural
}
if
err
:=
equalToAcceptedOrFresh
(
requestedNames
.
Singular
,
acceptedNames
.
Singular
,
allResources
);
err
!=
nil
{
condition
.
Status
=
apiextensions
.
ConditionTrue
condition
.
Reason
=
"Singular"
condition
.
Message
=
err
.
Error
()
}
else
{
newNames
.
Singular
=
requestedNames
.
Singular
}
if
!
reflect
.
DeepEqual
(
requestedNames
.
ShortNames
,
acceptedNames
.
ShortNames
)
{
errs
:=
[]
error
{}
existingShortNames
:=
sets
.
NewString
(
acceptedNames
.
ShortNames
...
)
for
_
,
shortName
:=
range
requestedNames
.
ShortNames
{
// if the shortname is already ours, then we're fine
if
existingShortNames
.
Has
(
shortName
)
{
continue
}
if
err
:=
equalToAcceptedOrFresh
(
shortName
,
""
,
allResources
);
err
!=
nil
{
errs
=
append
(
errs
,
err
)
}
}
if
err
:=
utilerrors
.
NewAggregate
(
errs
);
err
!=
nil
{
condition
.
Status
=
apiextensions
.
ConditionTrue
condition
.
Reason
=
"ShortNames"
condition
.
Message
=
err
.
Error
()
}
else
{
newNames
.
ShortNames
=
requestedNames
.
ShortNames
}
}
if
err
:=
equalToAcceptedOrFresh
(
requestedNames
.
Kind
,
acceptedNames
.
Kind
,
allKinds
);
err
!=
nil
{
condition
.
Status
=
apiextensions
.
ConditionTrue
condition
.
Reason
=
"Kind"
condition
.
Message
=
err
.
Error
()
}
else
{
newNames
.
Kind
=
requestedNames
.
Kind
}
if
err
:=
equalToAcceptedOrFresh
(
requestedNames
.
ListKind
,
acceptedNames
.
ListKind
,
allKinds
);
err
!=
nil
{
condition
.
Status
=
apiextensions
.
ConditionTrue
condition
.
Reason
=
"ListKind"
condition
.
Message
=
err
.
Error
()
}
else
{
newNames
.
ListKind
=
requestedNames
.
ListKind
}
// if we haven't changed the condition, then our names must be good.
if
condition
.
Status
==
apiextensions
.
ConditionUnknown
{
condition
.
Status
=
apiextensions
.
ConditionFalse
condition
.
Reason
=
"NoConflicts"
condition
.
Message
=
"no conflicts found"
}
return
newNames
,
condition
}
func
equalToAcceptedOrFresh
(
requestedName
,
acceptedName
string
,
usedNames
sets
.
String
)
error
{
if
requestedName
==
acceptedName
{
return
nil
}
if
!
usedNames
.
Has
(
requestedName
)
{
return
nil
}
return
fmt
.
Errorf
(
"%q is already in use"
,
requestedName
)
}
func
(
c
*
NamingConditionController
)
sync
(
key
string
)
error
{
inCustomResourceDefinition
,
err
:=
c
.
crdLister
.
Get
(
key
)
if
apierrors
.
IsNotFound
(
err
)
{
return
nil
}
if
err
!=
nil
{
return
err
}
acceptedNames
,
namingCondition
:=
c
.
calculateNames
(
inCustomResourceDefinition
)
// nothing to do if accepted names and NameConflict condition didn't change
if
reflect
.
DeepEqual
(
inCustomResourceDefinition
.
Status
.
AcceptedNames
,
acceptedNames
)
&&
apiextensions
.
IsCRDConditionEquivalent
(
&
namingCondition
,
apiextensions
.
FindCRDCondition
(
inCustomResourceDefinition
,
apiextensions
.
NameConflict
))
{
return
nil
}
crd
:=
&
apiextensions
.
CustomResourceDefinition
{}
if
err
:=
apiextensions
.
DeepCopy_apiextensions_CustomResourceDefinition
(
inCustomResourceDefinition
,
crd
,
cloner
);
err
!=
nil
{
return
err
}
crd
.
Status
.
AcceptedNames
=
acceptedNames
apiextensions
.
SetCRDCondition
(
crd
,
namingCondition
)
updatedObj
,
err
:=
c
.
crdClient
.
CustomResourceDefinitions
()
.
UpdateStatus
(
crd
)
if
err
!=
nil
{
return
err
}
// if the update was successful, go ahead and add the entry to the mutation cache
c
.
crdMutationCache
.
Mutation
(
updatedObj
)
// we updated our status, so we may be releasing a name. When this happens, we need to rekick everything in our group
// if we fail to rekick, just return as normal. We'll get everything on a resync
list
,
err
:=
c
.
crdLister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
return
nil
}
for
_
,
curr
:=
range
list
{
if
curr
.
Spec
.
Group
==
crd
.
Spec
.
Group
{
c
.
queue
.
Add
(
curr
.
Name
)
}
}
return
nil
}
func
(
c
*
NamingConditionController
)
Run
(
stopCh
<-
chan
struct
{})
{
defer
utilruntime
.
HandleCrash
()
defer
c
.
queue
.
ShutDown
()
glog
.
Infof
(
"Starting NamingConditionController"
)
defer
glog
.
Infof
(
"Shutting down NamingConditionController"
)
if
!
cache
.
WaitForCacheSync
(
stopCh
,
c
.
crdSynced
)
{
return
}
// only start one worker thread since its a slow moving API and the naming conflict resolution bits aren't thread-safe
go
wait
.
Until
(
c
.
runWorker
,
time
.
Second
,
stopCh
)
<-
stopCh
}
func
(
c
*
NamingConditionController
)
runWorker
()
{
for
c
.
processNextWorkItem
()
{
}
}
// processNextWorkItem deals with one key off the queue. It returns false when it's time to quit.
func
(
c
*
NamingConditionController
)
processNextWorkItem
()
bool
{
key
,
quit
:=
c
.
queue
.
Get
()
if
quit
{
return
false
}
defer
c
.
queue
.
Done
(
key
)
err
:=
c
.
syncFn
(
key
.
(
string
))
if
err
==
nil
{
c
.
queue
.
Forget
(
key
)
return
true
}
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"%v failed with: %v"
,
key
,
err
))
c
.
queue
.
AddRateLimited
(
key
)
return
true
}
func
(
c
*
NamingConditionController
)
enqueue
(
obj
*
apiextensions
.
CustomResourceDefinition
)
{
key
,
err
:=
cache
.
DeletionHandlingMetaNamespaceKeyFunc
(
obj
)
if
err
!=
nil
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"Couldn't get key for object %#v: %v"
,
obj
,
err
))
return
}
c
.
queue
.
Add
(
key
)
}
func
(
c
*
NamingConditionController
)
addCustomResourceDefinition
(
obj
interface
{})
{
castObj
:=
obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
glog
.
V
(
4
)
.
Infof
(
"Adding %s"
,
castObj
.
Name
)
c
.
enqueue
(
castObj
)
}
func
(
c
*
NamingConditionController
)
updateCustomResourceDefinition
(
obj
,
_
interface
{})
{
castObj
:=
obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
glog
.
V
(
4
)
.
Infof
(
"Updating %s"
,
castObj
.
Name
)
c
.
enqueue
(
castObj
)
}
func
(
c
*
NamingConditionController
)
deleteCustomResourceDefinition
(
obj
interface
{})
{
castObj
,
ok
:=
obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
if
!
ok
{
tombstone
,
ok
:=
obj
.
(
cache
.
DeletedFinalStateUnknown
)
if
!
ok
{
glog
.
Errorf
(
"Couldn't get object from tombstone %#v"
,
obj
)
return
}
castObj
,
ok
=
tombstone
.
Obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
if
!
ok
{
glog
.
Errorf
(
"Tombstone contained object that is not expected %#v"
,
obj
)
return
}
}
glog
.
V
(
4
)
.
Infof
(
"Deleting %q"
,
castObj
.
Name
)
c
.
enqueue
(
castObj
)
}
staging/src/k8s.io/kube-apiextensions-server/pkg/controller/status/naming_controller_test.go
0 → 100644
View file @
cb604f75
/*
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
status
import
(
"reflect"
"strings"
"testing"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions"
listers
"k8s.io/kube-apiextensions-server/pkg/client/listers/apiextensions/internalversion"
)
type
crdBuilder
struct
{
curr
apiextensions
.
CustomResourceDefinition
}
func
newCRD
(
name
string
)
*
crdBuilder
{
tokens
:=
strings
.
SplitN
(
name
,
"."
,
2
)
return
&
crdBuilder
{
curr
:
apiextensions
.
CustomResourceDefinition
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
name
},
Spec
:
apiextensions
.
CustomResourceDefinitionSpec
{
Group
:
tokens
[
1
],
Names
:
apiextensions
.
CustomResourceDefinitionNames
{
Plural
:
tokens
[
0
],
},
},
},
}
}
func
(
b
*
crdBuilder
)
SpecNames
(
plural
,
singular
,
kind
,
listKind
string
,
shortNames
...
string
)
*
crdBuilder
{
b
.
curr
.
Spec
.
Names
.
Plural
=
plural
b
.
curr
.
Spec
.
Names
.
Singular
=
singular
b
.
curr
.
Spec
.
Names
.
Kind
=
kind
b
.
curr
.
Spec
.
Names
.
ListKind
=
listKind
b
.
curr
.
Spec
.
Names
.
ShortNames
=
shortNames
return
b
}
func
(
b
*
crdBuilder
)
StatusNames
(
plural
,
singular
,
kind
,
listKind
string
,
shortNames
...
string
)
*
crdBuilder
{
b
.
curr
.
Status
.
AcceptedNames
.
Plural
=
plural
b
.
curr
.
Status
.
AcceptedNames
.
Singular
=
singular
b
.
curr
.
Status
.
AcceptedNames
.
Kind
=
kind
b
.
curr
.
Status
.
AcceptedNames
.
ListKind
=
listKind
b
.
curr
.
Status
.
AcceptedNames
.
ShortNames
=
shortNames
return
b
}
func
names
(
plural
,
singular
,
kind
,
listKind
string
,
shortNames
...
string
)
apiextensions
.
CustomResourceDefinitionNames
{
ret
:=
apiextensions
.
CustomResourceDefinitionNames
{
Plural
:
plural
,
Singular
:
singular
,
Kind
:
kind
,
ListKind
:
listKind
,
ShortNames
:
shortNames
,
}
return
ret
}
func
(
b
*
crdBuilder
)
NewOrDie
()
*
apiextensions
.
CustomResourceDefinition
{
return
&
b
.
curr
}
var
goodCondition
=
apiextensions
.
CustomResourceDefinitionCondition
{
Type
:
apiextensions
.
NameConflict
,
Status
:
apiextensions
.
ConditionFalse
,
Reason
:
"NoConflicts"
,
Message
:
"no conflicts found"
,
}
func
badCondition
(
reason
,
message
string
)
apiextensions
.
CustomResourceDefinitionCondition
{
return
apiextensions
.
CustomResourceDefinitionCondition
{
Type
:
apiextensions
.
NameConflict
,
Status
:
apiextensions
.
ConditionTrue
,
Reason
:
reason
,
Message
:
message
,
}
}
func
TestSync
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
in
*
apiextensions
.
CustomResourceDefinition
existing
[]
*
apiextensions
.
CustomResourceDefinition
expectedNames
apiextensions
.
CustomResourceDefinitionNames
expectedCondition
apiextensions
.
CustomResourceDefinitionCondition
}{
{
name
:
"first resource"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{},
expectedNames
:
apiextensions
.
CustomResourceDefinitionNames
{
Plural
:
"alfa"
,
},
expectedCondition
:
goodCondition
,
},
{
name
:
"different groups"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"alfa.charlie.com"
)
.
StatusNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
goodCondition
,
},
{
name
:
"conflict plural to singular"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"alfa"
,
""
,
""
)
.
NewOrDie
(),
},
expectedNames
:
names
(
""
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
badCondition
(
"Plural"
,
`"alfa" is already in use`
),
},
{
name
:
"conflict singular to shortName"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"indias"
,
""
,
""
,
"delta-singular"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
""
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
badCondition
(
"Singular"
,
`"delta-singular" is already in use`
),
},
{
name
:
"conflict on shortName to shortName"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"indias"
,
""
,
""
,
"hotel-shortname-2"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
),
expectedCondition
:
badCondition
(
"ShortNames"
,
`"hotel-shortname-2" is already in use`
),
},
{
name
:
"conflict on kind to listkind"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"indias"
,
""
,
"echo-kind"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"delta-singular"
,
""
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
badCondition
(
"Kind"
,
`"echo-kind" is already in use`
),
},
{
name
:
"conflict on listkind to kind"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"indias"
,
"foxtrot-listkind"
,
""
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
""
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
badCondition
(
"ListKind"
,
`"foxtrot-listkind" is already in use`
),
},
{
name
:
"no conflict on resource and kind"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"echo-kind"
,
""
,
""
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
goodCondition
,
},
{
name
:
"merge on conflicts"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
StatusNames
(
"zulu"
,
"yankee-singular"
,
"xray-kind"
,
"whiskey-listkind"
,
"victor-shortname-1"
,
"uniform-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"indias"
,
"foxtrot-listkind"
,
""
,
"delta-singular"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"yankee-singular"
,
"echo-kind"
,
"whiskey-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
badCondition
(
"ListKind"
,
`"foxtrot-listkind" is already in use`
),
},
{
name
:
"merge on conflicts shortNames as one"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
StatusNames
(
"zulu"
,
"yankee-singular"
,
"xray-kind"
,
"whiskey-listkind"
,
"victor-shortname-1"
,
"uniform-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"india.bravo.com"
)
.
StatusNames
(
"india"
,
"indias"
,
"foxtrot-listkind"
,
""
,
"delta-singular"
,
"golf-shortname-1"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"yankee-singular"
,
"echo-kind"
,
"whiskey-listkind"
,
"victor-shortname-1"
,
"uniform-shortname-2"
),
expectedCondition
:
badCondition
(
"ListKind"
,
`"foxtrot-listkind" is already in use`
),
},
{
name
:
"no conflicts on self"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
StatusNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
StatusNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
),
expectedCondition
:
goodCondition
,
},
{
name
:
"no conflicts on self, remove shortname"
,
in
:
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
)
.
StatusNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
existing
:
[]
*
apiextensions
.
CustomResourceDefinition
{
newCRD
(
"alfa.bravo.com"
)
.
SpecNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
StatusNames
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
,
"hotel-shortname-2"
)
.
NewOrDie
(),
},
expectedNames
:
names
(
"alfa"
,
"delta-singular"
,
"echo-kind"
,
"foxtrot-listkind"
,
"golf-shortname-1"
),
expectedCondition
:
goodCondition
,
},
}
for
_
,
tc
:=
range
tests
{
crdIndexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
for
_
,
obj
:=
range
tc
.
existing
{
crdIndexer
.
Add
(
obj
)
}
c
:=
NamingConditionController
{
crdLister
:
listers
.
NewCustomResourceDefinitionLister
(
crdIndexer
),
crdMutationCache
:
cache
.
NewIntegerResourceVersionMutationCache
(
crdIndexer
,
crdIndexer
),
}
actualNames
,
actualCondition
:=
c
.
calculateNames
(
tc
.
in
)
if
e
,
a
:=
tc
.
expectedNames
,
actualNames
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"%v expected %v, got %#v"
,
tc
.
name
,
e
,
a
)
}
if
e
,
a
:=
tc
.
expectedCondition
,
actualCondition
;
!
apiextensions
.
IsCRDConditionEquivalent
(
&
e
,
&
a
)
{
t
.
Errorf
(
"%v expected %v, got %v"
,
tc
.
name
,
e
,
a
)
}
}
}
staging/src/k8s.io/kube-apiextensions-server/pkg/registry/customresourcedefinition/BUILD
View file @
cb604f75
...
@@ -22,6 +22,7 @@ go_library(
...
@@ -22,6 +22,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions:go_default_library",
"//vendor/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions:go_default_library",
...
...
staging/src/k8s.io/kube-apiextensions-server/pkg/registry/customresourcedefinition/etcd.go
View file @
cb604f75
...
@@ -18,8 +18,10 @@ package customresourcedefinition
...
@@ -18,8 +18,10 @@ package customresourcedefinition
import
(
import
(
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
genericapirequest
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/generic"
genericregistry
"k8s.io/apiserver/pkg/registry/generic/registry"
genericregistry
"k8s.io/apiserver/pkg/registry/generic/registry"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions"
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions"
)
)
...
@@ -52,3 +54,28 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST
...
@@ -52,3 +54,28 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST
}
}
return
&
REST
{
store
}
return
&
REST
{
store
}
}
}
// NewStatusREST makes a RESTStorage for status that has more limited options.
// It is based on the original REST so that we can share the same underlying store
func
NewStatusREST
(
scheme
*
runtime
.
Scheme
,
rest
*
REST
)
*
StatusREST
{
statusStore
:=
*
rest
.
Store
statusStore
.
CreateStrategy
=
nil
statusStore
.
DeleteStrategy
=
nil
statusStore
.
UpdateStrategy
=
NewStatusStrategy
(
scheme
)
return
&
StatusREST
{
store
:
&
statusStore
}
}
type
StatusREST
struct
{
store
*
genericregistry
.
Store
}
var
_
=
rest
.
Updater
(
&
StatusREST
{})
func
(
r
*
StatusREST
)
New
()
runtime
.
Object
{
return
&
apiextensions
.
CustomResourceDefinition
{}
}
// Update alters the status subset of an object.
func
(
r
*
StatusREST
)
Update
(
ctx
genericapirequest
.
Context
,
name
string
,
objInfo
rest
.
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
{
return
r
.
store
.
Update
(
ctx
,
name
,
objInfo
)
}
staging/src/k8s.io/kube-apiextensions-server/pkg/registry/customresourcedefinition/strategy.go
View file @
cb604f75
...
@@ -32,44 +32,82 @@ import (
...
@@ -32,44 +32,82 @@ import (
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/validation"
"k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/validation"
)
)
type
apiServerS
trategy
struct
{
type
s
trategy
struct
{
runtime
.
ObjectTyper
runtime
.
ObjectTyper
names
.
NameGenerator
names
.
NameGenerator
}
}
func
NewStrategy
(
typer
runtime
.
ObjectTyper
)
apiServerS
trategy
{
func
NewStrategy
(
typer
runtime
.
ObjectTyper
)
s
trategy
{
return
apiServerS
trategy
{
typer
,
names
.
SimpleNameGenerator
}
return
s
trategy
{
typer
,
names
.
SimpleNameGenerator
}
}
}
func
(
apiServerS
trategy
)
NamespaceScoped
()
bool
{
func
(
s
trategy
)
NamespaceScoped
()
bool
{
return
false
return
false
}
}
func
(
apiServerS
trategy
)
PrepareForCreate
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
)
{
func
(
s
trategy
)
PrepareForCreate
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
)
{
}
}
func
(
apiServerS
trategy
)
PrepareForUpdate
(
ctx
genericapirequest
.
Context
,
obj
,
old
runtime
.
Object
)
{
func
(
s
trategy
)
PrepareForUpdate
(
ctx
genericapirequest
.
Context
,
obj
,
old
runtime
.
Object
)
{
}
}
func
(
apiServerS
trategy
)
Validate
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
)
field
.
ErrorList
{
func
(
s
trategy
)
Validate
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
)
field
.
ErrorList
{
return
validation
.
ValidateCustomResourceDefinition
(
obj
.
(
*
apiextensions
.
CustomResourceDefinition
))
return
validation
.
ValidateCustomResourceDefinition
(
obj
.
(
*
apiextensions
.
CustomResourceDefinition
))
}
}
func
(
apiServerS
trategy
)
AllowCreateOnUpdate
()
bool
{
func
(
s
trategy
)
AllowCreateOnUpdate
()
bool
{
return
false
return
false
}
}
func
(
apiServerS
trategy
)
AllowUnconditionalUpdate
()
bool
{
func
(
s
trategy
)
AllowUnconditionalUpdate
()
bool
{
return
false
return
false
}
}
func
(
apiServerS
trategy
)
Canonicalize
(
obj
runtime
.
Object
)
{
func
(
s
trategy
)
Canonicalize
(
obj
runtime
.
Object
)
{
}
}
func
(
apiServerS
trategy
)
ValidateUpdate
(
ctx
genericapirequest
.
Context
,
obj
,
old
runtime
.
Object
)
field
.
ErrorList
{
func
(
s
trategy
)
ValidateUpdate
(
ctx
genericapirequest
.
Context
,
obj
,
old
runtime
.
Object
)
field
.
ErrorList
{
return
validation
.
ValidateCustomResourceDefinitionUpdate
(
obj
.
(
*
apiextensions
.
CustomResourceDefinition
),
old
.
(
*
apiextensions
.
CustomResourceDefinition
))
return
validation
.
ValidateCustomResourceDefinitionUpdate
(
obj
.
(
*
apiextensions
.
CustomResourceDefinition
),
old
.
(
*
apiextensions
.
CustomResourceDefinition
))
}
}
type
statusStrategy
struct
{
runtime
.
ObjectTyper
names
.
NameGenerator
}
func
NewStatusStrategy
(
typer
runtime
.
ObjectTyper
)
statusStrategy
{
return
statusStrategy
{
typer
,
names
.
SimpleNameGenerator
}
}
func
(
statusStrategy
)
NamespaceScoped
()
bool
{
return
false
}
func
(
statusStrategy
)
PrepareForUpdate
(
ctx
genericapirequest
.
Context
,
obj
,
old
runtime
.
Object
)
{
newObj
:=
obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
oldObj
:=
old
.
(
*
apiextensions
.
CustomResourceDefinition
)
newObj
.
Spec
=
oldObj
.
Spec
newObj
.
Labels
=
oldObj
.
Labels
newObj
.
Annotations
=
oldObj
.
Annotations
newObj
.
Finalizers
=
oldObj
.
Finalizers
newObj
.
OwnerReferences
=
oldObj
.
OwnerReferences
}
func
(
statusStrategy
)
AllowCreateOnUpdate
()
bool
{
return
false
}
func
(
statusStrategy
)
AllowUnconditionalUpdate
()
bool
{
return
false
}
func
(
statusStrategy
)
Canonicalize
(
obj
runtime
.
Object
)
{
}
func
(
statusStrategy
)
ValidateUpdate
(
ctx
genericapirequest
.
Context
,
obj
,
old
runtime
.
Object
)
field
.
ErrorList
{
return
validation
.
ValidateUpdateCustomResourceDefinitionStatus
(
obj
.
(
*
apiextensions
.
CustomResourceDefinition
),
old
.
(
*
apiextensions
.
CustomResourceDefinition
))
}
func
GetAttrs
(
obj
runtime
.
Object
)
(
labels
.
Set
,
fields
.
Set
,
error
)
{
func
GetAttrs
(
obj
runtime
.
Object
)
(
labels
.
Set
,
fields
.
Set
,
error
)
{
apiserver
,
ok
:=
obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
apiserver
,
ok
:=
obj
.
(
*
apiextensions
.
CustomResourceDefinition
)
if
!
ok
{
if
!
ok
{
...
...
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