• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bakito / sealed-secrets-web / 12463906830

23 Dec 2024 08:42AM UTC coverage: 62.007% (+2.0%) from 59.961%
12463906830

push

github

bakito
format code with golines

50 of 59 new or added lines in 4 files covered. (84.75%)

1 existing line in 1 file now uncovered.

346 of 558 relevant lines covered (62.01%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.35
/pkg/handler/secrets.go
1
package handler
2

3
import (
4
        "context"
5
        "fmt"
6
        "log"
7
        "net/http"
8
        "sort"
9
        "strings"
10

11
        "github.com/bakito/sealed-secrets-web/pkg/config"
12
        ssClient "github.com/bitnami-labs/sealed-secrets/pkg/client/clientset/versioned/typed/sealedsecrets/v1alpha1"
13
        "github.com/gin-gonic/gin"
14
        v1 "k8s.io/api/core/v1"
15
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
        "k8s.io/apimachinery/pkg/runtime"
17
        "k8s.io/apimachinery/pkg/runtime/schema"
18
        "k8s.io/client-go/kubernetes/scheme"
19
        corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
20
        "k8s.io/client-go/tools/clientcmd"
21
)
22

23
// BuildClients build the  k82 clients
24
func BuildClients(
25
        clientConfig clientcmd.ClientConfig,
26
        disableLoadSecrets bool,
NEW
27
) (corev1.CoreV1Interface, ssClient.BitnamiV1alpha1Interface, error) {
×
28
        if disableLoadSecrets {
×
29
                return nil, nil, nil
×
30
        }
×
31
        conf, err := clientConfig.ClientConfig()
×
32
        if err != nil {
×
33
                return nil, nil, err
×
34
        }
×
35

36
        restClient, err := corev1.NewForConfig(conf)
×
37
        if err != nil {
×
38
                return nil, nil, err
×
39
        }
×
40

41
        ssCl, err := ssClient.NewForConfig(conf)
×
42
        if err != nil {
×
43
                return nil, nil, err
×
44
        }
×
45

46
        return restClient, ssCl, nil
×
47
}
48

49
// SecretsHandler handles our secrets operations.
50
type SecretsHandler struct {
51
        coreClient         corev1.CoreV1Interface
52
        ssClient           ssClient.BitnamiV1alpha1Interface
53
        disableLoadSecrets bool
54
        includeNamespaces  map[string]bool
55
}
56

57
// NewHandler creates a new secret handler.
58
func NewHandler(
59
        coreClient corev1.CoreV1Interface,
60
        ssCl ssClient.BitnamiV1alpha1Interface,
61
        cfg *config.Config,
NEW
62
) *SecretsHandler {
×
63
        inMap := make(map[string]bool)
×
64
        for _, n := range cfg.IncludeNamespaces {
×
65
                inMap[n] = true
×
66
        }
×
67
        return &SecretsHandler{
×
68
                ssClient:           ssCl,
×
69
                coreClient:         coreClient,
×
70
                disableLoadSecrets: cfg.DisableLoadSecrets,
×
71
                includeNamespaces:  inMap,
×
72
        }
×
73
}
74

75
// List returns a list of all secrets.
76
func (h *SecretsHandler) list(ctx context.Context) ([]Secret, error) {
×
77
        var secrets []Secret
×
78
        fmt.Printf("secrets: %#v\n", secrets)
×
79
        if h.disableLoadSecrets {
×
80
                return secrets, nil
×
81
        }
×
82

83
        if len(h.includeNamespaces) > 0 {
×
84
                for ns := range h.includeNamespaces {
×
85
                        list, err := h.listForNamespace(ctx, ns)
×
86
                        if err != nil {
×
87
                                return nil, err
×
88
                        }
×
89
                        secrets = append(secrets, list...)
×
90
                }
91
        } else {
×
92
                list, err := h.listForNamespace(ctx, "")
×
93
                if err != nil {
×
94
                        return nil, err
×
95
                }
×
96
                secrets = append(secrets, list...)
×
97
        }
98

99
        sort.Slice(secrets, func(i, j int) bool {
×
100
                if secrets[i].Namespace == secrets[j].Namespace {
×
101
                        return secrets[i].Name < secrets[j].Name
×
102
                }
×
103
                return secrets[i].Namespace < secrets[j].Namespace
×
104
        })
105

106
        return secrets, nil
×
107
}
108

109
func (h *SecretsHandler) listForNamespace(ctx context.Context, ns string) ([]Secret, error) {
×
110
        var secrets []Secret
×
111
        ssList, err := h.ssClient.SealedSecrets(ns).List(ctx, metav1.ListOptions{})
×
112
        if err != nil {
×
113
                return nil, err
×
114
        }
×
115
        for _, item := range ssList.Items {
×
116
                secrets = append(secrets, Secret{Namespace: item.Namespace, Name: item.Name})
×
117
        }
×
118
        return secrets, nil
×
119
}
120

121
// GetSecret returns a secret by name in the given namespace.
122
func (h *SecretsHandler) GetSecret(ctx context.Context, namespace, name string) (*v1.Secret, error) {
×
123
        if h.disableLoadSecrets {
×
124
                return nil, nil
×
125
        }
×
126
        if len(h.includeNamespaces) > 0 && !h.includeNamespaces[namespace] {
×
127
                return nil, fmt.Errorf("namespace '%s' is not allowed", namespace)
×
128
        }
×
129
        secret, err := h.coreClient.Secrets(namespace).Get(ctx, name, metav1.GetOptions{})
×
130
        if err != nil {
×
131
                return nil, err
×
132
        }
×
133
        secret.TypeMeta = metav1.TypeMeta{
×
134
                APIVersion: "v1",
×
135
                Kind:       "Secret",
×
136
        }
×
137
        secret.ObjectMeta.ManagedFields = nil
×
138
        secret.ObjectMeta.OwnerReferences = nil
×
139
        secret.ObjectMeta.CreationTimestamp = metav1.Time{}
×
140
        secret.ObjectMeta.ResourceVersion = ""
×
141
        secret.ObjectMeta.UID = ""
×
142

×
143
        return secret, nil
×
144
}
145

146
func (h *SecretsHandler) AllSecrets(c *gin.Context) {
×
147
        if h.disableLoadSecrets {
×
148
                c.JSON(http.StatusForbidden, gin.H{"error": "Loading secrets is disabled"})
×
149
                return
×
150
        }
×
151

152
        sec, err := h.list(c)
×
153
        if err != nil {
×
154
                log.Printf("Error in %s: %v\n", Sanitize(c.Request.URL.Path), err)
×
155
                c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
×
156
                return
×
157
        }
×
158

159
        c.JSON(http.StatusOK, gin.H{"secrets": sec})
×
160
}
161

162
func (h *SecretsHandler) Secret(c *gin.Context) {
×
163
        contentType, outputFormat, done := NegotiateFormat(c)
×
164
        if done {
×
165
                return
×
166
        }
×
167

168
        if h.disableLoadSecrets {
×
169
                c.JSON(http.StatusForbidden, gin.H{"error": "Loading secrets is disabled"})
×
170
                return
×
171
        }
×
172

173
        // Load existing secret.
174
        namespace := Sanitize(c.Param("namespace"))
×
175
        name := Sanitize(c.Param("name"))
×
176
        secret, err := h.GetSecret(c, namespace, name)
×
177
        if err != nil {
×
178
                log.Printf("Error in %s: %v\n", Sanitize(c.Request.URL.Path), err)
×
179
                c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
×
180
                return
×
181
        }
×
182

183
        encode, err := encodeSecret(secret, outputFormat)
×
184
        if err != nil {
×
185
                log.Printf("Error in %s: %v\n", Sanitize(c.Request.URL.Path), err)
×
186
                c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
×
187
                return
×
188
        }
×
189
        c.Data(http.StatusOK, contentType, encode)
×
190
}
191

192
func encodeSecret(secret *v1.Secret, outputFormat string) ([]byte, error) {
1✔
193
        var contentType string
1✔
194
        switch strings.ToLower(outputFormat) {
1✔
195
        case "json", "":
1✔
196
                contentType = runtime.ContentTypeJSON
1✔
197
        case "yaml":
1✔
198
                contentType = runtime.ContentTypeYAML
1✔
199
        default:
×
200
                return nil, fmt.Errorf("unsupported output format: %s", outputFormat)
×
201
        }
202

203
        info, ok := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), contentType)
1✔
204
        if !ok {
1✔
205
                return nil, fmt.Errorf("unsupported output format: %s", outputFormat)
×
206
        }
×
207

208
        prettyEncoder := info.PrettySerializer
1✔
209
        if prettyEncoder == nil {
2✔
210
                prettyEncoder = info.Serializer
1✔
211
        }
1✔
212
        encoder := scheme.Codecs.EncoderForVersion(prettyEncoder, schema.GroupVersion{Group: "", Version: "v1"})
1✔
213

1✔
214
        return runtime.Encode(encoder, secret)
1✔
215
}
216

217
type Secret struct {
218
        Namespace string `json:"namespace" yaml:"namespace"`
219
        Name      string `json:"name"      yaml:"name"`
220
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc