-
Notifications
You must be signed in to change notification settings - Fork 82
/
namespace.go
135 lines (117 loc) · 3.72 KB
/
namespace.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package resource
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/aws/aws-k8s-tester/e2e/framework/utils"
"github.com/onsi/ginkgo"
corev1 "k8s.io/api/core/v1"
apierrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
)
const (
DefaultNamespaceDeletionTimeout = 10 * time.Minute
)
type NamespaceManager struct {
cs kubernetes.Interface
namespacesToDelete []string
}
func NewNamespaceManager(cs kubernetes.Interface) *NamespaceManager {
return &NamespaceManager{
cs: cs,
}
}
func (m *NamespaceManager) Cleanup(ctx context.Context) error {
var errMsgs []string
for _, ns := range m.namespacesToDelete {
ctx, cancel := context.WithTimeout(ctx, DefaultNamespaceDeletionTimeout)
if err := m.DeleteNamespace(ctx, ns); err != nil {
errMsgs = append(errMsgs, fmt.Sprintf("Couldn't delete ns: %q: %s (%#v)", ns, err, err))
}
cancel()
}
if len(errMsgs) != 0 {
return errors.New(strings.Join(errMsgs, ","))
}
return nil
}
func (m *NamespaceManager) CreateNamespaceUnique(ctx context.Context, baseName string) (*corev1.Namespace, error) {
name, err := m.findAvailableNamespaceName(ctx, baseName)
if err != nil {
return nil, err
}
return m.CreateNamespace(ctx, name)
}
func (m *NamespaceManager) CreateNamespace(ctx context.Context, name string) (*corev1.Namespace, error) {
namespaceObj := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: "",
},
Status: corev1.NamespaceStatus{},
}
m.namespacesToDelete = append(m.namespacesToDelete, name)
var namespace *corev1.Namespace
ginkgo.By(fmt.Sprintf("Creating namespace %q for this suite.", name))
if err := wait.PollImmediateUntil(utils.PollIntervalShort, func() (bool, error) {
var err error
namespace, err = m.cs.CoreV1().Namespaces().Create(namespaceObj)
if err != nil {
utils.Logf("Unexpected error while creating namespace: %v", err)
return false, nil
}
return true, nil
}, ctx.Done()); err != nil {
return nil, err
}
return namespace, nil
}
// DeleteNamespace deletes the provided namespace, waits for it to be completely deleted.
func (m *NamespaceManager) DeleteNamespace(ctx context.Context, namespace string) error {
startTime := time.Now()
ginkgo.By(fmt.Sprintf("Deleting namespace %q for this suite.", namespace))
if err := m.cs.CoreV1().Namespaces().Delete(namespace, nil); err != nil {
if apierrs.IsNotFound(err) {
utils.Logf("Namespace %v was already deleted", namespace)
return nil
}
return err
}
// wait for namespace to delete or timeout.
if err := wait.PollImmediateUntil(utils.PollIntervalShort, func() (bool, error) {
if _, err := m.cs.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}); err != nil {
if apierrs.IsNotFound(err) {
return true, nil
}
utils.Logf("Error while waiting for namespace to be terminated: %v", err)
return false, nil
}
return false, nil
}, ctx.Done()); err != nil {
return err
}
utils.Logf("namespace %v deletion completed in %s", namespace, time.Since(startTime))
return nil
}
// findAvailableNamespaceName random namespace name starting with baseName.
func (m *NamespaceManager) findAvailableNamespaceName(ctx context.Context, baseName string) (string, error) {
var name string
err := wait.PollImmediateUntil(utils.PollIntervalShort, func() (bool, error) {
name = fmt.Sprintf("%v-%v", baseName, utils.RandomSuffix())
_, err := m.cs.CoreV1().Namespaces().Get(name, metav1.GetOptions{})
if err == nil {
// Already taken
return false, nil
}
if apierrs.IsNotFound(err) {
return true, nil
}
utils.Logf("Unexpected error while getting namespace: %v", err)
return false, nil
}, ctx.Done())
return name, err
}