Skip to content

Commit ff95934

Browse files
authored
feat(dynamic-localpv-provisioner):support pass image pull secrets when creating init-pvc-pod by localpv-provisioner (#22)
Add image pull secret to init PVC pod with the environment variable Signed-off-by: mahao <[email protected]>
1 parent 76b21e4 commit ff95934

File tree

8 files changed

+152
-2
lines changed

8 files changed

+152
-2
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
nohup.out
33
coverage.txt
44
.DS_Store
5+
cmd/provisioner-localpv/start.sh
6+
.idea

cmd/provisioner-localpv/app/config.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
//"github.com/pkg/errors"
3030
errors "github.com/pkg/errors"
31+
corev1 "k8s.io/api/core/v1"
3132
v1 "k8s.io/api/core/v1"
3233
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3334
//storagev1 "k8s.io/api/storage/v1"
@@ -327,3 +328,22 @@ func GetNodeLabelValue(n *v1.Node, labelKey string) string {
327328
func GetTaints(n *v1.Node) []v1.Taint {
328329
return n.Spec.Taints
329330
}
331+
332+
// GetImagePullSecrets parse image pull secrets from env
333+
// transform string to corev1.LocalObjectReference
334+
// multiple secrets are separated by commas
335+
func GetImagePullSecrets(s string) []corev1.LocalObjectReference {
336+
s = strings.TrimSpace(s)
337+
list := make([]corev1.LocalObjectReference, 0)
338+
if len(s) == 0 {
339+
return list
340+
}
341+
arr := strings.Split(s, ",")
342+
for _, item := range arr {
343+
if len(item) > 0 {
344+
l := corev1.LocalObjectReference{Name: strings.TrimSpace(item)}
345+
list = append(list, l)
346+
}
347+
}
348+
return list
349+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2019 The OpenEBS Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
*/
17+
18+
package app
19+
20+
import (
21+
"reflect"
22+
"testing"
23+
24+
corev1 "k8s.io/api/core/v1"
25+
)
26+
27+
func TestGetImagePullSecrets(t *testing.T) {
28+
testCases := map[string]struct {
29+
value string
30+
expectedValue []corev1.LocalObjectReference
31+
}{
32+
"empty variable": {
33+
value: "",
34+
expectedValue: []corev1.LocalObjectReference{},
35+
},
36+
"single value": {
37+
value: "image-pull-secret",
38+
expectedValue: []corev1.LocalObjectReference{{Name: "image-pull-secret"}},
39+
},
40+
"multiple value": {
41+
value: "image-pull-secret,secret-1",
42+
expectedValue: []corev1.LocalObjectReference{{Name: "image-pull-secret"}, {Name: "secret-1"}},
43+
},
44+
"whitespaces": {
45+
value: " ",
46+
expectedValue: []corev1.LocalObjectReference{},
47+
},
48+
"single value with whitespaces": {
49+
value: " docker-secret ",
50+
expectedValue: []corev1.LocalObjectReference{{Name: "docker-secret"}},
51+
},
52+
"multiple value with whitespaces": {
53+
value: " docker-secret, image-pull-secret ",
54+
expectedValue: []corev1.LocalObjectReference{{Name: "docker-secret"}, {Name: "image-pull-secret"}},
55+
},
56+
}
57+
for k, v := range testCases {
58+
v := v
59+
t.Run(k, func(t *testing.T) {
60+
actualValue := GetImagePullSecrets(v.value)
61+
if !reflect.DeepEqual(actualValue, v.expectedValue) {
62+
t.Errorf("expected %s got %s", v.expectedValue, actualValue)
63+
}
64+
})
65+
}
66+
}

cmd/provisioner-localpv/app/env.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ const (
3838
// ProvisionerBasePath is the environment variable that provides the
3939
// default base path on the node where host-path PVs will be provisioned.
4040
ProvisionerBasePath menv.ENVKey = "OPENEBS_IO_BASE_PATH"
41+
42+
// ProvisionerImagePullSecrets is the environment variable that provides the
43+
// init pod to use as authentication when pulling helper image, it is used in the scene where authentication is required
44+
ProvisionerImagePullSecrets menv.ENVKey = "OPENEBS_IO_IMAGE_PULL_SECRETS"
4145
)
4246

4347
var (
@@ -59,3 +63,6 @@ func getDefaultBasePath() string {
5963
func getOpenEBSServiceAccountName() string {
6064
return menv.Get(menv.OpenEBSServiceAccount)
6165
}
66+
func getOpenEBSImagePullSecrets() string {
67+
return menv.Get(ProvisionerImagePullSecrets)
68+
}

cmd/provisioner-localpv/app/env_test.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ limitations under the License.
1717
package app
1818

1919
import (
20-
menv "github.com/openebs/maya/pkg/env/v1alpha1"
2120
"os"
2221
"reflect"
2322
"testing"
23+
24+
menv "github.com/openebs/maya/pkg/env/v1alpha1"
2425
)
2526

2627
func TestGetOpenEBSNamespace(t *testing.T) {
@@ -157,3 +158,40 @@ func TestGetOpenEBSServiceAccountName(t *testing.T) {
157158
})
158159
}
159160
}
161+
162+
func TestGetOpenEBSImagePullSecrets(t *testing.T) {
163+
testCases := map[string]struct {
164+
value string
165+
expectedValue string
166+
}{
167+
"Missing env variable": {
168+
value: "",
169+
expectedValue: "",
170+
},
171+
"Present env variable with value": {
172+
value: "image-pull-secret",
173+
expectedValue: "image-pull-secret",
174+
},
175+
"Present env variable with multiple value": {
176+
value: "image-pull-secret,secret-1",
177+
expectedValue: "image-pull-secret,secret-1",
178+
},
179+
"Present env variable with whitespaces": {
180+
value: " ",
181+
expectedValue: "",
182+
},
183+
}
184+
for k, v := range testCases {
185+
v := v
186+
t.Run(k, func(t *testing.T) {
187+
if len(v.value) != 0 {
188+
os.Setenv(string(ProvisionerImagePullSecrets), v.value)
189+
}
190+
actualValue := getOpenEBSImagePullSecrets()
191+
if !reflect.DeepEqual(actualValue, v.expectedValue) {
192+
t.Errorf("expected %s got %s", v.expectedValue, actualValue)
193+
}
194+
os.Unsetenv(string(ProvisionerImagePullSecrets))
195+
})
196+
}
197+
}

cmd/provisioner-localpv/app/helper_hostpath.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ type HelperPodOptions struct {
7272
serviceAccountName string
7373

7474
selectedNodeTaints []corev1.Taint
75+
76+
imagePullSecrets []corev1.LocalObjectReference
7577
}
7678

7779
// validate checks that the required fields to launch
@@ -189,6 +191,7 @@ func (p *Provisioner) launchPod(config podConfig) (*corev1.Pod, error) {
189191
}).
190192
WithPrivilegedSecurityContext(&privileged),
191193
).
194+
WithImagePullSecrets(config.pOpts.imagePullSecrets).
192195
WithVolumeBuilder(
193196
volume.NewBuilder().
194197
WithName("data").

cmd/provisioner-localpv/app/provisioner_hostpath.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ func (p *Provisioner) ProvisionHostPath(opts pvController.ProvisionOptions, volu
5757
return nil, err
5858
}
5959

60-
klog.Infof("Creating volume %v at node with label %v=%v, path:%v", name, nodeAffinityKey, nodeAffinityValue, path)
60+
imagePullSecrets := GetImagePullSecrets(getOpenEBSImagePullSecrets())
61+
62+
klog.Infof("Creating volume %v at node with label %v=%v, path:%v,ImagePullSecrets:%v", name, nodeAffinityKey, nodeAffinityValue, path, imagePullSecrets)
6163

6264
//Before using the path for local PV, make sure it is created.
6365
initCmdsForPath := []string{"mkdir", "-m", "0777", "-p"}
@@ -69,6 +71,7 @@ func (p *Provisioner) ProvisionHostPath(opts pvController.ProvisionOptions, volu
6971
nodeAffinityLabelValue: nodeAffinityValue,
7072
serviceAccountName: saName,
7173
selectedNodeTaints: taints,
74+
imagePullSecrets: imagePullSecrets,
7275
}
7376
iErr := p.createInitPod(podOpts)
7477
if iErr != nil {

pkg/kubernetes/api/core/v1/pod/build.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,17 @@ func (b *Builder) WithContainer(container corev1.Container) *Builder {
210210
return b.WithContainers([]corev1.Container{container})
211211
}
212212

213+
// WithImagePullSecrets sets the pod image pull secrets
214+
// + optional
215+
// if the length is zero that no secret is needed to pull the image
216+
func (b *Builder) WithImagePullSecrets(secrets []corev1.LocalObjectReference) *Builder {
217+
if len(secrets) == 0 {
218+
return b
219+
}
220+
b.pod.object.Spec.ImagePullSecrets = secrets
221+
return b
222+
}
223+
213224
// WithVolumes sets the Volumes field in Pod with provided arguments
214225
func (b *Builder) WithVolumes(volumes []corev1.Volume) *Builder {
215226
if len(volumes) == 0 {

0 commit comments

Comments
 (0)