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
091b843b
Commit
091b843b
authored
Sep 07, 2016
by
Marcin Wielgus
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Delete resources in federated namespce
parent
23147d30
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
103 additions
and
19 deletions
+103
-19
namespace_controller.go
...g/federation-controller/namespace/namespace_controller.go
+36
-12
namespace_controller_test.go
...eration-controller/namespace/namespace_controller_test.go
+67
-7
No files found.
federation/pkg/federation-controller/namespace/namespace_controller.go
View file @
091b843b
...
...
@@ -251,7 +251,12 @@ func (nc *NamespaceController) reconcileNamespace(namespace string) {
}
baseNamespace
:=
baseNamespaceObj
.
(
*
api_v1
.
Namespace
)
if
baseNamespace
.
DeletionTimestamp
!=
nil
{
nc
.
delete
(
baseNamespace
)
if
err
:=
nc
.
delete
(
baseNamespace
);
err
!=
nil
{
glog
.
Errorf
(
"Failed to delete %s: %v"
,
namespace
,
err
)
nc
.
eventRecorder
.
Eventf
(
baseNamespace
,
api
.
EventTypeNormal
,
"DeleteFailed"
,
"Namespace delete failed: %v"
,
err
)
nc
.
deliverNamespace
(
namespace
,
0
,
true
)
}
return
}
...
...
@@ -320,7 +325,8 @@ func (nc *NamespaceController) reconcileNamespace(namespace string) {
nc
.
deliverNamespace
(
namespace
,
nc
.
namespaceReviewDelay
,
false
)
}
func
(
nc
*
NamespaceController
)
delete
(
namespace
*
api_v1
.
Namespace
)
{
// delete deletes the given namespace or returns error if the deletion was not complete.
func
(
nc
*
NamespaceController
)
delete
(
namespace
*
api_v1
.
Namespace
)
error
{
// Set Terminating status.
updatedNamespace
:=
&
api_v1
.
Namespace
{
ObjectMeta
:
namespace
.
ObjectMeta
,
...
...
@@ -333,13 +339,33 @@ func (nc *NamespaceController) delete(namespace *api_v1.Namespace) {
nc
.
eventRecorder
.
Event
(
namespace
,
api
.
EventTypeNormal
,
"DeleteNamespace"
,
fmt
.
Sprintf
(
"Marking for deletion"
))
_
,
err
:=
nc
.
federatedApiClient
.
Core
()
.
Namespaces
()
.
Update
(
updatedNamespace
)
if
err
!=
nil
{
glog
.
Errorf
(
"Failed to update namespace %s: %v"
,
updatedNamespace
.
Name
,
err
)
nc
.
deliverNamespace
(
namespace
.
Name
,
0
,
true
)
return
return
fmt
.
Errorf
(
"failed to update namespace: %v"
,
err
)
}
}
// TODO: delete all namespace content.
// Right now there is just 5 types of objects: ReplicaSet, Secret, Ingress, Events and Service.
// Temporarly these items are simply deleted one by one to squeeze this code into 1.4.
// TODO: Make it generic (like in the regular namespace controller) and parallel.
err
:=
nc
.
federatedApiClient
.
Core
()
.
Services
(
namespace
.
Name
)
.
DeleteCollection
(
&
api
.
DeleteOptions
{},
api
.
ListOptions
{})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to delete service list: %v"
,
err
)
}
err
=
nc
.
federatedApiClient
.
Extensions
()
.
ReplicaSets
(
namespace
.
Name
)
.
DeleteCollection
(
&
api
.
DeleteOptions
{},
api
.
ListOptions
{})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to delete replicaset list from namespace: %v"
,
err
)
}
err
=
nc
.
federatedApiClient
.
Core
()
.
Secrets
(
namespace
.
Name
)
.
DeleteCollection
(
&
api
.
DeleteOptions
{},
api
.
ListOptions
{})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to delete secret list from namespace: %v"
,
err
)
}
err
=
nc
.
federatedApiClient
.
Extensions
()
.
Ingresses
(
namespace
.
Name
)
.
DeleteCollection
(
&
api
.
DeleteOptions
{},
api
.
ListOptions
{})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to delete ingresses list from namespace: %v"
,
err
)
}
err
=
nc
.
federatedApiClient
.
Core
()
.
Events
(
namespace
.
Name
)
.
DeleteCollection
(
&
api
.
DeleteOptions
{},
api
.
ListOptions
{})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to delete events list from namespace: %v"
,
err
)
}
// Remove kube_api.FinalzerKubernetes
if
len
(
updatedNamespace
.
Spec
.
Finalizers
)
!=
0
{
...
...
@@ -355,21 +381,19 @@ func (nc *NamespaceController) delete(namespace *api_v1.Namespace) {
}
_
,
err
:=
nc
.
federatedApiClient
.
Core
()
.
Namespaces
()
.
Finalize
(
updatedNamespace
)
if
err
!=
nil
{
glog
.
Errorf
(
"Failed to update namespace %s: %v"
,
updatedNamespace
.
Name
,
err
)
nc
.
deliverNamespace
(
namespace
.
Name
,
0
,
true
)
return
return
fmt
.
Errorf
(
"failed to finalize namespace: %v"
,
err
)
}
}
// TODO: What about namespaces in subclusters ???
err
:
=
nc
.
federatedApiClient
.
Core
()
.
Namespaces
()
.
Delete
(
updatedNamespace
.
Name
,
&
api
.
DeleteOptions
{})
err
=
nc
.
federatedApiClient
.
Core
()
.
Namespaces
()
.
Delete
(
updatedNamespace
.
Name
,
&
api
.
DeleteOptions
{})
if
err
!=
nil
{
// Its all good if the error is not found error. That means it is deleted already and we do not have to do anything.
// This is expected when we are processing an update as a result of namespace finalizer deletion.
// The process that deleted the last finalizer is also going to delete the namespace and we do not have to do anything.
if
!
errors
.
IsNotFound
(
err
)
{
glog
.
Errorf
(
"Failed to delete namespace %s: %v"
,
namespace
.
Name
,
err
)
nc
.
deliverNamespace
(
namespace
.
Name
,
0
,
true
)
return
fmt
.
Errorf
(
"failed to delete namespace: %v"
,
err
)
}
}
return
nil
}
federation/pkg/federation-controller/namespace/namespace_controller_test.go
View file @
091b843b
...
...
@@ -24,9 +24,12 @@ import (
federation_api
"k8s.io/kubernetes/federation/apis/federation/v1beta1"
fake_federation_release_1_4
"k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_4/fake"
.
"k8s.io/kubernetes/federation/pkg/federation-controller/util/test"
"k8s.io/kubernetes/pkg/api/unversioned"
api_v1
"k8s.io/kubernetes/pkg/api/v1"
extensionsv1
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
kube_release_1_4
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4"
fake_kube_release_1_4
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/fake"
"k8s.io/kubernetes/pkg/client/testing/core"
"k8s.io/kubernetes/pkg/runtime"
"github.com/stretchr/testify/assert"
...
...
@@ -35,6 +38,12 @@ import (
func
TestNamespaceController
(
t
*
testing
.
T
)
{
cluster1
:=
NewCluster
(
"cluster1"
,
api_v1
.
ConditionTrue
)
cluster2
:=
NewCluster
(
"cluster2"
,
api_v1
.
ConditionTrue
)
ns1
:=
api_v1
.
Namespace
{
ObjectMeta
:
api_v1
.
ObjectMeta
{
Name
:
"test-namespace"
,
SelfLink
:
"/api/v1/namespaces/test-namespace"
,
},
}
fakeClient
:=
&
fake_federation_release_1_4
.
Clientset
{}
RegisterFakeList
(
"clusters"
,
&
fakeClient
.
Fake
,
&
federation_api
.
ClusterList
{
Items
:
[]
federation_api
.
Cluster
{
*
cluster1
}})
...
...
@@ -53,6 +62,29 @@ func TestNamespaceController(t *testing.T) {
RegisterFakeList
(
"namespaces"
,
&
cluster2Client
.
Fake
,
&
api_v1
.
NamespaceList
{
Items
:
[]
api_v1
.
Namespace
{}})
cluster2CreateChan
:=
RegisterFakeCopyOnCreate
(
"namespaces"
,
&
cluster2Client
.
Fake
,
cluster2Watch
)
RegisterFakeList
(
"replicasets"
,
&
fakeClient
.
Fake
,
&
extensionsv1
.
ReplicaSetList
{
Items
:
[]
extensionsv1
.
ReplicaSet
{
{
ObjectMeta
:
api_v1
.
ObjectMeta
{
Name
:
"test-rs"
,
Namespace
:
ns1
.
Namespace
,
}}}})
RegisterFakeList
(
"secrets"
,
&
fakeClient
.
Fake
,
&
api_v1
.
SecretList
{
Items
:
[]
api_v1
.
Secret
{
{
ObjectMeta
:
api_v1
.
ObjectMeta
{
Name
:
"test-secret"
,
Namespace
:
ns1
.
Namespace
,
}}}})
RegisterFakeList
(
"services"
,
&
fakeClient
.
Fake
,
&
api_v1
.
ServiceList
{
Items
:
[]
api_v1
.
Service
{
{
ObjectMeta
:
api_v1
.
ObjectMeta
{
Name
:
"test-service"
,
Namespace
:
ns1
.
Namespace
,
}}}})
nsDeleteChan
:=
RegisterDelete
(
&
fakeClient
.
Fake
,
"namespaces"
)
rsDeleteChan
:=
RegisterDeleteCollection
(
&
fakeClient
.
Fake
,
"replicasets"
)
serviceDeleteChan
:=
RegisterDeleteCollection
(
&
fakeClient
.
Fake
,
"services"
)
secretDeleteChan
:=
RegisterDeleteCollection
(
&
fakeClient
.
Fake
,
"secrets"
)
namespaceController
:=
NewNamespaceController
(
fakeClient
)
informer
:=
ToFederatedInformerForTestOnly
(
namespaceController
.
namespaceFederatedInformer
)
informer
.
SetClientFactory
(
func
(
cluster
*
federation_api
.
Cluster
)
(
kube_release_1_4
.
Interface
,
error
)
{
...
...
@@ -73,13 +105,6 @@ func TestNamespaceController(t *testing.T) {
stop
:=
make
(
chan
struct
{})
namespaceController
.
Run
(
stop
)
ns1
:=
api_v1
.
Namespace
{
ObjectMeta
:
api_v1
.
ObjectMeta
{
Name
:
"test-namespace"
,
SelfLink
:
"/api/v1/namespaces/test-namespace"
,
},
}
// Test add federated namespace.
namespaceWatch
.
Add
(
&
ns1
)
createdNamespace
:=
GetNamespaceFromChan
(
cluster1CreateChan
)
...
...
@@ -103,9 +128,44 @@ func TestNamespaceController(t *testing.T) {
assert
.
Equal
(
t
,
ns1
.
Name
,
createdNamespace2
.
Name
)
// assert.Contains(t, createdNamespace2.Annotations, "A")
ns1
.
DeletionTimestamp
=
&
unversioned
.
Time
{
Time
:
time
.
Now
()}
namespaceWatch
.
Modify
(
&
ns1
)
assert
.
Equal
(
t
,
ns1
.
Name
,
GetStringFromChan
(
nsDeleteChan
))
assert
.
Equal
(
t
,
"all"
,
GetStringFromChan
(
rsDeleteChan
))
assert
.
Equal
(
t
,
"all"
,
GetStringFromChan
(
serviceDeleteChan
))
assert
.
Equal
(
t
,
"all"
,
GetStringFromChan
(
secretDeleteChan
))
close
(
stop
)
}
func
RegisterDeleteCollection
(
client
*
core
.
Fake
,
resource
string
)
chan
string
{
deleteChan
:=
make
(
chan
string
,
100
)
client
.
AddReactor
(
"delete-collection"
,
resource
,
func
(
action
core
.
Action
)
(
bool
,
runtime
.
Object
,
error
)
{
deleteChan
<-
"all"
return
true
,
nil
,
nil
})
return
deleteChan
}
func
RegisterDelete
(
client
*
core
.
Fake
,
resource
string
)
chan
string
{
deleteChan
:=
make
(
chan
string
,
100
)
client
.
AddReactor
(
"delete"
,
resource
,
func
(
action
core
.
Action
)
(
bool
,
runtime
.
Object
,
error
)
{
deleteAction
:=
action
.
(
core
.
DeleteAction
)
deleteChan
<-
deleteAction
.
GetName
()
return
true
,
nil
,
nil
})
return
deleteChan
}
func
GetStringFromChan
(
c
chan
string
)
string
{
select
{
case
str
:=
<-
c
:
return
str
case
<-
time
.
After
(
5
*
time
.
Second
)
:
return
""
}
}
func
GetNamespaceFromChan
(
c
chan
runtime
.
Object
)
*
api_v1
.
Namespace
{
namespace
:=
GetObjectFromChan
(
c
)
.
(
*
api_v1
.
Namespace
)
return
namespace
...
...
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