Skip to content

Commit ed0ad7e

Browse files
committed
Image pull secrets
1 parent e922dc7 commit ed0ad7e

File tree

13 files changed

+213
-45
lines changed

13 files changed

+213
-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
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: 29 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.
@@ -648,6 +653,7 @@ func (in *CustomResourceDefinition) DeepCopy() *CustomResourceDefinition {
648653
}
649654

650655
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
656+
<<<<<<< HEAD
651657
func (in *Exec) DeepCopyInto(out *Exec) {
652658
*out = *in
653659
if in.Selector != nil {
@@ -685,10 +691,25 @@ func (in *Get) DeepCopyInto(out *Get) {
685691
*out = make(map[string]string, len(*in))
686692
for key, val := range *in {
687693
(*out)[key] = val
694+
=======
695+
func (in *ImagePullSecret) DeepCopyInto(out *ImagePullSecret) {
696+
*out = *in
697+
out.AnalyzeMeta = in.AnalyzeMeta
698+
if in.Outcomes != nil {
699+
in, out := &in.Outcomes, &out.Outcomes
700+
*out = make([]*Outcome, len(*in))
701+
for i := range *in {
702+
if (*in)[i] != nil {
703+
in, out := &(*in)[i], &(*out)[i]
704+
*out = new(Outcome)
705+
(*in).DeepCopyInto(*out)
706+
}
707+
>>>>>>> Image pull secrets
688708
}
689709
}
690710
}
691711

712+
<<<<<<< HEAD
692713
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Get.
693714
func (in *Get) DeepCopy() *Get {
694715
if in == nil {
@@ -725,6 +746,14 @@ func (in *HTTP) DeepCopy() *HTTP {
725746
return nil
726747
}
727748
out := new(HTTP)
749+
=======
750+
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePullSecret.
751+
func (in *ImagePullSecret) DeepCopy() *ImagePullSecret {
752+
if in == nil {
753+
return nil
754+
}
755+
out := new(ImagePullSecret)
756+
>>>>>>> Image pull secrets
728757
in.DeepCopyInto(out)
729758
return out
730759
}

pkg/collect/cluster_resources.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package collect
22

33
import (
4+
"encoding/base64"
45
"encoding/json"
56
"fmt"
7+
"strings"
68

79
"github.com/replicatedhq/troubleshoot/pkg/redact"
810
corev1 "k8s.io/api/core/v1"
@@ -20,6 +22,7 @@ type ClusterResourcesOutput struct {
2022
Ingress map[string][]byte `json:"cluster-resources/ingress,omitempty"`
2123
StorageClasses []byte `json:"cluster-resources/storage-classes.json,omitempty"`
2224
CustomResourceDefinitions []byte `json:"cluster-resources/custom-resource-definitions.json,omitempty"`
25+
ImagePullSecrets map[string][]byte `json:"cluster-resources/image-pull-secrets,omitempty"`
2326
}
2427

2528
func ClusterResources(redact bool) error {
@@ -92,6 +95,13 @@ func ClusterResources(redact bool) error {
9295
}
9396
clusterResourcesOutput.CustomResourceDefinitions = customResourceDefinitions
9497

98+
// imagepullsecrets
99+
imagePullSecrets, err := imagePullSecrets(client, namespaceNames)
100+
if err != nil {
101+
return err
102+
}
103+
clusterResourcesOutput.ImagePullSecrets = imagePullSecrets
104+
95105
if redact {
96106
clusterResourcesOutput, err = clusterResourcesOutput.Redact()
97107
if err != nil {
@@ -231,6 +241,51 @@ func crds(client *apiextensionsv1beta1clientset.ApiextensionsV1beta1Client) ([]b
231241
return b, nil
232242
}
233243

244+
func imagePullSecrets(client *kubernetes.Clientset, namespaces []string) (map[string][]byte, error) {
245+
imagePullSecrets := make(map[string][]byte)
246+
247+
// better than vendoring in.... kubernetes
248+
type DockerConfigEntry struct {
249+
Auth string `json:"auth"`
250+
}
251+
type DockerConfigJSON struct {
252+
Auths map[string]DockerConfigEntry `json:"auths"`
253+
}
254+
255+
for _, namespace := range namespaces {
256+
secrets, err := client.CoreV1().Secrets(namespace).List(metav1.ListOptions{})
257+
if err != nil {
258+
return nil, err
259+
}
260+
261+
for _, secret := range secrets.Items {
262+
if secret.Type == corev1.SecretTypeDockerConfigJson {
263+
dockerConfigJSON := DockerConfigJSON{}
264+
if err := json.Unmarshal(secret.Data[corev1.DockerConfigJsonKey], &dockerConfigJSON); err != nil {
265+
return nil, err
266+
}
267+
268+
for registry, registryAuth := range dockerConfigJSON.Auths {
269+
decoded, err := base64.StdEncoding.DecodeString(registryAuth.Auth)
270+
if err != nil {
271+
return nil, err
272+
}
273+
274+
registryAndUsername := make(map[string]string)
275+
registryAndUsername[registry] = strings.Split(string(decoded), ":")[0]
276+
b, err := json.Marshal(registryAndUsername)
277+
if err != nil {
278+
return nil, err
279+
}
280+
imagePullSecrets[fmt.Sprintf("%s/%s.json", namespace, secret.Name)] = b
281+
}
282+
}
283+
}
284+
}
285+
286+
return imagePullSecrets, nil
287+
}
288+
234289
func (c *ClusterResourcesOutput) Redact() (*ClusterResourcesOutput, error) {
235290
namespaces, err := redact.Redact(c.Namespaces)
236291
if err != nil {
@@ -268,5 +323,6 @@ func (c *ClusterResourcesOutput) Redact() (*ClusterResourcesOutput, error) {
268323
Ingress: ingress,
269324
StorageClasses: storageClasses,
270325
CustomResourceDefinitions: crds,
326+
ImagePullSecrets: c.ImagePullSecrets,
271327
}, nil
272328
}

pkg/collect/runner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func createCollectorPod(client client.Client, scheme *runtime.Scheme, ownerRef m
8989
return nil, err
9090
}
9191

92-
imageName := "replicatedhq/troubleshoot:latest"
92+
imageName := "replicated/troubleshoot:latest"
9393
imagePullPolicy := corev1.PullAlways
9494

9595
if image != "" {

0 commit comments

Comments
 (0)