Skip to content

Commit 537b117

Browse files
authored
Merge pull request #19 from replicatedhq/imagepullsecrets
Image pull secret collector and analyzers
2 parents e1adf97 + d83e11a commit 537b117

File tree

15 files changed

+290
-45
lines changed

15 files changed

+290
-45
lines changed

cmd/preflight/cli/interactive_results.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,11 @@ func showSaved(filename string) {
272272
func appName(preflightName string) string {
273273
words := strings.Split(strings.Title(strings.Replace(preflightName, "-", " ", -1)), " ")
274274
casedWords := []string{}
275-
for _, word := range words {
275+
for i, word := range words {
276276
if strings.ToLower(word) == "ai" {
277277
casedWords = append(casedWords, "AI")
278+
} else if strings.ToLower(word) == "io" && i > 0 {
279+
casedWords[i-1] += ".io"
278280
} else {
279281
casedWords = append(casedWords, word)
280282
}

cmd/preflight/cli/run_nocrd.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net/http"
1212
"os"
1313
"path/filepath"
14+
"strings"
1415
"time"
1516

1617
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
@@ -75,10 +76,20 @@ func runPreflightsNoCRD(v *viper.Viper, arg string) error {
7576

7677
return contents, nil
7778
}
79+
getChildCollectedFileContents := func(prefix string) (map[string][]byte, error) {
80+
matching := make(map[string][]byte)
81+
for k, v := range allCollectedData {
82+
if strings.HasPrefix(k, prefix) {
83+
matching[k] = v
84+
}
85+
}
86+
87+
return matching, nil
88+
}
7889

7990
analyzeResults := []*analyzerunner.AnalyzeResult{}
8091
for _, analyzer := range preflight.Spec.Analyzers {
81-
analyzeResult, err := analyzerunner.Analyze(analyzer, getCollectedFileContents)
92+
analyzeResult, err := analyzerunner.Analyze(analyzer, getCollectedFileContents, getChildCollectedFileContents)
8293
if err != nil {
8394
fmt.Printf("an analyzer failed to run: %v\n", err)
8495
continue

config/crds/troubleshoot.replicated.com_preflights.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,48 @@ spec:
475475
- outcomes
476476
- customResourceDefinitionName
477477
type: object
478+
imagePullSecret:
479+
properties:
480+
checkName:
481+
type: string
482+
outcomes:
483+
items:
484+
properties:
485+
fail:
486+
properties:
487+
message:
488+
type: string
489+
uri:
490+
type: string
491+
when:
492+
type: string
493+
type: object
494+
pass:
495+
properties:
496+
message:
497+
type: string
498+
uri:
499+
type: string
500+
when:
501+
type: string
502+
type: object
503+
warn:
504+
properties:
505+
message:
506+
type: string
507+
uri:
508+
type: string
509+
when:
510+
type: string
511+
type: object
512+
type: object
513+
type: array
514+
registryName:
515+
type: string
516+
required:
517+
- outcomes
518+
- registryName
519+
type: object
478520
ingress:
479521
properties:
480522
checkName:

config/crds/zz_generated.deepcopy.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ func (in *Analyze) DeepCopyInto(out *Analyze) {
3636
*out = new(AnalyzeSecret)
3737
(*in).DeepCopyInto(*out)
3838
}
39+
if in.ImagePullSecret != nil {
40+
in, out := &in.ImagePullSecret, &out.ImagePullSecret
41+
*out = new(ImagePullSecret)
42+
(*in).DeepCopyInto(*out)
43+
}
3944
}
4045

4146
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Analyze.
@@ -713,6 +718,33 @@ func (in *HTTP) DeepCopy() *HTTP {
713718
return out
714719
}
715720

721+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
722+
func (in *ImagePullSecret) DeepCopyInto(out *ImagePullSecret) {
723+
*out = *in
724+
out.AnalyzeMeta = in.AnalyzeMeta
725+
if in.Outcomes != nil {
726+
in, out := &in.Outcomes, &out.Outcomes
727+
*out = make([]*Outcome, len(*in))
728+
for i := range *in {
729+
if (*in)[i] != nil {
730+
in, out := &(*in)[i], &(*out)[i]
731+
*out = new(Outcome)
732+
(*in).DeepCopyInto(*out)
733+
}
734+
}
735+
}
736+
}
737+
738+
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePullSecret.
739+
func (in *ImagePullSecret) DeepCopy() *ImagePullSecret {
740+
if in == nil {
741+
return nil
742+
}
743+
out := new(ImagePullSecret)
744+
in.DeepCopyInto(out)
745+
return out
746+
}
747+
716748
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
717749
func (in *Ingress) DeepCopyInto(out *Ingress) {
718750
*out = *in
Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,50 @@
11
apiVersion: troubleshoot.replicated.com/v1beta1
22
kind: Preflight
33
metadata:
4-
name: shiny-new-ai
4+
name: support-io
55
spec:
66
uploadResultsTo: https://hookb.in/Z26mz8R9VpC7q7eYrWob
77
analyzers:
8-
- clusterVersion:
8+
- imagePullSecret:
9+
checkName: "blarg"
10+
registryName: quay.io
911
outcomes:
1012
- fail:
11-
when: "< 1.13.0"
12-
message: Sorry, ShinyNew.ai requires at least Kubernetes 1.14.0. Please update your Kubernetes cluster before installing.
13-
uri: https://enterprise.shinynew.ai/install/requirements/kubernetes
14-
- warn:
15-
when: "< 1.15.0"
16-
message: The version of Kubernetes you are running meets the minimum requirements to run ShineyNew.ai. It's recommended to run Kubernetes 1.15.0 or later.
17-
uri: https://enterprise.shinynew.ai/install/requirements/kubernetes
13+
message: Cannot pull from quay.io
1814
- pass:
19-
message: The version of Kubernetes you have installed meets the required and recommended versions.
20-
- storageClass:
21-
checkName: Required storage classes
22-
storageClassName: "microk8s-hostpath"
23-
outcomes:
24-
- fail:
25-
message: The required storage class was not found in the cluster.
26-
- pass:
27-
message: The required storage class was found in the cluster.
28-
- ingress:
29-
namespace: default
30-
ingressName: my-app-ingress
31-
outcomes:
32-
- fail:
33-
message: Expected to find an ingress named "my-app-ingress".
34-
- pass:
35-
message: Expected ingress was found.
36-
customResourceDefinitionName: rook
37-
outcomes:
38-
- fail:
39-
message: Rook is required for ShinyNew.ai. Rook was not found in the cluster.
40-
- pass:
41-
message: Found a supported version of Rook installed and running in the cluster.
15+
message: Found credentials to pull from quay.io
16+
# - clusterVersion:
17+
# outcomes:
18+
# - fail:
19+
# when: "< 1.13.0"
20+
# message: Sorry, support.io requires at least Kubernetes 1.14.0. Please update your Kubernetes cluster before installing.
21+
# uri: https://enterprise.support.io/install/requirements/kubernetes
22+
# - warn:
23+
# when: "< 1.15.0"
24+
# message: The version of Kubernetes you are running meets the minimum requirements to run support.io. It's recommended to run Kubernetes 1.15.0 or later.
25+
# uri: https://enterprise.support.io/install/requirements/kubernetes
26+
# - pass:
27+
# message: The version of Kubernetes you have installed meets the required and recommended versions.
28+
# - storageClass:
29+
# checkName: Required storage classes
30+
# storageClassName: "microk8s-hostpath"
31+
# outcomes:
32+
# - fail:
33+
# message: The required storage class was not found in the cluster.
34+
# - pass:
35+
# message: The required storage class was found in the cluster.
36+
# - ingress:
37+
# namespace: default
38+
# ingressName: my-app-ingress
39+
# outcomes:
40+
# - fail:
41+
# message: Expected to find an ingress named "my-app-ingress".
42+
# - pass:
43+
# message: Expected ingress was found.
44+
# - customResourceDefinitionName:
45+
# customResourceDefinitionName: rook
46+
# outcomes:
47+
# - fail:
48+
# message: Rook is required for Support.io. Rook was not found in the cluster.
49+
# - pass:
50+
# message: Found a supported version of Rook installed and running in the cluster.

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,4 @@ require (
3232
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
3333
sigs.k8s.io/controller-runtime v0.2.0-beta.2
3434
sigs.k8s.io/controller-tools v0.2.0-beta.2 // indirect
35-
3635
)

pkg/analyze/analyzer.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,27 @@ type AnalyzeResult struct {
1616
URI string
1717
}
1818

19-
func Analyze(analyzer *troubleshootv1beta1.Analyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
19+
type getCollectedFileContents func(string) ([]byte, error)
20+
type getChildCollectedFileContents func(string) (map[string][]byte, error)
21+
22+
func Analyze(analyzer *troubleshootv1beta1.Analyze, getFile getCollectedFileContents, findFiles getChildCollectedFileContents) (*AnalyzeResult, error) {
2023
if analyzer.ClusterVersion != nil {
21-
return analyzeClusterVersion(analyzer.ClusterVersion, getCollectedFileContents)
24+
return analyzeClusterVersion(analyzer.ClusterVersion, getFile)
2225
}
2326
if analyzer.StorageClass != nil {
24-
return analyzeStorageClass(analyzer.StorageClass, getCollectedFileContents)
27+
return analyzeStorageClass(analyzer.StorageClass, getFile)
2528
}
2629
if analyzer.CustomResourceDefinition != nil {
27-
return analyzeCustomResourceDefinition(analyzer.CustomResourceDefinition, getCollectedFileContents)
30+
return analyzeCustomResourceDefinition(analyzer.CustomResourceDefinition, getFile)
2831
}
2932
if analyzer.Ingress != nil {
30-
return analyzeIngress(analyzer.Ingress, getCollectedFileContents)
33+
return analyzeIngress(analyzer.Ingress, getFile)
3134
}
3235
if analyzer.Secret != nil {
33-
return analyzeSecret(analyzer.Secret, getCollectedFileContents)
36+
return analyzeSecret(analyzer.Secret, getFile)
37+
}
38+
if analyzer.ImagePullSecret != nil {
39+
return analyzeImagePullSecret(analyzer.ImagePullSecret, findFiles)
3440
}
3541

3642
return nil, errors.New("invalid analyzer")

pkg/analyze/image_pull_secret.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package analyzer
2+
3+
import (
4+
"encoding/json"
5+
6+
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
7+
)
8+
9+
func analyzeImagePullSecret(analyzer *troubleshootv1beta1.ImagePullSecret, getChildCollectedFileContents func(string) (map[string][]byte, error)) (*AnalyzeResult, error) {
10+
imagePullSecrets, err := getChildCollectedFileContents("cluster-resources/image-pull-secrets")
11+
if err != nil {
12+
return nil, err
13+
}
14+
15+
var failOutcome *troubleshootv1beta1.Outcome
16+
var passOutcome *troubleshootv1beta1.Outcome
17+
for _, outcome := range analyzer.Outcomes {
18+
if outcome.Fail != nil {
19+
failOutcome = outcome
20+
} else if outcome.Pass != nil {
21+
passOutcome = outcome
22+
}
23+
}
24+
25+
result := AnalyzeResult{
26+
Title: analyzer.CheckName,
27+
IsFail: true,
28+
Message: failOutcome.Fail.Message,
29+
URI: failOutcome.Fail.URI,
30+
}
31+
32+
for _, v := range imagePullSecrets {
33+
registryAndUsername := make(map[string]string)
34+
if err := json.Unmarshal(v, &registryAndUsername); err != nil {
35+
return nil, err
36+
}
37+
38+
for registry, _ := range registryAndUsername {
39+
if registry == analyzer.RegistryName {
40+
result.IsPass = true
41+
result.IsFail = false
42+
result.Message = passOutcome.Pass.Message
43+
result.URI = passOutcome.Pass.URI
44+
}
45+
}
46+
}
47+
48+
return &result, nil
49+
}

pkg/apis/troubleshoot/v1beta1/analyzer_shared.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ type AnalyzeSecret struct {
4444
Key string `json:"key,omitempty" yaml:"key,omitempty"`
4545
}
4646

47+
type ImagePullSecret struct {
48+
AnalyzeMeta `json:",inline" yaml:",inline"`
49+
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
50+
RegistryName string `json:"registryName" yaml:"registryName"`
51+
}
52+
4753
type AnalyzeMeta struct {
4854
CheckName string `json:"checkName,omitempty" yaml:"checkName,omitempty"`
4955
}
@@ -54,4 +60,5 @@ type Analyze struct {
5460
CustomResourceDefinition *CustomResourceDefinition `json:"customResourceDefinition,omitempty" yaml:"customResourceDefinition,omitempty"`
5561
Ingress *Ingress `json:"ingress,omitempty" yaml:"ingress,omitempty"`
5662
Secret *AnalyzeSecret `json:"secret,omitempty" yaml:"secret,omitempty"`
63+
ImagePullSecret *ImagePullSecret `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
5764
}

pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ func (in *Analyze) DeepCopyInto(out *Analyze) {
5252
*out = new(AnalyzeSecret)
5353
(*in).DeepCopyInto(*out)
5454
}
55+
if in.ImagePullSecret != nil {
56+
in, out := &in.ImagePullSecret, &out.ImagePullSecret
57+
*out = new(ImagePullSecret)
58+
(*in).DeepCopyInto(*out)
59+
}
5560
}
5661

5762
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Analyze.
@@ -729,6 +734,33 @@ func (in *HTTP) DeepCopy() *HTTP {
729734
return out
730735
}
731736

737+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
738+
func (in *ImagePullSecret) DeepCopyInto(out *ImagePullSecret) {
739+
*out = *in
740+
out.AnalyzeMeta = in.AnalyzeMeta
741+
if in.Outcomes != nil {
742+
in, out := &in.Outcomes, &out.Outcomes
743+
*out = make([]*Outcome, len(*in))
744+
for i := range *in {
745+
if (*in)[i] != nil {
746+
in, out := &(*in)[i], &(*out)[i]
747+
*out = new(Outcome)
748+
(*in).DeepCopyInto(*out)
749+
}
750+
}
751+
}
752+
}
753+
754+
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePullSecret.
755+
func (in *ImagePullSecret) DeepCopy() *ImagePullSecret {
756+
if in == nil {
757+
return nil
758+
}
759+
out := new(ImagePullSecret)
760+
in.DeepCopyInto(out)
761+
return out
762+
}
763+
732764
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
733765
func (in *Ingress) DeepCopyInto(out *Ingress) {
734766
*out = *in

0 commit comments

Comments
 (0)