mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
feat(helm): helm apps deployed by portainer not marked as external EE-1624 (#5637)
* helm lib update * helm handler requires kubernetes deployer to modify helm deployed resources * AddAppLabels updated to be more generic - support for adding multiple labels using map * path installed helm release manifest with portainer labels using kubectl * updated helm handler unit tests to use mock KubernetesDeployer * adding labels to manifest retrieved from release * optional namespace support for k8s raw manifest deployment * - inline postprocessing support when extracting - get namespace from yaml support - added and updated tests * lowercase error wrapping * updated libhelm dep
This commit is contained in:
parent
50f63ae865
commit
af98660a55
14 changed files with 494 additions and 30 deletions
|
@ -410,7 +410,7 @@ spec:
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := AddAppLabels([]byte(tt.input), labels)
|
||||
result, err := AddAppLabels([]byte(tt.input), labels.ToMap())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wantOutput, string(result))
|
||||
})
|
||||
|
@ -451,7 +451,7 @@ spec:
|
|||
targetPort: 5000
|
||||
`
|
||||
|
||||
result, err := AddAppLabels([]byte(input), labels)
|
||||
result, err := AddAppLabels([]byte(input), labels.ToMap())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, string(result))
|
||||
}
|
||||
|
@ -487,7 +487,291 @@ spec:
|
|||
targetPort: 5000
|
||||
`
|
||||
|
||||
result, err := AddAppLabels([]byte(input), labels)
|
||||
result, err := AddAppLabels([]byte(input), labels.ToMap())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, string(result))
|
||||
}
|
||||
|
||||
func Test_AddAppLabels_HelmApp(t *testing.T) {
|
||||
labels := GetHelmAppLabels("best-name", "best-owner")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
wantOutput string
|
||||
}{
|
||||
{
|
||||
name: "bitnami nginx configmap",
|
||||
input: `apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nginx-test-server-block
|
||||
labels:
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
data:
|
||||
server-blocks-paths.conf: |-
|
||||
include "/opt/bitnami/nginx/conf/server_blocks/ldap/*.conf";
|
||||
include "/opt/bitnami/nginx/conf/server_blocks/common/*.conf";
|
||||
`,
|
||||
wantOutput: `apiVersion: v1
|
||||
data:
|
||||
server-blocks-paths.conf: |-
|
||||
include "/opt/bitnami/nginx/conf/server_blocks/ldap/*.conf";
|
||||
include "/opt/bitnami/nginx/conf/server_blocks/common/*.conf";
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
io.portainer.kubernetes.application.name: best-name
|
||||
io.portainer.kubernetes.application.owner: best-owner
|
||||
name: nginx-test-server-block
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "bitnami nginx service",
|
||||
input: `apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-test
|
||||
labels:
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
externalTrafficPolicy: "Cluster"
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
selector:
|
||||
app.kubernetes.io/name: nginx
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
`,
|
||||
wantOutput: `apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
io.portainer.kubernetes.application.name: best-name
|
||||
io.portainer.kubernetes.application.owner: best-owner
|
||||
name: nginx-test
|
||||
spec:
|
||||
externalTrafficPolicy: Cluster
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
selector:
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/name: nginx
|
||||
type: LoadBalancer
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "bitnami nginx deployment",
|
||||
input: `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-test
|
||||
labels:
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: nginx
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
shareProcessNamespace: false
|
||||
serviceAccountName: default
|
||||
containers:
|
||||
- name: nginx
|
||||
image: docker.io/bitnami/nginx:1.21.3-debian-10-r0
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
`,
|
||||
wantOutput: `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
io.portainer.kubernetes.application.name: best-name
|
||||
io.portainer.kubernetes.application.owner: best-owner
|
||||
name: nginx-test
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/name: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: nginx-test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: nginx
|
||||
helm.sh/chart: nginx-9.5.4
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- image: docker.io/bitnami/nginx:1.21.3-debian-10-r0
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: nginx
|
||||
serviceAccountName: default
|
||||
shareProcessNamespace: false
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := AddAppLabels([]byte(tt.input), labels)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wantOutput, string(result))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_DocumentSeperator(t *testing.T) {
|
||||
labels := KubeAppLabels{
|
||||
StackID: 123,
|
||||
Name: "best-name",
|
||||
Owner: "best-owner",
|
||||
Kind: "git",
|
||||
}
|
||||
|
||||
input := `apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
io.kompose.service: database
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
io.kompose.service: backend
|
||||
`
|
||||
expected := `apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
io.kompose.service: database
|
||||
io.portainer.kubernetes.application.kind: git
|
||||
io.portainer.kubernetes.application.name: best-name
|
||||
io.portainer.kubernetes.application.owner: best-owner
|
||||
io.portainer.kubernetes.application.stackid: "123"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
io.kompose.service: backend
|
||||
io.portainer.kubernetes.application.kind: git
|
||||
io.portainer.kubernetes.application.name: best-name
|
||||
io.portainer.kubernetes.application.owner: best-owner
|
||||
io.portainer.kubernetes.application.stackid: "123"
|
||||
`
|
||||
result, err := AddAppLabels([]byte(input), labels.ToMap())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, string(result))
|
||||
}
|
||||
|
||||
func Test_GetNamespace(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "valid namespace",
|
||||
input: `apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
namespace: test-namespace
|
||||
`,
|
||||
want: "test-namespace",
|
||||
},
|
||||
{
|
||||
name: "invalid namespace",
|
||||
input: `apiVersion: v1
|
||||
kind: Namespace
|
||||
`,
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := GetNamespace([]byte(tt.input))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.want, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_ExtractDocuments(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "multiple documents",
|
||||
input: `apiVersion: v1
|
||||
kind: Namespace
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
`,
|
||||
want: []string{`apiVersion: v1
|
||||
kind: Namespace
|
||||
`, `apiVersion: v1
|
||||
kind: Service
|
||||
`},
|
||||
},
|
||||
{
|
||||
name: "single document",
|
||||
input: `apiVersion: v1
|
||||
kind: Namespace
|
||||
`,
|
||||
want: []string{`apiVersion: v1
|
||||
kind: Namespace
|
||||
`},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
results, err := ExtractDocuments([]byte(tt.input), nil)
|
||||
assert.NoError(t, err)
|
||||
for i := range results {
|
||||
assert.Equal(t, tt.want[i], string(results[i]))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue