Skip to content

Commit e836456

Browse files
committed
frontend: app: i18n: Resolved merge conflicts
2 parents 37881d4 + c3848bc commit e836456

File tree

122 files changed

+16516
-10514
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+16516
-10514
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Headlamp was created to blend the traditional feature set of other web UIs/dashb
2525
- Vendor-independent / generic Kubernetes UI
2626
- Works in-cluster, or locally as a desktop app
2727
- Multi-cluster
28-
- Extensible through plugins
28+
- Extensible through [plugins](https://github.com/headlamp-k8s/plugins)
2929
- UI controls reflecting user roles (no deletion/update if not allowed)
3030
- Clean & modern UI
3131
- Cancellable creation/update/deletion operations
@@ -77,9 +77,16 @@ tested, or comment if there are any regressions in the existing ones.
7777

7878
## Extensions / Plugins
7979

80+
Please see [headlamp plugins on Artifact Hub](https://artifacthub.io/packages/search?kind=21&sort=relevance&page=1) for a list of plugins published.
81+
82+
See the [plugins repo](https://github.com/headlamp-k8s/plugins) for some official plugins.
83+
84+
### Plugin development
85+
8086
If you are interested in tweaking Headlamp to fit your use-cases, you can check out
8187
our [plugin development guide](https://headlamp.dev/docs/latest/development/plugins/).
8288

89+
8390
## Get involved
8491

8592
Check out our:

SECURITY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
## Reporting a Vulnerability
44

55
Please read our documentation on how to [report security issues](https://headlamp.dev/docs/latest/contributing/#security-issues).
6+
7+
We kindly ask that you responsibly disclose any vulnerabilities and give us appropriate time to develop a fix.

backend/cmd/headlamp.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,14 +1298,25 @@ func (c *HeadlampConfig) getClusters() []Cluster {
12981298
continue
12991299
}
13001300

1301+
kubeconfigPath := context.KubeConfigPath
1302+
1303+
source := context.SourceStr()
1304+
1305+
clusterID := context.ClusterID
1306+
13011307
clusters = append(clusters, Cluster{
13021308
Name: context.Name,
13031309
Server: context.Cluster.Server,
13041310
AuthType: context.AuthType(),
13051311
Metadata: map[string]interface{}{
1306-
"source": context.SourceStr(),
1312+
"source": source,
13071313
"namespace": context.KubeContext.Namespace,
13081314
"extensions": context.KubeContext.Extensions,
1315+
"origin": map[string]interface{}{
1316+
"kubeconfig": kubeconfigPath,
1317+
},
1318+
"originalName": context.Name,
1319+
"clusterID": clusterID,
13091320
},
13101321
})
13111322
}

backend/pkg/kubeconfig/kubeconfig.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ type Context struct {
4545
proxy *httputil.ReverseProxy `json:"-"`
4646
Internal bool `json:"internal"`
4747
Error string `json:"error"`
48+
// KubeConfigPath is the file path for the kubeconfig file.
49+
KubeConfigPath string `json:"kubeConfigPath"`
50+
// ClusterID is the unique identifier for the cluster, consisting of the filepath and context name.
51+
ClusterID string `json:"clusterID"`
4852
}
4953

5054
type OidcConfig struct {
@@ -336,7 +340,7 @@ type ContextLoadError struct {
336340
// LoadContextsFromFile loads contexts from a kubeconfig file.
337341
// It reads the kubeconfig file from the given path and loads the contexts from the file.
338342
// It returns an error if the file cannot be read.
339-
// It will return valid contexts, ContextLoadError and errors if there are any errors in the file.
343+
// It will return valid (contexts, ContextLoadErrors,nil) and errors if there are any errors in the file.
340344
func LoadContextsFromFile(kubeConfigPath string, source int) ([]Context, []ContextLoadError, error) {
341345
data, err := os.ReadFile(kubeConfigPath)
342346
if err != nil {
@@ -345,7 +349,19 @@ func LoadContextsFromFile(kubeConfigPath string, source int) ([]Context, []Conte
345349

346350
skipProxySetup := source != KubeConfig
347351

348-
return loadContextsFromData(data, source, skipProxySetup)
352+
contexts, contextErrors, err := loadContextsFromData(data, source, skipProxySetup)
353+
if err != nil {
354+
return nil, nil, fmt.Errorf("error loading contexts from file: %v", err)
355+
}
356+
357+
// add the KubeConfigPath to each context
358+
for i := range contexts {
359+
contexts[i].KubeConfigPath = kubeConfigPath
360+
// create the clusterID from the path and context name
361+
contexts[i].ClusterID = fmt.Sprintf("%s+%s", kubeConfigPath, contexts[i].Name)
362+
}
363+
364+
return contexts, contextErrors, nil
349365
}
350366

351367
// LoadContextsFromBase64String loads contexts from a base64 encoded kubeconfig string.

backend/pkg/kubeconfig/kubeconfig_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package kubeconfig_test
33
import (
44
"context"
55
"encoding/base64"
6+
"fmt"
67
"net/http"
78
"net/http/httptest"
89
"os"
@@ -86,6 +87,59 @@ func TestLoadContextsFromKubeConfigFile(t *testing.T) {
8687
})
8788
}
8889

90+
// TestLoadContextFromFile validates the behavior of the LoadContextsFromFile function.
91+
//
92+
// This test ensures that the function correctly processes a valid kubeconfig file
93+
// and produces the expected metadata results without errors.
94+
func TestLoadContextFromFile(t *testing.T) {
95+
kubeConfigFile := "./test_data/kubeconfig_metadata"
96+
97+
contexts, contextErrors, err := kubeconfig.LoadContextsFromFile(kubeConfigFile, kubeconfig.KubeConfig)
98+
99+
require.NoError(t, err, "Expected no error for valid file")
100+
require.Empty(t, contextErrors, "Expected no context errors for valid file")
101+
require.Equal(t, 2, len(contexts), "Expected 3 contexts from valid file")
102+
103+
expectedNames := []string{"random-cluster-x", "random-cluster-y", ""}
104+
expectedClusterIDs := []string{
105+
fmt.Sprintf("%s+%s", kubeConfigFile, "random-cluster-x"),
106+
fmt.Sprintf("%s+%s", kubeConfigFile, "random-cluster-y"),
107+
}
108+
109+
for _, ctx := range contexts {
110+
assert.NotEmpty(t, ctx.Name, "Expected non-empty context name")
111+
assert.Contains(t, expectedNames, ctx.Name, "Unexpected context name")
112+
assert.Contains(t, expectedClusterIDs, ctx.ClusterID, "Unexpected ClusterID")
113+
assert.Equal(t, kubeConfigFile, ctx.KubeConfigPath, "Unexpected kubeconfig path")
114+
assert.Equal(t, fmt.Sprintf("%s+%s", kubeConfigFile, ctx.Name), ctx.ClusterID, "Unexpected ClusterID")
115+
}
116+
}
117+
118+
// TestLoadContextsWithDuplicateNames validates the behavior of the LoadContextsFromMultipleFiles function.
119+
func TestLoadContextsWithDuplicateNames(t *testing.T) {
120+
// Simulate two kubeconfig files with duplicate context names
121+
kubeConfigFile1 := "./test_data/kubeconfig_metadata"
122+
kubeConfigFile2 := "./test_data/kubeconfig_metadata_duplicate"
123+
124+
// Both files have a context named "random-cluster-x"
125+
combined := kubeConfigFile1 + string(os.PathListSeparator) + kubeConfigFile2
126+
127+
contexts, contextErrors, err := kubeconfig.LoadContextsFromMultipleFiles(combined, kubeconfig.KubeConfig)
128+
require.NoError(t, err, "Expected no error for valid file")
129+
require.Empty(t, contextErrors, "Expected no context errors for valid file")
130+
131+
// Should load both contexts, even if names are the same, but may overwrite in store
132+
var count int
133+
134+
for _, ctx := range contexts {
135+
if ctx.Name == "random-cluster-x" {
136+
count++
137+
}
138+
}
139+
140+
assert.Equal(t, 2, count, "Expected 2 contexts with the same name")
141+
}
142+
89143
func TestContext(t *testing.T) {
90144
kubeConfigFile := config.GetDefaultKubeConfigPath()
91145

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
apiVersion: v1
2+
clusters:
3+
- cluster:
4+
certificate-authority-data: dGVzdA==
5+
server: https://kubernetes.docker.internal:6443
6+
name: random-cluster-x
7+
- cluster:
8+
certificate-authority-data: dGVzdA==
9+
extensions:
10+
- extension:
11+
last-update: Mon, 26 Dec 2022 20:33:03 IST
12+
provider: random-cluster-y.sigs.k8s.io
13+
version: v1.28.0
14+
name: cluster_info
15+
server: https://127.0.0.1:60279
16+
name: random-cluster-y
17+
contexts:
18+
- context:
19+
cluster: random-cluster-x
20+
user: random-cluster-x
21+
name: random-cluster-x
22+
- context:
23+
cluster: random-cluster-y
24+
extensions:
25+
- extension:
26+
last-update: Mon, 26 Dec 2022 20:33:03 IST
27+
provider: random-cluster-y.sigs.k8s.io
28+
version: v1.28.0
29+
name: context_info
30+
namespace: default
31+
user: random-cluster-y
32+
name: random-cluster-y
33+
current-context: random-cluster-y
34+
kind: Config
35+
preferences: {}
36+
users:
37+
- name: random-cluster-x
38+
user:
39+
client-certificate-data: dGVzdA==
40+
client-key-data: dGVzdA==
41+
- name: random-cluster-y
42+
user:
43+
client-certificate-data: dGVzdA==
44+
client-key-data: dGVzdA==
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
apiVersion: v1
2+
clusters:
3+
- cluster:
4+
certificate-authority-data: dGVzdA==
5+
server: https://kubernetes.docker.internal:6443
6+
name: random-cluster-x
7+
- cluster:
8+
certificate-authority-data: dGVzdA==
9+
extensions:
10+
- extension:
11+
last-update: Mon, 26 Dec 2022 20:33:03 IST
12+
provider: random-cluster-y.sigs.k8s.io
13+
version: v1.28.0
14+
name: cluster_info
15+
server: https://127.0.0.1:60279
16+
name: random-cluster-y
17+
contexts:
18+
- context:
19+
cluster: random-cluster-x
20+
user: random-cluster-x
21+
name: random-cluster-x
22+
- context:
23+
cluster: random-cluster-y
24+
extensions:
25+
- extension:
26+
last-update: Mon, 26 Dec 2022 20:33:03 IST
27+
provider: random-cluster-y.sigs.k8s.io
28+
version: v1.28.0
29+
name: context_info
30+
namespace: default
31+
user: random-cluster-y
32+
name: random-cluster-y
33+
current-context: random-cluster-y
34+
kind: Config
35+
preferences: {}
36+
users:
37+
- name: random-cluster-x
38+
user:
39+
client-certificate-data: dGVzdA==
40+
client-key-data: dGVzdA==
41+
- name: random-cluster-y
42+
user:
43+
client-certificate-data: dGVzdA==
44+
client-key-data: dGVzdA==

0 commit comments

Comments
 (0)