Skip to content

Commit 34f3599

Browse files
validate persistent volumes for aks clusters (#950)
1 parent 241050b commit 34f3599

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

cmd/src/validate_kube.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ Examples:
3333
3434
Suppress output (useful for CI/CD pipelines)
3535
$ src validate kube --quiet
36+
37+
Validate EKS cluster:
38+
$ src validate kube --eks
39+
40+
Validate GKE cluster:
41+
$ src validate kube --gke
42+
43+
Validate AKS cluster:
44+
$ src validate kube --aks
3645
`
3746

3847
flagSet := flag.NewFlagSet("kube", flag.ExitOnError)
@@ -48,6 +57,7 @@ Examples:
4857
quiet = flagSet.Bool("quiet", false, "(optional) suppress output and return exit status only")
4958
eks = flagSet.Bool("eks", false, "(optional) validate EKS cluster")
5059
gke = flagSet.Bool("gke", false, "(optional) validate GKE cluster")
60+
aks = flagSet.Bool("aks", false, "(optional) validate AKS cluster")
5161
)
5262

5363
if home := homedir.HomeDir(); home != "" {
@@ -96,6 +106,10 @@ Examples:
96106
options = append(options, kube.Gke())
97107
}
98108

109+
if *aks {
110+
options = append(options, kube.Aks())
111+
}
112+
99113
return kube.Validate(context.Background(), clientSet, config, options...)
100114
}
101115

internal/validate/kube/aks.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package kube
2+
3+
import (
4+
"context"
5+
6+
"github.com/sourcegraph/src-cli/internal/validate"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
)
9+
10+
func Aks() Option {
11+
return func(config *Config) {
12+
config.aks = true
13+
}
14+
}
15+
16+
func AksCsiDrivers(ctx context.Context, config *Config) ([]validate.Result, error) {
17+
var results []validate.Result
18+
19+
storageClassResults, err := validateStorageClass(ctx, config)
20+
if err != nil {
21+
results = append(results, validate.Result{
22+
Status: validate.Failure,
23+
Message: "AKS: could not validate if persistent volumes are enabled",
24+
})
25+
26+
return results, err
27+
}
28+
29+
results = append(results, storageClassResults...)
30+
31+
return results, nil
32+
}
33+
34+
func validateStorageClass(ctx context.Context, config *Config) ([]validate.Result, error) {
35+
var results []validate.Result
36+
37+
storageClient := config.clientSet.StorageV1()
38+
storageClasses, err := storageClient.StorageClasses().List(ctx, metav1.ListOptions{})
39+
if err != nil {
40+
return nil, err
41+
}
42+
43+
for _, item := range storageClasses.Items {
44+
if item.Name == "sourcegraph" {
45+
if item.Provisioner != "disk.csi.azure.com" {
46+
results = append(results, validate.Result{
47+
Status: validate.Failure,
48+
Message: "provisioner does not enable persistent volumes",
49+
})
50+
} else {
51+
results = append(results, validate.Result{
52+
Status: validate.Success,
53+
Message: "persistent volumes enabled",
54+
})
55+
}
56+
57+
if string(*item.ReclaimPolicy) != "Retain" {
58+
results = append(results, validate.Result{
59+
Status: validate.Failure,
60+
Message: "storageclass has a reclaim policy other than 'Retain'",
61+
})
62+
} else {
63+
results = append(results, validate.Result{
64+
Status: validate.Success,
65+
Message: "storageclass has correct reclaim policy (Retain)",
66+
})
67+
}
68+
69+
if string(*item.VolumeBindingMode) != "WaitForFirstConsumer" {
70+
results = append(results, validate.Result{
71+
Status: validate.Failure,
72+
Message: "storageclass has a binding mode other than 'WaitForFirstConsumer'",
73+
})
74+
} else {
75+
results = append(results, validate.Result{
76+
Status: validate.Success,
77+
Message: "storageclass has correct volumeBindingMode (WaitForFirstConsumer)",
78+
})
79+
}
80+
}
81+
}
82+
83+
if len(results) == 0 {
84+
results = append(results, validate.Result{
85+
Status: validate.Warning,
86+
Message: "you have not yet deployed a sourcegraph instance to this cluster, or you've named your storageclass something other than 'sourcegraph'",
87+
})
88+
}
89+
90+
return results, nil
91+
}

internal/validate/kube/kube.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type Config struct {
4646
restConfig *rest.Config
4747
eks bool
4848
gke bool
49+
aks bool
4950
eksClient *eks.Client
5051
ec2Client *ec2.Client
5152
iamClient *iam.Client
@@ -81,6 +82,7 @@ func Validate(ctx context.Context, clientSet *kubernetes.Clientset, restConfig *
8182
restConfig: restConfig,
8283
eks: false,
8384
gke: false,
85+
aks: false,
8486
}
8587

8688
for _, opt := range opts {
@@ -133,6 +135,21 @@ func Validate(ctx context.Context, clientSet *kubernetes.Clientset, restConfig *
133135
})
134136
}
135137

138+
if cfg.aks {
139+
if err := CurrentContextSetTo("aks"); err != nil {
140+
return errors.Newf("%s %s", validate.FailureEmoji, err)
141+
}
142+
143+
Aks()
144+
145+
validations = append(validations, validation{
146+
Validate: AksCsiDrivers,
147+
WaitMsg: "AKS: validating persistent volumes",
148+
SuccessMsg: "AKS: persistent volumes validated",
149+
ErrMsg: "AKS: validating persistent volumes failed",
150+
})
151+
}
152+
136153
var totalFailCount int
137154

138155
for _, v := range validations {
@@ -457,12 +474,24 @@ func CurrentContextSetTo(clusterService string) error {
457474
got := strings.Split(currentContext, ":")
458475
want := []string{"arn", "aws", clusterService}
459476

477+
if got[0] != "arn" {
478+
return errors.New("no eks cluster configured")
479+
}
480+
460481
if len(got) >= 3 {
461482
got = got[:3]
462483
if !reflect.DeepEqual(got, want) {
463484
return errors.New("no eks cluster configured")
464485
}
465486
}
487+
} else if clusterService == "aks" {
488+
colons := strings.Split(currentContext, ":") // aws string
489+
underscores := strings.Split(currentContext, "_") // gke string
490+
491+
// if current context has 'arn' or 'gke' in string, return error
492+
if colons[0] == "arn" || underscores[0] == "gke" {
493+
return errors.New("no aks cluster configured")
494+
}
466495
}
467496

468497
return nil

0 commit comments

Comments
 (0)