Skip to content

Commit 6fbb79c

Browse files
committed
⭐️ discover k8s applications
1 parent da56dae commit 6fbb79c

File tree

4 files changed

+255
-0
lines changed

4 files changed

+255
-0
lines changed
+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package resources
2+
3+
import (
4+
"slices"
5+
"sort"
6+
7+
"go.mondoo.com/cnquery/v11/llx"
8+
)
9+
10+
const (
11+
// https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/
12+
K8sApplicationName = "app.kubernetes.io/name"
13+
K8sApplicationInstance = "app.kubernetes.io/instance"
14+
K8sApplicationVersion = "app.kubernetes.io/version"
15+
K8sApplicationComponent = "app.kubernetes.io/component"
16+
K8sApplicationPartOf = "app.kubernetes.io/part-of"
17+
K8sApplicationManagedBy = "app.kubernetes.io/managed-by"
18+
)
19+
20+
func (k *mqlK8s) apps() ([]interface{}, error) {
21+
type k8sapp struct {
22+
name string
23+
version string
24+
instance string
25+
components []string
26+
partOf string
27+
managedBy string
28+
}
29+
30+
apps := map[string]k8sapp{}
31+
32+
// fetch deployment resources
33+
deployments := k.GetDeployments()
34+
if deployments.Error != nil {
35+
return nil, deployments.Error
36+
}
37+
38+
for i := range deployments.Data {
39+
d := deployments.Data[i].(*mqlK8sDeployment)
40+
labels := d.GetLabels().Data
41+
name, nameOk := labels[K8sApplicationName]
42+
instance, instanceOK := labels[K8sApplicationInstance]
43+
version, versionOK := labels[K8sApplicationVersion]
44+
component, componentOK := labels[K8sApplicationComponent]
45+
partOf, partOfOK := labels[K8sApplicationPartOf]
46+
managedBy, managedByOK := labels[K8sApplicationManagedBy]
47+
48+
if !nameOk {
49+
continue
50+
}
51+
52+
app := k8sapp{
53+
name: name.(string),
54+
}
55+
if instanceOK {
56+
app.instance = instance.(string)
57+
}
58+
if versionOK {
59+
app.version = version.(string)
60+
}
61+
if componentOK {
62+
app.components = []string{component.(string)}
63+
}
64+
if partOfOK {
65+
app.partOf = partOf.(string)
66+
}
67+
if managedByOK {
68+
app.managedBy = managedBy.(string)
69+
}
70+
71+
key := app.name + app.instance
72+
if existing, ok := apps[key]; ok {
73+
// if the app already exists, we need to merge the components
74+
components := append(existing.components, app.components...)
75+
sort.Strings(components)
76+
components = slices.Compact(components)
77+
existing.components = components
78+
apps[app.name+app.instance] = existing
79+
} else {
80+
apps[app.name+app.instance] = app
81+
}
82+
}
83+
84+
// // fetch daemonset resources
85+
// daemonsets := k.GetDaemonsets()
86+
// if daemonsets.Error != nil {
87+
// return nil, daemonsets.Error
88+
// }
89+
90+
// return k8s app list
91+
appList := []interface{}{}
92+
for _, app := range apps {
93+
r, err := CreateResource(k.MqlRuntime, "k8s.app", map[string]*llx.RawData{
94+
"__id": llx.StringData("app"),
95+
"name": llx.StringData(app.name),
96+
"version": llx.StringData(app.version),
97+
"instance": llx.StringData(app.instance),
98+
"managedBy": llx.StringData(app.managedBy),
99+
})
100+
if err != nil {
101+
return nil, err
102+
}
103+
104+
appList = append(appList, r)
105+
}
106+
107+
return appList, nil
108+
}

providers/k8s/resources/k8s.lr

+15
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ k8s {
5858
customresources() []k8s.customresource
5959
// Kubernetes admission webhook configurations
6060
validatingWebhookConfigurations() []k8s.admission.validatingwebhookconfiguration
61+
// Kubernetes applications
62+
apps() []k8s.app
6163
}
6264

6365
// Kubernetes API resources
@@ -865,6 +867,7 @@ private k8s.userinfo @defaults("username") {
865867
uid string
866868
}
867869

870+
// Kubernetes Validating Webhook Configuration
868871
private k8s.admission.validatingwebhookconfiguration @defaults("name") {
869872
// Mondoo ID for the Kubernetes object
870873
id string
@@ -886,4 +889,16 @@ private k8s.admission.validatingwebhookconfiguration @defaults("name") {
886889
manifest() dict
887890
// Webhooks configuration
888891
webhooks() []dict
892+
}
893+
894+
// Kubernetes Application
895+
private k8s.app {
896+
// Application name
897+
name string
898+
// Application version
899+
version string
900+
// Application instance
901+
instance string
902+
// Managed By
903+
managedBy string
889904
}

providers/k8s/resources/k8s.lr.go

+119
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

providers/k8s/resources/k8s.lr.manifest.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ resources:
55
k8s:
66
fields:
77
apiResources: {}
8+
apps:
9+
min_mondoo_version: 9.0.0
810
clusterrolebindings:
911
min_mondoo_version: 5.31.0
1012
clusterroles:
@@ -120,6 +122,17 @@ resources:
120122
platform:
121123
name:
122124
- kubernetes
125+
k8s.app:
126+
fields:
127+
instance: {}
128+
managedBy: {}
129+
name: {}
130+
version: {}
131+
is_private: true
132+
min_mondoo_version: 9.0.0
133+
platform:
134+
name:
135+
- kubernetes
123136
k8s.configmap:
124137
fields:
125138
annotations: {}

0 commit comments

Comments
 (0)