diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kubernetes_v1_config.yaml new file mode 100644 index 0000000..d456b2c --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kubernetes_v1_config.yaml @@ -0,0 +1,362 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kyverno-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kyverno-kubernetes_v1_config.yaml new file mode 100644 index 0000000..805b849 --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kyverno-kubernetes_v1_config.yaml @@ -0,0 +1,426 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..a51177f --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,448 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..614c23f --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-istio-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,384 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-kubernetes_v1_config.yaml new file mode 100644 index 0000000..daacc55 --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-kubernetes_v1_config.yaml @@ -0,0 +1,331 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME \ No newline at end of file diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-kyverno-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-kyverno-kubernetes_v1_config.yaml new file mode 100644 index 0000000..ddddc2c --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-kyverno-kubernetes_v1_config.yaml @@ -0,0 +1,394 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-kyverno-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-kyverno-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..a315824 --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-kyverno-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,416 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/argo-argo_rollouts-fluxcd-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-argo_rollouts-fluxcd-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..f254e2f --- /dev/null +++ b/kubernetes/templates/argo-argo_rollouts-fluxcd-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,352 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + # ArgoCD Rollouts configuration + - kind: argoproj.io/v1alpha1/rollouts + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Rollout-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"Rollout"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // null + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/argo-fluxcd-istio-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-istio-kubernetes_v1_config.yaml new file mode 100644 index 0000000..13b406c --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-istio-kubernetes_v1_config.yaml @@ -0,0 +1,337 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + diff --git a/kubernetes/templates/argo-fluxcd-istio-kyverno-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-istio-kyverno-kubernetes_v1_config.yaml new file mode 100644 index 0000000..9382bd1 --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-istio-kyverno-kubernetes_v1_config.yaml @@ -0,0 +1,401 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp diff --git a/kubernetes/templates/argo-fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..0329357 --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,423 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/argo-fluxcd-istio-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-istio-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..437b54c --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-istio-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,359 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/argo-fluxcd-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-kubernetes_v1_config.yaml new file mode 100644 index 0000000..1aef779 --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-kubernetes_v1_config.yaml @@ -0,0 +1,306 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME \ No newline at end of file diff --git a/kubernetes/templates/argo-fluxcd-kyverno-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-kyverno-kubernetes_v1_config.yaml new file mode 100644 index 0000000..87fc1be --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-kyverno-kubernetes_v1_config.yaml @@ -0,0 +1,369 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp diff --git a/kubernetes/templates/argo-fluxcd-kyverno-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-kyverno-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..0790141 --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-kyverno-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,391 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/argo-fluxcd-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/argo-fluxcd-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..44c1fb6 --- /dev/null +++ b/kubernetes/templates/argo-fluxcd-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,327 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + # ArgoCD configuration + - kind: argoproj.io/v1alpha1/applications + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + blueprint: '"argocdApp"' + title: .metadata.name + properties: + status: .status.health.status + syncStatus: .status.sync.status + syncPolicy: .spec.syncPolicy // null + gitRepo: .spec.source.repoURL// null + gitPath: .spec.source.path // null + gitRev: .status.sync.revision // null + relations: + workload: '(.spec.destination.namespace as $namespace | .status.resources | map(select(.kind == "Deployment" or .kind == "StatefulSet" or .kind == "DaemonSet" or .kind == "Rollout" )) | .[] | .name + "-" + .kind + "-" + $namespace + "-" + env.CLUSTER_NAME) // []' + argocdProject: .spec.project + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + destinationNamespace: .spec.destination.namespace + "-" + env.CLUSTER_NAME + + - kind: argoproj.io/v1alpha1/appproject + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdProject"' + properties: + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: v1/secrets + selector: + query: '.metadata.labels // {} | contains({ "argocd.argoproj.io/secret-type": "repository" })' + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"argocdRepo"' + properties: + repoUrl: .data.url | @base64d + repoType: .data.type | @base64d + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/fluxcd-istio-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-istio-kubernetes_v1_config.yaml new file mode 100644 index 0000000..529fb2b --- /dev/null +++ b/kubernetes/templates/fluxcd-istio-kubernetes_v1_config.yaml @@ -0,0 +1,291 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + diff --git a/kubernetes/templates/fluxcd-istio-kyverno-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-istio-kyverno-kubernetes_v1_config.yaml new file mode 100644 index 0000000..08e3ece --- /dev/null +++ b/kubernetes/templates/fluxcd-istio-kyverno-kubernetes_v1_config.yaml @@ -0,0 +1,355 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp diff --git a/kubernetes/templates/fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..0cd3d84 --- /dev/null +++ b/kubernetes/templates/fluxcd-istio-kyverno-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,377 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/fluxcd-istio-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-istio-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..72985d4 --- /dev/null +++ b/kubernetes/templates/fluxcd-istio-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,313 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: networking.istio.io/v1beta1/virtualservices + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"virtualServices"' + properties: + title: .metadata.name + hosts: .spec.hosts + match: .spec.http[].match + labels: .metadata.labels + relations: + gateways: .spec.gateways[] + "-" + .metadata.namespace + services: .metadata.namespace as $namespace | .spec.http[].route[].destination.host + "-" + $namespace + + - kind: networking.istio.io/v1beta1/gateways + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + blueprint: '"gateways"' + properties: + title: .metadata.name + ports: .spec.servers[].port.number + name: .metadata.name + labels: .metadata.labels + selector: .spec.selector + relations: + namespace: .metadata.namespace + + + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/fluxcd-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-kubernetes_v1_config.yaml new file mode 100644 index 0000000..e79e995 --- /dev/null +++ b/kubernetes/templates/fluxcd-kubernetes_v1_config.yaml @@ -0,0 +1,260 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME \ No newline at end of file diff --git a/kubernetes/templates/fluxcd-kyverno-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-kyverno-kubernetes_v1_config.yaml new file mode 100644 index 0000000..9eb6d20 --- /dev/null +++ b/kubernetes/templates/fluxcd-kyverno-kubernetes_v1_config.yaml @@ -0,0 +1,323 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp diff --git a/kubernetes/templates/fluxcd-kyverno-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-kyverno-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..b4775ac --- /dev/null +++ b/kubernetes/templates/fluxcd-kyverno-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,345 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: kyverno.io/v1/policies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kyverno.io/v1/clusterpolicies + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicy"' + properties: + admission: .spec.admission + background: .spec.background + validationFailureAction: .spec.validationFailureAction + createdAt: .metadata.creationTimestamp + + - kind: wgpolicyk8s.io/v1alpha2/policyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: wgpolicyk8s.io/v1alpha2/clusterpolicyreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .scope.name + icon: '"Cluster"' + blueprint: '"kyvernoPolicyReport"' + properties: + pass: .summary.pass + fail: .summary.fail + warn: .summary.warn + error: .summary.error + skip: .summary.skip + createdAt: .metadata.creationTimestamp + + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME diff --git a/kubernetes/templates/fluxcd-trivy-kubernetes_v1_config.yaml b/kubernetes/templates/fluxcd-trivy-kubernetes_v1_config.yaml new file mode 100644 index 0000000..09b76fe --- /dev/null +++ b/kubernetes/templates/fluxcd-trivy-kubernetes_v1_config.yaml @@ -0,0 +1,281 @@ +# Base Kubernetes configuration + +resources: # List of K8s resources to list, watch, and export to Port. + - kind: v1/namespaces # group/version/resource (G/V/R) format + selector: + query: .metadata.name | startswith("kube") | not # JQ boolean query. If evaluated to false - skip syncing the object. + port: + entity: + mappings: # Mappings between one K8s object to one or many Port Entities. Each value is a JQ query. + - identifier: .metadata.name + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"namespace"' + properties: + creationTimestamp: .metadata.creationTimestamp + labels: .metadata.labels + relations: + Cluster: 'env.CLUSTER_NAME' + + - kind: v1/namespaces + selector: + query: .metadata.name | contains("kube-system") + port: + entity: + mappings: + - identifier: env.CLUSTER_NAME + title: env.CLUSTER_NAME + blueprint: '"cluster"' + + - kind: apps/v1/deployments + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-Deployment-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"workload"' + properties: + kind: '"Deployment"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategyConfig: .spec.strategy // {} + strategy: .spec.strategy.type + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/daemonsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-DaemonSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"DaemonSet"' + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + strategyConfig: .spec.strategy // {} + availableReplicas: .status.availableReplicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + labels: .metadata.labels + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/statefulsets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-StatefulSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + blueprint: '"workload"' + properties: + kind: '"StatefulSet"' + labels: .metadata.labels + creationTimestamp: .metadata.creationTimestamp + strategyConfig: .spec.strategy // {} + replicas: .spec.replicas + availableReplicas: .status.availableReplicas + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + Namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: apps/v1/replicasets + selector: + query: .metadata.namespace | startswith("kube") | not + port: + entity: + mappings: + - identifier: .metadata.name + "-ReplicaSet-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Deployment"' + blueprint: '"replicaSet"' + properties: + creationTimestamp: .metadata.creationTimestamp + replicas: .spec.replicas + hasPrivileged: .spec.template.spec.containers | [.[].securityContext.privileged] | any + hasLatest: .spec.template.spec.containers[].image | contains(":latest") + hasLimits: .spec.template.spec.containers | all(has("resources") and (.resources.limits.memory and .resources.limits.cpu)) + strategy: .spec.strategy.type // "" + availableReplicas: .status.availableReplicas + labels: .metadata.labels + containers: (.spec.template.spec.containers | map({name, image, resources})) + isHealthy: if .spec.replicas == .status.availableReplicas then "Healthy" else "Unhealthy" end + relations: + replicaSetManager: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME // [] + + # Pods who are owned by replica-sets are connected directly to their deployment + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind == "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + replicaSet: .metadata.ownerReferences[0].name + "-" + "ReplicaSet" + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME // "" + + + # Pods that are not managed by replicasets->deployments (daemonsets, statefulsets etc) + - kind: v1/pods + selector: + query: (.metadata.ownerReferences[0].kind != "ReplicaSet") and (.metadata.namespace | startswith("kube") | not) + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Microservices"' + blueprint: '"pod"' + properties: + startTime: .status.startTime + phase: .status.phase + labels: .metadata.labels + containers: (.spec.containers | map({image, resources})) + .status.containerStatuses | group_by(.image) | map(add) + conditions: .status.conditions + relations: + workload: .metadata.ownerReferences[0].name + "-" + .metadata.ownerReferences[0].kind + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + Node: (.spec.nodeName) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + + - kind: v1/nodes + port: + entity: + mappings: + - identifier: (.metadata.name) | (split(".")|join("_")) + "-" + env.CLUSTER_NAME + title: .metadata.name + "-" + env.CLUSTER_NAME + icon: '"Node"' + blueprint: '"node"' + properties: + creationTimestamp: .metadata.creationTimestamp + totalCPU: .status.allocatable.cpu + totalMemory: .status.allocatable.memory + labels: .metadata.labels + kubeletVersion: .status.nodeInfo.kubeletVersion | split("-") | .[0] + ready: .status.conditions[] | select(.type == "Ready") | .status + relations: + Cluster: env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1/gitrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: source.toolkit.fluxcd.io/v1beta2/helmrepositories + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxSource"' + properties: + repoURL: .spec.url + sourceType: .kind + branch: .spec.ref.branch + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: kustomize.toolkit.fluxcd.io/v1/kustomizations + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + + - kind: helm.toolkit.fluxcd.io/v2beta2/helmreleases + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Fluxcd"' + blueprint: '"fluxApplication"' + properties: + targetNamespace: .spec.targetNamespace + namespace: .metadata.namespace + ready: .status.conditions[] | select(.type == "Ready") | .status + path: .spec.path + prune: .spec.prune + applicationType: .kind + interval: .spec.chart.spec.interval + createdAt: .metadata.creationTimestamp + relations: + source: .spec.chart.spec.sourceRef.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + - kind: aquasecurity.github.io/v1alpha1/configauditreports + port: + entity: + mappings: + - identifier: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME + title: .metadata.name + icon: '"Trivy"' + blueprint: '"trivyVulnerabilities"' + properties: + scanner: .report.scanner.name + criticalCount: .report.summary.criticalCount + highCount: .report.summary.highCount + lowCount: .report.summary.lowCount + mediumCount: .report.summary.mediumCount + category: .report.checks[0].category + message: .report.checks[0].messages + severity: .report.checks[0].severity + scannerVersion: .report.scanner.version + createdAt: .metadata.creationTimestamp + relations: + namespace: .metadata.namespace + "-" + env.CLUSTER_NAME