├── .github ├── pull_request_template.md ├── semantic.yml └── workflows │ ├── kind.yml │ ├── lint.yml │ ├── nightly_quarantine.yml │ └── release.yml ├── .gitignore ├── .golangci.yml ├── .releaserc ├── Dockerfile ├── Dockerfile.fast ├── LICENSE ├── Makefile ├── README.md ├── cmd ├── access.go ├── apply.go ├── backup.go ├── ca.go ├── cleanup.go ├── common.go ├── common_test.go ├── config.go ├── conformance.go ├── consul.go ├── contoller.go ├── dashboard.go ├── db.go ├── deploy.go ├── dns.go ├── docker-images.go ├── docs.go ├── exec.go ├── harbor.go ├── logs.go ├── machine-images.go ├── namespace.go ├── node.go ├── nsx.go ├── operator.go ├── orphan.go ├── provision.go ├── report.go ├── rolling.go ├── seal.go ├── snapshot.go ├── status.go ├── terminate.go ├── test.go ├── undelete.go ├── unseal.go ├── upgrade.go ├── vault.go └── vm.go ├── config ├── crd │ ├── bases │ │ └── karina.flanksource.com_karinaconfigs.yaml │ └── kustomization.yaml ├── deploy │ ├── crd.yml │ └── operator.yml ├── operator │ ├── certmanager │ │ ├── certificate.yaml │ │ ├── kustomization.yaml │ │ └── kustomizeconfig.yaml │ ├── default │ │ ├── kustomization.yaml │ │ ├── manager_auth_proxy_patch.yaml │ │ ├── manager_webhook_patch.yaml │ │ └── webhookcainjection_patch.yaml │ ├── manager │ │ ├── kustomization.yaml │ │ └── manager.yaml │ ├── rbac │ │ ├── kustomization.yaml │ │ ├── leader_election_role.yaml │ │ ├── leader_election_role_binding.yaml │ │ ├── role.yaml │ │ ├── role_binding.yaml │ │ └── service_account.yaml │ └── webhook │ │ ├── kustomization.yaml │ │ ├── kustomizeconfig.yaml │ │ └── service.yaml └── samples │ └── karina.flanksource.com_v1_karina_config.yaml ├── docs ├── Dockerfile ├── Makefile ├── admin-guide │ ├── antrea.md │ ├── auditing.md │ ├── authentication.md │ ├── backup.md │ ├── calico.md │ ├── canary-checker.md │ ├── cluster-lifecycle.md │ ├── cni.md │ ├── configuration.md │ ├── consul.md │ ├── encryption.md │ ├── index.md │ ├── ingress.md │ ├── istio.md │ ├── local-path.md │ ├── logging.md │ ├── minio.md │ ├── multi-tenancy.md │ ├── ncp.md │ ├── opa.md │ ├── persistent-volumes.md │ ├── prometheus.md │ ├── provisioning │ │ ├── ca.md │ │ ├── dns.md │ │ ├── kind.md │ │ ├── machine-images.md │ │ ├── master-discovery.md │ │ ├── vcenter.md │ │ ├── vsphere-platform-example.yaml │ │ └── vsphere.md │ ├── rbac.md │ ├── sealed-secrets.md │ ├── security.md │ ├── sso.md │ ├── thanos.md │ ├── troubleshooting.md │ ├── vault.md │ └── vsphere.md ├── cli │ └── .gitignore ├── comparisons.md ├── configuration.md ├── crds.txt ├── developer-guide │ ├── index.md │ ├── make-targets.md │ └── testing.md ├── img │ ├── Cluster Lifecycle.png │ ├── favicon.png │ ├── logo.png │ └── monitoring.png ├── index.md ├── mkdocs.yml ├── operators │ ├── consul.md │ ├── elastic.md │ ├── git.md │ ├── harbor.md │ ├── platform.md │ ├── postgres.md │ ├── prometheus.md │ ├── rabbitmq.md │ ├── redis.md │ ├── template.md │ └── template │ │ └── index.md ├── overrides │ ├── content.html │ ├── icons │ │ ├── 1.svg │ │ ├── 100.svg │ │ ├── 2.svg │ │ ├── 3.svg │ │ ├── 4.svg │ │ ├── 5.svg │ │ ├── 6.svg │ │ ├── 7.svg │ │ ├── 8.svg │ │ ├── 9.svg │ │ ├── action.svg │ │ ├── alarm.svg │ │ ├── alert.svg │ │ ├── argo-logo.svg │ │ ├── argo-stacked-color.svg │ │ ├── argo.svg │ │ ├── asterix.svg │ │ ├── azure-pipelines.svg │ │ ├── azure-repos.svg │ │ ├── bash.svg │ │ ├── beats.svg │ │ ├── bomb.svg │ │ ├── book.svg │ │ ├── captain.svg │ │ ├── check.svg │ │ ├── cni.svg │ │ ├── cobweb.svg │ │ ├── construction.svg │ │ ├── consul.svg │ │ ├── containerdPull.svg │ │ ├── containerdPush.svg │ │ ├── danager.svg │ │ ├── dex-logo.svg │ │ ├── dex-stacked-color.svg │ │ ├── dex.svg │ │ ├── dns.svg │ │ ├── dockerPull.svg │ │ ├── dockerPush.svg │ │ ├── eck.svg │ │ ├── elastic.svg │ │ ├── elasticsearch.svg │ │ ├── etcd.svg │ │ ├── exclamation.svg │ │ ├── explode.svg │ │ ├── finish.svg │ │ ├── fire.svg │ │ ├── flux.svg │ │ ├── git.svg │ │ ├── github.svg │ │ ├── grafana.svg │ │ ├── harbor.svg │ │ ├── hash.svg │ │ ├── helm-icon-color.svg │ │ ├── helm.svg │ │ ├── http.svg │ │ ├── https.svg │ │ ├── icmp.svg │ │ ├── json.svg │ │ ├── k8s │ │ │ ├── c-role.svg │ │ │ ├── cm.svg │ │ │ ├── crb.svg │ │ │ ├── crd.svg │ │ │ ├── cronjob.svg │ │ │ ├── deploy.svg │ │ │ ├── ds.svg │ │ │ ├── ep.svg │ │ │ ├── group.svg │ │ │ ├── hpa.svg │ │ │ ├── ing.svg │ │ │ ├── job.svg │ │ │ ├── limits.svg │ │ │ ├── netpol.svg │ │ │ ├── ns.svg │ │ │ ├── pod.svg │ │ │ ├── psp.svg │ │ │ ├── pv.svg │ │ │ ├── pvc.svg │ │ │ ├── quota.svg │ │ │ ├── rb.svg │ │ │ ├── role.svg │ │ │ ├── rs.svg │ │ │ ├── sa.svg │ │ │ ├── sc.svg │ │ │ ├── secret.svg │ │ │ ├── sts.svg │ │ │ ├── svc.svg │ │ │ ├── user.svg │ │ │ └── vol.svg │ │ ├── keyboard.svg │ │ ├── kibaba.svg │ │ ├── kibana.svg │ │ ├── kubernetes.svg │ │ ├── ldap.svg │ │ ├── logstash.svg │ │ ├── memcached-ar21.svg │ │ ├── memcached-icon.svg │ │ ├── nginx.svg │ │ ├── ok.svg │ │ ├── opa-logo.svg │ │ ├── opa.svg │ │ ├── operator.svg │ │ ├── postgres.svg │ │ ├── prometheus-logo.svg │ │ ├── prometheus-stacked-color.svg │ │ ├── prometheus.svg │ │ ├── question.svg │ │ ├── rabbitmq-logo.svg │ │ ├── rabbitmq.svg │ │ ├── redis-logo.svg │ │ ├── redis.svg │ │ ├── s3.svg │ │ ├── shell.svg │ │ ├── silence.svg │ │ ├── silence2.svg │ │ ├── skull.svg │ │ ├── snowflake.svg │ │ ├── speak.svg │ │ ├── ssl.svg │ │ ├── star.svg │ │ ├── tag.svg │ │ ├── talk.svg │ │ ├── target.svg │ │ ├── terraform-enterprise.svg │ │ ├── thanos-logo.svg │ │ ├── thanos-stacked-color.svg │ │ ├── thanos.svg │ │ ├── trafficlight.svg │ │ ├── vault.svg │ │ ├── vmware.svg │ │ ├── warn.svg │ │ ├── webhook.svg │ │ ├── wifi.svg │ │ └── worker.svg │ └── style.css ├── reference │ ├── .keep │ └── config.md ├── requirements.txt └── user-guide │ ├── annotations.md │ ├── canary-checker.md │ ├── configuration.md │ ├── gitops.md │ ├── index.md │ ├── ingress.md │ ├── install.md │ ├── logging.md │ ├── opa.md │ ├── petclinic.yaml │ ├── prometheus.md │ ├── secrets.md │ ├── templating.md │ └── tls.md ├── go.mod ├── go.sum ├── hack └── boilerplate.go.txt ├── main.go ├── manifests ├── Makefile ├── antrea.yaml ├── apacheds.yaml ├── argo-rollouts.yaml ├── argocd-operator.yaml ├── argocd-rbac.yaml ├── auditbeat.yaml ├── calico.yaml ├── canary-checker-monitoring.yaml.raw ├── canary-checker.yaml ├── cert-manager-clusterissuer.yaml ├── cert-manager-monitor.yaml.raw ├── cert-manager.yaml ├── configmap-reloader.yaml ├── crd │ ├── antrea.yaml │ ├── argo-rollouts.yaml │ ├── argocd-operator.yaml │ ├── calico.yaml │ ├── canary-checker.yaml │ ├── cert-manager.yaml │ ├── eck.yaml │ ├── flux.yaml │ ├── gatekeeper.yaml │ ├── git-operator.yaml │ ├── grafana-operator.yaml │ ├── istio.yaml │ ├── karina-operator.yaml │ ├── logs-exporter.yaml │ ├── mongo-db.yaml │ ├── mongodb-operator.yaml │ ├── platform-operator.yaml │ ├── postgres-operator.yaml │ ├── postgresql-db.yaml │ ├── prometheus.yaml │ ├── rabbitmq.yaml │ ├── redis-db.yaml │ ├── redis.yaml │ ├── sealed-secrets.yaml │ ├── service-monitor.yaml │ ├── template-operator.yaml │ ├── velero.yaml │ └── vpa.yaml ├── cron.yaml ├── csi-s3.yaml ├── dex.cfg ├── dex.yaml ├── eck.yaml ├── elasticsearch.yaml ├── eventrouter.yaml ├── external-dns.yaml ├── filebeat.yaml ├── flux-monitor.yaml ├── flux.yaml ├── gatekeeper │ ├── allowed-repos.yaml │ ├── banned-image-tags.yaml │ ├── block-nodeports.yaml │ ├── container-limits.yaml │ ├── container-resource-ratios.yaml │ ├── deny-all.yaml │ ├── disallowed-tags.yaml │ ├── required-annotations.yaml │ ├── required-labels.yaml │ ├── required-probes.yaml │ └── unique-ingress-host.yaml ├── git-operator.yaml ├── harbor │ ├── chartmuseum.yaml │ ├── core.yaml │ ├── exporter.yaml │ ├── jobservice.yaml │ ├── portal.yaml │ ├── redis.yaml │ ├── registry.yaml │ └── trivy.yaml ├── images.yaml ├── istio-operator.yaml ├── journalbeat.yaml ├── k8s-dashboard.yaml ├── karina-operator.yaml ├── local-path.yaml ├── logs-exporter.yaml ├── minio.yaml ├── modsecurity-configuration.yaml ├── modsecurity-filebeat.yaml ├── mongodb-operator.yaml ├── monitoring │ ├── alertmanager-configs.yaml │ ├── alertmanager-rules.yaml.raw │ ├── dashboards │ │ ├── alerts.json.raw │ │ ├── canary-checker.json.raw │ │ ├── cert-manager.json.raw │ │ ├── cluster-dash.json.raw │ │ ├── cluster-total.json │ │ ├── coredns.json.raw │ │ ├── docker.json.raw │ │ ├── elasticsearch.json │ │ ├── harbor-exporter.json.raw │ │ ├── harbor.json.raw │ │ ├── k8s-resources-cluster.json │ │ ├── k8s-resources-namespace.json │ │ ├── k8s-resources-node.json │ │ ├── k8s-resources-pod.json │ │ ├── k8s-resources-workload.json │ │ ├── k8s-resources-workloads-namespace.json │ │ ├── kubelet.json.raw │ │ ├── kubernetes-cluster-rev2.json.raw │ │ ├── log-counts.json.raw │ │ ├── namespace-by-pod.json │ │ ├── namespace-by-workload.json │ │ ├── namespaces.json.raw │ │ ├── netstat.json │ │ ├── nginx-ingress-controller-rev1.json.raw │ │ ├── node-cluster-rsrc-use.json │ │ ├── node-rsrc-use.json │ │ ├── nodes.json │ │ ├── patroni.json.raw │ │ ├── persistentvolumesusage.json │ │ ├── pod-total.json │ │ ├── pods.json │ │ ├── prometheus.json │ │ ├── proxy.json │ │ ├── statefulset.json │ │ ├── summary-nodes.json.raw │ │ ├── summary-pvc.json.raw │ │ ├── unmanaged │ │ │ ├── etcd.json │ │ │ ├── grafana-dashboard-apiserver.json │ │ │ ├── grafana-dashboard-controller-manager.json │ │ │ └── grafana-dashboard-scheduler.json │ │ └── workload-total.json │ ├── grafana-operator.yaml │ ├── karma.yaml │ ├── kube-prometheus.yaml │ ├── kube-state-metrics.yaml │ ├── kubernetes-rules.yaml.raw │ ├── namespace-rules.yaml.raw │ ├── nginx-alerts.yaml.raw │ ├── node-exporter.yaml │ ├── prometheus-adapter.yaml │ ├── prometheus-operator-rules.yaml.raw │ ├── prometheus-operator.yaml │ ├── pushgateway.yaml │ ├── service-monitors.yaml │ ├── thanos │ │ ├── base.yaml │ │ ├── compactor.yaml │ │ ├── querier.yaml │ │ └── store.yaml │ └── unmanaged │ │ ├── alertmanager-rules.yaml.raw │ │ └── service-monitors.yaml ├── nfs.yaml ├── nginx-oauth.yaml ├── nginx.yaml ├── nginx │ ├── evp.lua │ ├── hmac.lua │ ├── jwt-validators.lua │ ├── jwt.lua │ └── oauth2_group_access.lua ├── node-local-dns.yaml ├── opa-gatekeeper-monitoring.yaml.raw ├── opa-gatekeeper.yaml ├── opa-kubemgmt.yaml ├── packetbeat.yaml ├── platform-operator.yaml ├── postgres-exporter-config.yaml ├── postgres-operator-config.yaml ├── postgres-operator-monitoring.yaml.raw ├── postgres-operator.yaml ├── rabbitmq.yaml ├── rbac.yaml ├── redis-operator.yaml ├── registry-creds-secrets.yaml ├── registry-creds.yaml ├── sealed-secrets.yaml ├── static.go ├── template-operator.yaml ├── template │ ├── mongo-db.yaml.raw │ ├── postgresql-db.yaml.raw │ └── redis-db.yaml.raw ├── test │ ├── argo-rollouts.yaml │ └── percona-server-mongodb.yaml ├── upstream │ ├── .gitignore │ ├── argo-rollouts │ │ ├── base │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── argocd-operator │ │ └── crd │ │ │ └── kustomization.yaml │ ├── calico │ │ └── crd │ │ │ └── kustomization.yaml │ ├── canary-checker │ │ ├── base │ │ │ ├── kustomization.yaml │ │ │ └── servicemonitor.yaml │ │ ├── crd │ │ │ └── kustomization.yaml │ │ └── helm │ │ │ ├── chart.yaml │ │ │ └── values.yaml │ ├── cert-manager │ │ ├── base │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── eck │ │ ├── base │ │ │ ├── certificate.yaml │ │ │ ├── delete-secret.yaml │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── external-dns │ │ └── base │ │ │ └── kustomization.yaml │ ├── flux │ │ ├── base │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── gatekeeper │ │ └── crd │ │ │ └── kustomization.yaml │ ├── git-operator │ │ ├── base │ │ │ ├── ingress.yaml │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── grafana-operator │ │ └── crd │ │ │ └── kustomization.yaml │ ├── istio │ │ └── crd │ │ │ └── kustomization.yaml │ ├── karina-operator │ │ ├── base │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── logs-exporter │ │ ├── base │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── mongo-db │ │ ├── crd │ │ │ └── kustomization.yaml │ │ └── template │ │ │ └── kustomization.yaml │ ├── mongodb-operator │ │ ├── base │ │ │ ├── kustomization.yaml │ │ │ ├── operator-patch.yaml │ │ │ └── rbac.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── monitoring │ │ ├── grafana-operator │ │ │ └── base │ │ │ │ └── kustomization.yaml │ │ ├── prometheus-adapter │ │ │ └── base │ │ │ │ └── kustomization.yaml │ │ ├── prometheus-operator-rules │ │ │ └── base │ │ │ │ └── kustomization.yaml │ │ └── prometheus-operator │ │ │ └── base │ │ │ └── kustomization.yaml │ ├── platform-operator │ │ ├── base │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── postgres-operator │ │ └── crd │ │ │ └── kustomization.yaml │ ├── postgresql-db │ │ ├── crd │ │ │ └── kustomization.yaml │ │ └── template │ │ │ └── kustomization.yaml │ ├── prometheus │ │ └── crd │ │ │ └── kustomization.yaml │ ├── redis-db │ │ ├── crd │ │ │ └── kustomization.yaml │ │ └── template │ │ │ └── kustomization.yaml │ ├── redis │ │ └── crd │ │ │ └── kustomization.yaml │ ├── sealed-secrets │ │ └── crd │ │ │ └── kustomization.yaml │ ├── service-monitor │ │ └── crd │ │ │ └── kustomization.yaml │ ├── template-operator │ │ ├── base │ │ │ └── kustomization.yaml │ │ └── crd │ │ │ └── kustomization.yaml │ ├── velero │ │ └── crd │ │ │ └── kustomization.yaml │ └── vpa │ │ └── crd │ │ └── kustomization.yaml ├── vault.yaml ├── velero.yaml ├── vpa.yaml ├── vsphere-cpi.yaml └── vsphere-csi.yaml ├── pkg ├── api │ ├── argocd │ │ ├── argocd_types.go │ │ ├── argocdexport_types.go │ │ └── zz_generated.deepcopy.go │ ├── calico │ │ ├── bgpconfig.go │ │ ├── bgppeer.go │ │ ├── constant.go │ │ ├── ippool.go │ │ ├── register.go │ │ └── zz_generated.deepcopy.go │ ├── certmanager │ │ └── util.go │ ├── consul.go │ ├── elasticsearch │ │ └── model.go │ ├── kubeadm.go │ ├── operator │ │ └── v1 │ │ │ ├── groupversion_info.go │ │ │ ├── karina_config.go │ │ │ └── zz_generated.deepcopy.go │ ├── platformoperator │ │ └── v1 │ │ │ ├── clusterresourcequota_types.go │ │ │ ├── groupversion_info.go │ │ │ ├── webhook_types.go │ │ │ └── zz_generated.deepcopy.go │ ├── postgres │ │ ├── cluster_config.go │ │ ├── types.go │ │ └── zz_deep_copy.go │ ├── prometheus │ │ ├── register.go │ │ └── v1 │ │ │ ├── doc.go │ │ │ ├── register.go │ │ │ ├── thanos_types.go │ │ │ ├── types.go │ │ │ └── zz_generated.deepcopy.go │ └── secrets.go ├── ca │ ├── ca.go │ ├── generate.go │ └── validate.go ├── client │ ├── dns │ │ ├── dns.go │ │ ├── dummy.go │ │ └── route53.go │ └── postgres │ │ ├── patroni.go │ │ ├── restic.go │ │ └── tasks.go ├── constants │ ├── const.go │ └── runtime_objects.go ├── controller │ └── burnin │ │ └── burnin.go ├── elastic │ └── export.go ├── nsx │ ├── client.go │ └── types.go ├── operator │ ├── karina_config_controller.go │ └── operator.go ├── phases │ ├── antrea │ │ ├── install.go │ │ └── test.go │ ├── apacheds │ │ ├── install.go │ │ └── test.go │ ├── argocdoperator │ │ ├── install.go │ │ └── test.go │ ├── argorollouts │ │ ├── install.go │ │ └── test.go │ ├── auditbeat │ │ └── install.go │ ├── base │ │ ├── install.go │ │ └── test.go │ ├── calico │ │ ├── install.go │ │ └── test.go │ ├── canary │ │ ├── deploy.go │ │ └── test.go │ ├── certmanager │ │ ├── install.go │ │ └── test.go │ ├── configmapreloader │ │ ├── install.go │ │ └── test.go │ ├── conformance.go │ ├── consul │ │ ├── tasks.go │ │ └── test.go │ ├── crds │ │ └── install.go │ ├── csi │ │ ├── localpath │ │ │ ├── install.go │ │ │ └── test.go │ │ ├── nfs │ │ │ ├── install.go │ │ │ └── test.go │ │ └── s3 │ │ │ ├── install.go │ │ │ └── test.go │ ├── dashboard │ │ └── install.go │ ├── dex │ │ ├── install.go │ │ └── test.go │ ├── eck │ │ ├── install.go │ │ └── test.go │ ├── elasticsearch │ │ ├── install.go │ │ └── test.go │ ├── eventrouter │ │ └── deploy.go │ ├── externaldns │ │ ├── install.go │ │ └── test.go │ ├── filebeat │ │ └── install.go │ ├── flux │ │ ├── fluxv2.go │ │ └── test.go │ ├── gitoperator │ │ ├── install.go │ │ └── test.go │ ├── harbor │ │ ├── client.go │ │ ├── defaults.go │ │ ├── install.go │ │ ├── operations.go │ │ └── test.go │ ├── ingress │ │ └── install.go │ ├── istiooperator │ │ ├── install.go │ │ └── test.go │ ├── journalbeat │ │ └── install.go │ ├── karinaoperator │ │ ├── install.go │ │ └── test.go │ ├── konfigadm.go │ ├── kubeadm │ │ ├── kubeadm.go │ │ └── test.go │ ├── logsexporter │ │ └── install.go │ ├── minio │ │ ├── install.go │ │ └── test.go │ ├── mongodboperator │ │ ├── install.go │ │ └── test.go │ ├── monitoring │ │ ├── monitoring.go │ │ └── test.go │ ├── nginx │ │ ├── install.go │ │ └── test.go │ ├── nodelocaldns │ │ ├── install.go │ │ └── test.go │ ├── opa │ │ ├── deploy.go │ │ ├── install.go │ │ └── test.go │ ├── order │ │ └── order.go │ ├── packetbeat │ │ └── deploy.go │ ├── platformoperator │ │ ├── install.go │ │ └── test.go │ ├── postgresoperator │ │ ├── install.go │ │ ├── tasks.go │ │ └── test.go │ ├── pre │ │ └── install.go │ ├── rabbitmqoperator │ │ ├── install.go │ │ └── test.go │ ├── redisoperator │ │ ├── install.go │ │ └── test.go │ ├── registrycreds │ │ ├── install.go │ │ └── test.go │ ├── sealedsecrets │ │ ├── install.go │ │ └── test.go │ ├── snapshot │ │ └── snapshot.go │ ├── templateoperator │ │ ├── install.go │ │ └── test.go │ ├── vault │ │ ├── install.go │ │ ├── tasks.go │ │ └── test.go │ ├── velero │ │ ├── install.go │ │ ├── test.go │ │ └── types.go │ ├── vpa │ │ ├── deploy.go │ │ └── test.go │ └── vsphere │ │ ├── install.go │ │ └── test.go ├── platform │ ├── consul.go │ ├── dnsroundrobin.go │ ├── hooks.go │ ├── kind.go │ ├── nsx.go │ ├── platform.go │ └── vm.go ├── provision │ ├── cluster.go │ ├── kind.go │ ├── rolling.go │ ├── status.go │ ├── terminate.go │ ├── upgrade.go │ ├── vm.go │ ├── vmware │ │ ├── clone.go │ │ ├── clone_template.go │ │ ├── cluster.go │ │ ├── list.go │ │ ├── session.go │ │ └── vm.go │ └── vsphere.go ├── reports │ └── quotas.go ├── status │ └── gatekeeper.go ├── test │ └── dex_oauth.go └── types │ ├── api.go │ ├── config.go │ ├── default.go │ ├── inline.go │ ├── nsx.go │ ├── types.go │ └── zz_generated.deepcopy.go ├── scripts ├── generate_kind_image.sh └── golint.sh └── test ├── _minio.yaml ├── _monitoring.yaml ├── canary-checker.yaml ├── cicd.yaml ├── coredns.yaml ├── elastic.yaml ├── encrypted.yaml.enc ├── fixtures ├── audit-policy.yaml ├── canary-config.yaml ├── encryption-config.yaml ├── konfigadm-template.yaml ├── ldap.yaml ├── overwrite.yaml ├── simple.yaml ├── template-test.yaml └── unrecognized-fields.yaml ├── gatekeeper.yaml ├── harbor2.yaml ├── hosted-tests.yaml ├── linter.yaml ├── linter └── main.go ├── managed.yaml ├── manifests └── elastic │ ├── elastic.yaml │ ├── eval.sh │ └── kustomization.yaml ├── minimal-antrea.yaml ├── minimal.yaml ├── monitoring.yaml ├── nosql.yaml ├── opa ├── bundles │ ├── .manifest │ ├── automobile.tar.gz │ └── automobile │ │ └── data.json ├── constraints │ ├── ban-latest-tag.yaml │ ├── must-have-probes.yaml │ └── whitelist-registries.yaml ├── gatekeeper-fixtures │ ├── accepted │ │ ├── deployment-valid.yaml │ │ └── pod-valid.yaml │ ├── rejected │ │ └── deployment-invalid.yaml │ └── resources │ │ └── resources.yaml ├── opa-fixtures │ ├── accepted │ │ ├── deployment-valid.yaml │ │ ├── ingress-whitelisted.yaml │ │ ├── namespace-valid.yaml │ │ └── pod-valid.yaml │ ├── rejected │ │ ├── deployment-invalid-no-tag.yaml │ │ ├── deployment-invalid-probes-liveness.yaml │ │ ├── deployment-invalid-probes-readiness.yaml │ │ ├── deployment-invalid-registry.yaml │ │ ├── deployment-invalid-wrong-tag.yaml │ │ ├── ingress-invalid-conflict.yaml │ │ ├── ingress-invalid-not-whitelisted.yaml │ │ ├── namespace-invalid-no-company-lables.yaml │ │ ├── namespace-invalid-wrong-company.yaml │ │ ├── namespace-invalid-wrong-service.yaml │ │ ├── pod-invalid-no-tag.yaml │ │ ├── pod-invalid-probes.yaml │ │ ├── pod-invalid-registry.yaml │ │ └── pod-invalid-wrong-tag.yaml │ └── resources │ │ └── resources.yaml └── policies │ ├── check-image.rego │ ├── check-ingress-conflict.rego │ ├── check-ingress-whitelist.rego │ ├── check-liveness.rego │ ├── check-ns.rego │ └── check-readiness.rego ├── patch1.yaml ├── platform.yaml ├── postgres.yaml ├── quarantine.yaml ├── secure.yaml ├── security.yaml ├── templatePatch.yaml ├── test.sh ├── test.yaml ├── tesults.yaml ├── upgrade.sh └── vsphere-harbor.yaml /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | _Short summary of what is the issue and the solution._ 4 | 5 | ### Dependencies 6 | 7 | - _Ex. Other PRs._ 8 | 9 | ### Breaking Change 10 | 11 | - [ ] Yes 12 | - [ ] No 13 | 14 | ### Testing Notes 15 | 16 | **What I did:** 17 | _What did you do to validate this PR?_ 18 | 19 | **How you can replicate my testing:** 20 | _How can the reviewer validate this PR?_ 21 | 22 | ### **Links** 23 | 24 | _Issues links or other related resources_ 25 | -------------------------------------------------------------------------------- /.github/semantic.yml: -------------------------------------------------------------------------------- 1 | # Always validate all commits, and ignore the PR title 2 | commitsOnly: true 3 | 4 | # Allow use of Merge commits (eg on github: "Merge branch 'master' into feature/ride-unicorns") 5 | # this is only relevant when using commitsOnly: true (or titleAndCommits: true) 6 | allowMergeCommits: true 7 | 8 | # Allow use of Revert commits (eg on github: "Revert "feat: ride unicorns"") 9 | # this is only relevant when using commitsOnly: true (or titleAndCommits: true) 10 | allowRevertCommits: true 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | build-tools* 3 | .bin/ 4 | .ref/ 5 | .kind/ 6 | .go/ 7 | *_cert.yaml 8 | *-admin.yml 9 | *.env 10 | config*.yaml 11 | config*.yml 12 | #TODO: verify intent of ignoring docs/*.md at PR 13 | #docs/*.md 14 | .DS_Store 15 | *-packr.go 16 | packrd/ 17 | dist/ 18 | hack/ 19 | .kube/ 20 | .helm/ 21 | .manifests/ 22 | kind 23 | test-results/ 24 | artifacts/ 25 | snapshot/ 26 | vendor/ 27 | .idea 28 | .vscode 29 | *.swp 30 | .certs 31 | .sops.* 32 | manifests/bin 33 | #goland ide generated files: 34 | __debug_bin 35 | .scratchpad 36 | .pid 37 | karina.iml 38 | docs/site/ 39 | docs/build/ 40 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | # timeout for analysis, e.g. 30s, 5m, default is 1m 3 | timeout: 20m 4 | 5 | skip-dirs: 6 | - ./pkg/k8s/etcd 7 | - ./pkg/k8s/drain 8 | - ./pkg/k8s/proxy 9 | skip-files: 10 | - pkg/api/certmanager/types.go 11 | 12 | linters: 13 | # please, do not use `enable-all`: it's deprecated and will be removed soon. 14 | # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint 15 | disable-all: true 16 | enable: 17 | - bodyclose 18 | - deadcode 19 | - depguard 20 | - dogsled 21 | - errcheck 22 | - goconst 23 | - gofmt 24 | - goimports 25 | - goprintffuncname 26 | - gosimple 27 | - govet 28 | - ineffassign 29 | - misspell 30 | - nakedret 31 | - revive 32 | - rowserrcheck 33 | - staticcheck 34 | - structcheck 35 | - stylecheck 36 | - typecheck 37 | - unconvert 38 | - unparam 39 | - unused 40 | - varcheck 41 | - whitespace 42 | 43 | linters-settings: 44 | gofmt: 45 | simplify: false 46 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | plugins: 2 | - - "@semantic-release/commit-analyzer" 3 | - releaseRules: 4 | - { type: doc, scope: README, release: patch } 5 | - { type: fix, release: patch } 6 | - { type: chore, release: patch } 7 | - { type: refactor, release: patch } 8 | - { type: feat, release: minor } 9 | - { type: ci, release: false } 10 | - { type: style, release: false } 11 | parserOpts: 12 | noteKeywords: 13 | - MAJOR RELEASE 14 | - "@semantic-release/release-notes-generator" 15 | - - "@semantic-release/github" 16 | - assets: 17 | - path: ./.bin/karina 18 | name: karina 19 | - path: ./.bin/karina_osx 20 | name: karina_osx 21 | -------------------------------------------------------------------------------- /Dockerfile.fast: -------------------------------------------------------------------------------- 1 | FROM ubuntu:bionic 2 | ARG SYSTOOLS_VERSION=3.6 3 | 4 | RUN apt-get update && \ 5 | apt-get install -y genisoimage gnupg-agent curl apt-transport-https wget jq git sudo python-setuptools python-pip python-dev build-essential xz-utils ca-certificates unzip zip software-properties-common && \ 6 | rm -Rf /var/lib/apt/lists/* && \ 7 | rm -Rf /usr/share/doc && rm -Rf /usr/share/man && \ 8 | apt-get clean 9 | 10 | RUN wget -nv --no-check-certificate https://github.com/moshloop/systools/releases/download/${SYSTOOLS_VERSION}/systools.deb && dpkg -i systools.deb 11 | ARG SOPS_VERSION=3.5.0 12 | RUN install_deb https://github.com/mozilla/sops/releases/download/v${SOPS_VERSION}/sops_${SOPS_VERSION}_amd64.deb 13 | RUN install_bin https://github.com/CrunchyData/postgres-operator/releases/download/v4.1.0/expenv 14 | RUN install_bin https://github.com/hongkailiu/gojsontoyaml/releases/download/e8bd32d/gojsontoyaml 15 | RUN pip install awscli 16 | 17 | ADD .bin/static/karina /bin/karina 18 | 19 | ENTRYPOINT [ "/bin/karina" ] 20 | -------------------------------------------------------------------------------- /cmd/apply.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "io/ioutil" 5 | 6 | log "github.com/sirupsen/logrus" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | var Apply = &cobra.Command{ 11 | Use: "apply", 12 | Short: "Apply a configuration to a resource by filename", 13 | Args: cobra.MinimumNArgs(1), 14 | Run: func(cmd *cobra.Command, args []string) { 15 | 16 | ns, _ := cmd.Flags().GetString("namespace") 17 | p := getPlatform(cmd) 18 | for _, spec := range args { 19 | data, err := ioutil.ReadFile(spec) 20 | if err != nil { 21 | log.Fatalf("Could not read %s: %v", spec, err) 22 | } 23 | template, err := p.TemplateText(string(data)) 24 | if err != nil { 25 | log.Fatalf("failed to template %s: %v", spec, err) 26 | } 27 | if err := p.ApplyText(ns, template); err != nil { 28 | log.Fatalf("failed to apply %s: %v", spec, err) 29 | } 30 | } 31 | }, 32 | } 33 | 34 | func init() { 35 | Apply.Flags().StringP("namespace", "n", "", "The namespace to apply") 36 | } 37 | -------------------------------------------------------------------------------- /cmd/backup.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | log "github.com/sirupsen/logrus" 5 | "github.com/spf13/cobra" 6 | 7 | "github.com/flanksource/karina/pkg/phases/velero" 8 | ) 9 | 10 | var Backup = &cobra.Command{ 11 | Use: "backup", 12 | Short: "Create new velero backup", 13 | Args: cobra.MinimumNArgs(0), 14 | Run: func(cmd *cobra.Command, args []string) { 15 | if _, err := velero.CreateBackup(getPlatform(cmd)); err != nil { 16 | log.Fatalf("Error creating backup %v", err) 17 | } 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /cmd/config.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var Config = &cobra.Command{ 10 | Use: "config", 11 | Short: "Commands for working with config files", 12 | } 13 | 14 | var validateConfig = &cobra.Command{ 15 | Use: "validate", 16 | Short: "Validate config", 17 | Args: cobra.MinimumNArgs(0), 18 | Run: func(cmd *cobra.Command, args []string) { 19 | p := getPlatform(cmd) 20 | config := p.String() 21 | fmt.Printf("Generated config is:\n%s\n", config) 22 | }, 23 | } 24 | 25 | func init() { 26 | Config.AddCommand(validateConfig) 27 | } 28 | -------------------------------------------------------------------------------- /cmd/contoller.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/spf13/cobra" 7 | 8 | "github.com/flanksource/karina/pkg/controller/burnin" 9 | ) 10 | 11 | var burninControllerPeriod time.Duration 12 | var BurninController = &cobra.Command{ 13 | Use: "burnin-controller", 14 | // Short: "Commands for provisioning clusters and VMs", 15 | Run: func(cmd *cobra.Command, args []string) { 16 | // first we start a burnin controller in the background that checks 17 | // new nodes with the burnin taint for health, removing the taint 18 | // once they become healthy 19 | burninCancel := make(chan bool) 20 | burnin.Run(getPlatform(cmd), burninControllerPeriod, burninCancel) 21 | }, 22 | } 23 | 24 | func init() { 25 | BurninController.Flags().DurationVar(&burninControllerPeriod, "burnin-period", time.Minute*3, "Period to burn-in new nodes before scheduling workloads on") 26 | } 27 | -------------------------------------------------------------------------------- /cmd/dashboard.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "path" 5 | 6 | "github.com/flanksource/karina/pkg/phases/monitoring" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | var Dashboard = &cobra.Command{ 11 | Use: "dashboard", 12 | } 13 | 14 | func init() { 15 | deploy := &cobra.Command{ 16 | Use: "deploy", 17 | Run: func(cmd *cobra.Command, args []string) { 18 | p := getPlatform(cmd) 19 | file, _ := cmd.Flags().GetString("file") 20 | name, _ := cmd.Flags().GetString("name") 21 | folder, _ := cmd.Flags().GetString("folder") 22 | if name == "" { 23 | name = path.Base(file) 24 | } 25 | if err := monitoring.DeployDashboard(p, folder, name, file); err != nil { 26 | p.Fatalf("failed to deploy dashboard: %v", err) 27 | } 28 | p.Infof("Dashboard %s deployed !", name) 29 | }, 30 | } 31 | 32 | deploy.Flags().StringP("file", "f", "", "Grafana dashboard which needs to be deployed") 33 | deploy.Flags().StringP("name", "n", "", "Grafana dashboard name") 34 | deploy.Flags().StringP("folder", "", "Customer", "Grafana dashboard folder name") 35 | Dashboard.AddCommand(deploy) 36 | } 37 | -------------------------------------------------------------------------------- /cmd/machine-images.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | ) 6 | 7 | var MachineImages = &cobra.Command{ 8 | Use: "machine-images", 9 | Aliases: []string{"vm"}, 10 | Short: "Commands for working with machine images", 11 | } 12 | 13 | func init() { 14 | MachineImages.AddCommand(&cobra.Command{ 15 | Use: "list", 16 | Short: "List all machine images currently uploaded", 17 | Args: cobra.MinimumNArgs(0), 18 | Run: func(cmd *cobra.Command, args []string) { 19 | 20 | }, 21 | }) 22 | MachineImages.AddCommand(&cobra.Command{ 23 | Use: "build", 24 | Short: "Builds a new machine-image", 25 | Args: cobra.MinimumNArgs(0), 26 | Run: func(cmd *cobra.Command, args []string) { 27 | 28 | }, 29 | }) 30 | MachineImages.AddCommand(&cobra.Command{ 31 | Use: "upload", 32 | Short: "Uploads a new machine image", 33 | Args: cobra.MinimumNArgs(0), 34 | Run: func(cmd *cobra.Command, args []string) { 35 | 36 | }, 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /cmd/namespace.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/hako/durafmt" 7 | 8 | "github.com/spf13/cobra" 9 | 10 | "time" 11 | ) 12 | 13 | var Namespace = &cobra.Command{ 14 | Use: "namespace", 15 | Short: "Commands for manipulating namespaces", 16 | } 17 | 18 | var timeout time.Duration 19 | 20 | var namespaceForceDelete = &cobra.Command{ 21 | Use: "force-delete", 22 | Short: "Clears the namespace finalizers allowing it to be deleted", 23 | Args: cobra.MinimumNArgs(1), 24 | RunE: func(cmd *cobra.Command, args []string) error { 25 | p := getPlatform(cmd) 26 | 27 | ns := args[0] 28 | fmt.Printf("Clearing finalizers on namespace %v\n", ns) 29 | 30 | duration := durafmt.Parse(timeout).String() 31 | fmt.Printf("Using timeout of %v\n", duration) 32 | 33 | err := p.ForceDeleteNamespace(ns, timeout) 34 | if err != nil { 35 | return fmt.Errorf("clearing the finalizers failed with: %v", err) 36 | } 37 | 38 | return nil 39 | }, 40 | } 41 | 42 | func init() { 43 | namespaceForceDelete.Flags().DurationVar(&timeout, "timeout", time.Minute*2, "specify the timeout") 44 | Namespace.AddCommand(namespaceForceDelete) 45 | } 46 | -------------------------------------------------------------------------------- /cmd/nsx.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | // TODO: Remove this module 4 | 5 | import ( 6 | log "github.com/sirupsen/logrus" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | var NSX = &cobra.Command{ 11 | Use: "nsx", 12 | Short: "Commands for interacting with NSX clusters", 13 | } 14 | 15 | func init() { 16 | logLevel := &cobra.Command{ 17 | Use: "set-log-level", 18 | Short: "Update the logging level", 19 | Run: func(cmd *cobra.Command, args []string) { 20 | level, _ := cmd.Flags().GetString("log-level") 21 | log.Infof("Setting log level to %s", level) 22 | }, 23 | } 24 | 25 | NSX.AddCommand(logLevel) 26 | } 27 | -------------------------------------------------------------------------------- /cmd/orphan.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | var Orphan = &cobra.Command{ 9 | Use: "orphan", 10 | Short: "Remove owner references from an object", 11 | Args: cobra.MinimumNArgs(2), 12 | Run: func(cmd *cobra.Command, args []string) { 13 | platform := getPlatform(cmd) 14 | 15 | kind := args[0] 16 | name := args[1] 17 | namespace, _ := cmd.Flags().GetString("namespace") 18 | 19 | object, found := constants.RuntimeObjects[kind] 20 | if !found { 21 | if err := platform.OrphanCRD(kind, name, namespace); err != nil { 22 | platform.Fatalf("failed to orphan %s %s in namespace %s: %v", kind, name, namespace, err) 23 | } 24 | } else { 25 | if err := platform.Orphan(kind, name, namespace, object); err != nil { 26 | platform.Fatalf("failed to orphan %s %s in namespace %s: %v", kind, name, namespace, err) 27 | } 28 | } 29 | }, 30 | } 31 | 32 | func init() { 33 | Orphan.Flags().StringP("namespace", "n", "", "Namespace where object is present") 34 | } 35 | -------------------------------------------------------------------------------- /cmd/report.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/reports" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | var Report = &cobra.Command{ 9 | Use: "report", 10 | } 11 | 12 | var reportOpts = reports.ReportOptions{} 13 | 14 | func init() { 15 | Report.PersistentFlags().StringVar(&reportOpts.Path, "input", "", "Path to input directory of specs") 16 | Report.PersistentFlags().StringArrayVar(&reportOpts.Annotations, "col", nil, "Annotations to include in the report") 17 | Report.PersistentFlags().StringVar(&reportOpts.Format, "format", "table", "Format of the report, can be one of table,csv") 18 | Report.AddCommand(&cobra.Command{ 19 | Use: "quotas", 20 | RunE: func(cmd *cobra.Command, args []string) error { 21 | return reports.Quotas(reportOpts) 22 | }, 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /cmd/snapshot.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "time" 5 | 6 | log "github.com/sirupsen/logrus" 7 | "github.com/spf13/cobra" 8 | 9 | "github.com/flanksource/karina/pkg/phases/snapshot" 10 | ) 11 | 12 | var opts = snapshot.Options{} 13 | var Snapshot = &cobra.Command{ 14 | Use: "snapshot", 15 | Short: "Take a snapshot of the running system", 16 | Args: cobra.MinimumNArgs(0), 17 | Run: func(cmd *cobra.Command, args []string) { 18 | opts.Namespaces = args 19 | if err := snapshot.Take(getPlatform(cmd), opts); err != nil { 20 | log.Fatalf("Failed to get cluster snapshot, %s", err) 21 | } 22 | }, 23 | } 24 | 25 | func init() { 26 | Snapshot.Flags().StringVarP(&opts.Destination, "output-dir", "o", "snapshot", "Output directory for snapshot") 27 | since, _ := time.ParseDuration("4h") 28 | Snapshot.Flags().DurationVar(&opts.LogsSince, "since", since, "Return logs newer than a relative duration like 5s, 2m, or 3h") 29 | Snapshot.Flags().BoolVarP(&opts.IncludeSpecs, "include-specs", "", false, "Export yaml specs") 30 | Snapshot.Flags().BoolVarP(&opts.IncludeEvents, "include-events", "", true, "Export events") 31 | Snapshot.Flags().BoolVarP(&opts.IncludeLogs, "include-logs", "", true, "Export logs for pods") 32 | Snapshot.Flags().IntVar(&opts.Concurrency, "concurrency", 1, "Run the export concurrently") 33 | } 34 | -------------------------------------------------------------------------------- /cmd/terminate.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | log "github.com/sirupsen/logrus" 5 | "github.com/spf13/cobra" 6 | 7 | "github.com/flanksource/karina/pkg/provision" 8 | ) 9 | 10 | var Terminate = &cobra.Command{ 11 | Use: "terminate", 12 | Short: "Terminate a cluster and destroy all VM's and resources associated with it", 13 | Args: cobra.MinimumNArgs(0), 14 | Run: func(cmd *cobra.Command, args []string) { 15 | if err := provision.Terminate(getPlatform(cmd)); err != nil { 16 | log.Fatalf("Failed to cleanup cluster, %s", err) 17 | } 18 | }, 19 | } 20 | 21 | var TerminateNodes = &cobra.Command{ 22 | Use: "terminate-node [nodes]", 23 | Short: "Cordon and terminate the specified nodes", 24 | Args: cobra.MinimumNArgs(1), 25 | Run: func(cmd *cobra.Command, args []string) { 26 | if err := provision.TerminateNodes(getPlatform(cmd), args); err != nil { 27 | log.Fatalf("Failed terminate nodes %s", err) 28 | } 29 | }, 30 | } 31 | 32 | var TerminateOrphans = &cobra.Command{ 33 | Use: "terminate-orphans", 34 | Short: "Terminate all orphaned VM's that have not successfully joined the cluster", 35 | Run: func(cmd *cobra.Command, args []string) { 36 | if err := provision.TerminateOrphans(getPlatform(cmd)); err != nil { 37 | log.Fatalf("Failed terminate nodes %s", err) 38 | } 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /cmd/undelete.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | var Undelete = &cobra.Command{ 9 | Use: "undelete", 10 | Short: "Undelete kubernetes objects", 11 | Args: cobra.MinimumNArgs(2), 12 | Run: func(cmd *cobra.Command, args []string) { 13 | platform := getPlatform(cmd) 14 | 15 | kind := args[0] 16 | name := args[1] 17 | namespace, _ := cmd.Flags().GetString("namespace") 18 | 19 | object, found := constants.RuntimeObjects[kind] 20 | if !found { 21 | if err := platform.UndeleteCRD(kind, name, namespace); err != nil { 22 | platform.Fatalf("failed to undelete %s %s in namespace %s: %v", kind, name, namespace, err) 23 | } 24 | } else { 25 | if err := platform.Undelete(kind, name, namespace, object); err != nil { 26 | platform.Fatalf("failed to undelete %s %s in namespace %s: %v", kind, name, namespace, err) 27 | } 28 | } 29 | }, 30 | } 31 | 32 | func init() { 33 | Undelete.Flags().StringP("namespace", "n", "", "Namespace where object is present") 34 | } 35 | -------------------------------------------------------------------------------- /cmd/upgrade.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/flanksource/commons/logger" 5 | "github.com/flanksource/karina/pkg/provision" 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var Upgrade = &cobra.Command{ 10 | Use: "upgrade", 11 | Short: "Upgrade the kubernetes control plane", 12 | Args: cobra.MinimumNArgs(0), 13 | Run: func(cmd *cobra.Command, args []string) { 14 | if err := provision.Upgrade(getPlatform(cmd)); err != nil { 15 | logger.Fatalf("Failed to upgrade cluster, %s", err) 16 | } 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /cmd/vault.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | log "github.com/sirupsen/logrus" 5 | "github.com/spf13/cobra" 6 | 7 | "github.com/flanksource/karina/pkg/phases/vault" 8 | ) 9 | 10 | var Vault = &cobra.Command{ 11 | Use: "vault", 12 | Short: "Commands for working with vault", 13 | } 14 | 15 | func init() { 16 | init := &cobra.Command{ 17 | Use: "init", 18 | Short: "Initialize and import CA into vault", 19 | Args: cobra.MinimumNArgs(0), 20 | Run: func(cmd *cobra.Command, args []string) { 21 | if err := vault.Init(getPlatform(cmd)); err != nil { 22 | log.Fatalf("Failed to initialize vault %v", err) 23 | } 24 | }, 25 | } 26 | 27 | Vault.AddCommand(init) 28 | } 29 | -------------------------------------------------------------------------------- /config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - bases/karina.flanksource.com_karinaconfigs.yaml -------------------------------------------------------------------------------- /config/operator/certmanager/certificate.yaml: -------------------------------------------------------------------------------- 1 | # The following manifests contain a self-signed issuer CR and a certificate CR. 2 | # More document can be found at https://docs.cert-manager.io 3 | # WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for 4 | # breaking changes 5 | apiVersion: cert-manager.io/v1alpha2 6 | kind: Issuer 7 | metadata: 8 | name: selfsigned-issuer 9 | namespace: system 10 | spec: 11 | selfSigned: {} 12 | --- 13 | apiVersion: cert-manager.io/v1alpha2 14 | kind: Certificate 15 | metadata: 16 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 17 | namespace: system 18 | spec: 19 | # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize 20 | dnsNames: 21 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc 22 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local 23 | issuerRef: 24 | kind: Issuer 25 | name: selfsigned-issuer 26 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize 27 | -------------------------------------------------------------------------------- /config/operator/certmanager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - certificate.yaml 3 | 4 | configurations: 5 | - kustomizeconfig.yaml 6 | -------------------------------------------------------------------------------- /config/operator/certmanager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is for teaching kustomize how to update name ref and var substitution 2 | nameReference: 3 | - kind: Issuer 4 | group: cert-manager.io 5 | fieldSpecs: 6 | - kind: Certificate 7 | group: cert-manager.io 8 | path: spec/issuerRef/name 9 | 10 | varReference: 11 | - kind: Certificate 12 | group: cert-manager.io 13 | path: spec/commonName 14 | - kind: Certificate 15 | group: cert-manager.io 16 | path: spec/dnsNames 17 | -------------------------------------------------------------------------------- /config/operator/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: platform-system 2 | bases: 3 | - ../../crd 4 | - ../rbac 5 | - ../manager 6 | -------------------------------------------------------------------------------- /config/operator/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 14 | args: 15 | - "--secure-listen-address=0.0.0.0:8443" 16 | - "--upstream=http://127.0.0.1:8080/" 17 | - "--logtostderr=true" 18 | - "--v=10" 19 | ports: 20 | - containerPort: 8443 21 | name: https 22 | - name: manager 23 | args: 24 | - operator 25 | - "--metrics-addr=127.0.0.1:8080" 26 | - "--enable-leader-election" 27 | - "--log-level=debug" 28 | -------------------------------------------------------------------------------- /config/operator/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | ports: 12 | - containerPort: 9443 13 | name: webhook-server 14 | protocol: TCP 15 | volumeMounts: 16 | - mountPath: /tmp/k8s-webhook-server/serving-certs 17 | name: cert 18 | readOnly: true 19 | volumes: 20 | - name: cert 21 | secret: 22 | defaultMode: 420 23 | secretName: webhook-server-cert 24 | -------------------------------------------------------------------------------- /config/operator/default/webhookcainjection_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch add annotation to admission webhook config and 2 | # the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: MutatingWebhookConfiguration 5 | metadata: 6 | name: mutating-webhook-configuration 7 | annotations: 8 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 9 | --- 10 | apiVersion: admissionregistration.k8s.io/v1 11 | kind: ValidatingWebhookConfiguration 12 | metadata: 13 | name: validating-webhook-configuration 14 | annotations: 15 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 16 | -------------------------------------------------------------------------------- /config/operator/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: platform-system 4 | resources: 5 | - manager.yaml 6 | images: 7 | - name: controller 8 | newName: flanksource/karina 9 | newTag: latest 10 | -------------------------------------------------------------------------------- /config/operator/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: karina 5 | namespace: system 6 | labels: 7 | control-plane: karina-operator 8 | spec: 9 | selector: 10 | matchLabels: 11 | control-plane: karina-operator 12 | replicas: 1 13 | template: 14 | metadata: 15 | labels: 16 | control-plane: karina-operator 17 | spec: 18 | serviceAccountName: karina 19 | containers: 20 | - command: 21 | - /bin/karina 22 | args: 23 | - operator 24 | - --enable-leader-election 25 | - --log-level=debug 26 | image: docker.io/flanksource/karina:latest 27 | imagePullPolicy: IfNotPresent 28 | name: karina-operator 29 | resources: 30 | limits: 31 | cpu: 500m 32 | memory: 256Mi 33 | requests: 34 | cpu: 100m 35 | memory: 128Mi 36 | -------------------------------------------------------------------------------- /config/operator/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: platform-system 2 | resources: 3 | - service_account.yaml 4 | - role.yaml 5 | - role_binding.yaml 6 | - leader_election_role.yaml 7 | - leader_election_role_binding.yaml 8 | -------------------------------------------------------------------------------- /config/operator/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: karina-operator-leader-election 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - "" 21 | resources: 22 | - configmaps/status 23 | verbs: 24 | - get 25 | - update 26 | - patch 27 | - apiGroups: 28 | - "" 29 | resources: 30 | - events 31 | verbs: 32 | - create 33 | -------------------------------------------------------------------------------- /config/operator/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: karina-operator-leader-election 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: karina-operator-leader-election 9 | subjects: 10 | - kind: ServiceAccount 11 | name: karina 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/operator/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRole 5 | metadata: 6 | creationTimestamp: null 7 | name: karina 8 | rules: 9 | - apiGroups: 10 | - '*' 11 | resources: 12 | - '*' 13 | verbs: 14 | - '*' 15 | -------------------------------------------------------------------------------- /config/operator/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: karina-operator 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: karina 9 | subjects: 10 | - kind: ServiceAccount 11 | name: karina 12 | namespace: system -------------------------------------------------------------------------------- /config/operator/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: karina 5 | namespace: system 6 | -------------------------------------------------------------------------------- /config/operator/webhook/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manifests.yaml 3 | - service.yaml 4 | 5 | configurations: 6 | - kustomizeconfig.yaml 7 | -------------------------------------------------------------------------------- /config/operator/webhook/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # the following config is for teaching kustomize where to look at when substituting vars. 2 | # It requires kustomize v2.1.0 or newer to work properly. 3 | nameReference: 4 | - kind: Service 5 | version: v1 6 | fieldSpecs: 7 | - kind: MutatingWebhookConfiguration 8 | group: admissionregistration.k8s.io 9 | path: webhooks/clientConfig/service/name 10 | - kind: ValidatingWebhookConfiguration 11 | group: admissionregistration.k8s.io 12 | path: webhooks/clientConfig/service/name 13 | 14 | namespace: 15 | - kind: MutatingWebhookConfiguration 16 | group: admissionregistration.k8s.io 17 | path: webhooks/clientConfig/service/namespace 18 | create: true 19 | - kind: ValidatingWebhookConfiguration 20 | group: admissionregistration.k8s.io 21 | path: webhooks/clientConfig/service/namespace 22 | create: true 23 | 24 | varReference: 25 | - path: metadata/annotations 26 | -------------------------------------------------------------------------------- /config/operator/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: webhook-service 6 | namespace: system 7 | spec: 8 | ports: 9 | - port: 443 10 | targetPort: 9443 11 | selector: 12 | control-plane: karina-operator 13 | -------------------------------------------------------------------------------- /docs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM squidfunk/mkdocs-material:6.2.8 2 | RUN apk add --update nodejs npm nghttp2-dev unzip 3 | RUN npm install netlify-cli 4 | COPY requirements.txt . 5 | RUN pip install -r requirements.txt 6 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | default: serve 3 | NAME:=karina 4 | CONTAINER:=mkdocs 5 | 6 | 7 | .PHONY: container 8 | container: 9 | docker build -t $(CONTAINER) ./ --build-arg GITHUB_TOKEN=$(GITHUB_TOKEN) 10 | 11 | 12 | .PHONY: serve 13 | serve: container 14 | docker run --rm -it -p 8000:8000 -v $(PWD):/docs -w /docs $(CONTAINER) 15 | 16 | .PHONY: build 17 | build: 18 | which mkdocs || pip3 install mkdocs 19 | pip3 install -r requirements.txt 20 | mkdocs build -d build/docs 21 | 22 | .PHONY: deploy 23 | deploy: build 24 | which netlify || npm install -g netlify 25 | netlify deploy --site b7d97db0-1bc2-4e8c-903d-6ebf3da18358 --prod --dir build/docs 26 | 27 | 28 | .PHONY: watch 29 | watch: 30 | which mkdocs || pip3 install mkdocs 31 | pip3 install -r requirements.txt 32 | -kill $(cat .pid) 33 | (cd build/docs && python -m SimpleHTTPServer & echo "$$!" > .pid) 34 | -watchexec --ignore build/ -- mkdocs build -d build/docs 35 | -kill $(cat .pid) 36 | rm .pid 37 | -------------------------------------------------------------------------------- /docs/admin-guide/antrea.md: -------------------------------------------------------------------------------- 1 | `karina.yml` 2 | ```yaml 3 | calico: 4 | disabled: true 5 | antrea: 6 | version: v0.13.0 7 | ``` 8 | 9 | Deploy using: 10 | ```bash 11 | karina depoy antrea -c karina.yml 12 | ``` 13 | -------------------------------------------------------------------------------- /docs/admin-guide/authentication.md: -------------------------------------------------------------------------------- 1 | # Authentication 2 | 3 | ### Setting up SSO via LDAP 4 | 5 | ```yaml 6 | ldap: 7 | adminGroup: NA1 8 | username: uid=admin,ou=system 9 | password: secret 10 | port: 10636 11 | host: apacheds.ldap 12 | dn: ou=users,dc=example,dc=com 13 | ``` 14 | 15 | See [login](/user-guide/login) for how to configure your kubectl client to authenticate via Dex. 16 | 17 | 18 | https://oidcdebugger.com/ 19 | -------------------------------------------------------------------------------- /docs/admin-guide/backup.md: -------------------------------------------------------------------------------- 1 | `karina.yml` 2 | 3 | ```yaml 4 | s3: 5 | #optional endpoint for S3-compatible blob stores 6 | #endpoint: 7 | region: eu-east-1 8 | access_key: !!env AWS_ACCESS_KEY 9 | secret_key: !!env AWS_SECRET_KEY 10 | velero: 11 | version: v1.3.2 12 | bucket: backups 13 | ``` 14 | Deploy using: 15 | ```bash 16 | karina deploy velero -c karina.yaml 17 | ``` 18 | 19 | #### To run a backup of the cluster objects 20 | 21 | ```shell 22 | karina backup 23 | ``` 24 | 25 | -------------------------------------------------------------------------------- /docs/admin-guide/calico.md: -------------------------------------------------------------------------------- 1 | ```yaml 2 | calico: 3 | version: v3.8.2 4 | ``` 5 | 6 | -------------------------------------------------------------------------------- /docs/admin-guide/cluster-lifecycle.md: -------------------------------------------------------------------------------- 1 | 2 | ![](../../img/Cluster%20Lifecycle.png) 3 | 4 | ##### Control Plane Init 5 | 6 | The control plane is initialized by: 7 | 8 | - Generating all the certificates (to be used to generate access credentials or provision new control plane nodes) 9 | - Injecting the certificates and configs into a cloud-config file and a provisioning a VM, on boot `kubeadm init` is run to bootstrap the cluster 10 | 11 | ##### Adding Secondary Control Plane Nodes 12 | 13 | - The certificates are injected into cloud-init and multiple VM's are provisioned concurrently which run `kubeadm join --control-plane` on boot 14 | 15 | ##### Adding Workers 16 | 17 | - Workers have a bootstrap token injected into cloud-init and multiple VM's are provisioned concurrently which run `kubeadm --join` on boot 18 | -------------------------------------------------------------------------------- /docs/admin-guide/cni.md: -------------------------------------------------------------------------------- 1 | ## Choosing a CNI 2 | 3 | 4 | 5 | ### Calico 6 | 7 | ### Antrea 8 | 9 | ### NSX-T NCP -------------------------------------------------------------------------------- /docs/admin-guide/configuration.md: -------------------------------------------------------------------------------- 1 | ../configuration.md -------------------------------------------------------------------------------- /docs/admin-guide/consul.md: -------------------------------------------------------------------------------- 1 | Access harbor at: [:octicons-link-external-24: consul.%%{domain}%%](https://consul.%%{domain}%%) 2 | 3 | # Consul 4 | 5 | ### Backup 6 | 7 | This command will create a consul snapshot and upload it to the S3 bucket provided in config. 8 | 9 | ```bash 10 | # Run snapshot one time 11 | karina consul backup --name consul-server --namespace vault 12 | # Deploy a cron job to create a snapshot every day at 04:00 AM 13 | karina consul backup --name consul-server --namespace vault --schedule "0 4 * * *" 14 | ``` 15 | 16 | See [karina consul backup](../../../cli/karina_consul_backup/) documentation for all command line arguments. 17 | 18 | 19 | ### Restore 20 | 21 | This command will restore a consul cluster from a snapshot stored in S3. 22 | 23 | ```bash 24 | karina consul restore --name consul-server --namespace vault s3://consul-backups/consul/backups/vault/consul-server/2020-04-03_01:02:03.snapshot 25 | ``` 26 | 27 | See [karina consul restore](../../../cli/karina_consul_restore/) documentation for all command line arguments. 28 | 29 | -------------------------------------------------------------------------------- /docs/admin-guide/encryption.md: -------------------------------------------------------------------------------- 1 | ### Configure Kubernetes Encryption 2 | 3 | Karina supports configuring encryption providers for stored secrets. 4 | 5 | This is configured by supplying an encryption provider configuration file (look [here](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#encrypting-your-data) for an example). 6 | 7 | Update the `kubernetes.encryption` section with the config file: 8 | 9 | ```yaml 10 | kubernetes: 11 | encryption: 12 | encryptionProviderConfigFile: ./encryption-config.yaml 13 | ``` 14 | 15 | !!! warning 16 | Note that encryption options are only used on provisioning, to update or add auditing to an existing cluster the configuration needs to be updated and then all master nodes rolled. 17 | 18 | See the official Kubernetes documentation for the [configuration file](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#understanding-the-encryption-at-rest-configuration) and the [various providers](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers) that can be configured. -------------------------------------------------------------------------------- /docs/admin-guide/index.md: -------------------------------------------------------------------------------- 1 | 2 | # Install karina 3 | 4 | === "Linux" 5 | ```bash 6 | wget -nv -O karina \ 7 | https://github.com/flanksource/karina/releases/latest/download/karina_linux-amd64 && \ 8 | chmod +x karina && \ 9 | mv karina /usr/local/bin/karina 10 | ``` 11 | 12 | === "MacOSX" 13 | ```zsh 14 | wget -nv -O karina \ 15 | https://github.com/flanksource/karina/releases/latest/download/karina_darwin-amd64 && \ 16 | chmod +x karina && \ 17 | mv karina /usr/local/bin/karina 18 | ``` 19 | 20 | 21 | !!! note 22 | For production pipelines you should always pin the version of karina you are using 23 | -------------------------------------------------------------------------------- /docs/admin-guide/istio.md: -------------------------------------------------------------------------------- 1 | `karina.yml` 2 | 3 | ```yaml 4 | 5 | ``` 6 | 7 | Deploying using : 8 | 9 | ```bash 10 | karina deploy istio-operator -c karina.yml 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/admin-guide/local-path.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/admin-guide/local-path.md -------------------------------------------------------------------------------- /docs/admin-guide/minio.md: -------------------------------------------------------------------------------- 1 | 2 | `karina.yml` 3 | ```yaml 4 | minio: 5 | version: RELEASE.2020-09-02T18-19-50Z 6 | access_key: minio 7 | secret_key: minio123 8 | # 1 or non HA, otherwise must be in multiples of 4 9 | replicas: 1 10 | ``` 11 | 12 | :1: Deploy: 13 | 14 | ```bash 15 | karina deploy minio -c karina.yml 16 | ``` 17 | 18 | :2: Access the UI: [:octicons-link-external-24: https://minio.%%{domain}%%](https://minio.%%{domain}%%) 19 | 20 | !!! warning 21 | Minio has significant limitations around scaling - Once created the the number of nodes cannot be increased to scale capacity 22 | -------------------------------------------------------------------------------- /docs/admin-guide/multi-tenancy.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/admin-guide/multi-tenancy.md -------------------------------------------------------------------------------- /docs/admin-guide/persistent-volumes.md: -------------------------------------------------------------------------------- 1 | # Local Path 2 | # vSphere Volumes 3 | -------------------------------------------------------------------------------- /docs/admin-guide/provisioning/ca.md: -------------------------------------------------------------------------------- 1 | First generate a new CA using [karina ca generate](/cli/karina_ca_generate.md) 2 | 3 | ```bash 4 | karina ca generate --name cluster-ca \ 5 | --cert-path cluster-ca.crt \ 6 | --private-key-path cluster-ca.key \ 7 | --password $CA_KEK \ 8 | --expiry 10 9 | ``` 10 | 11 | Configure karina to use this CA when provisioning: 12 | 13 | `karina.yml` 14 | ```yaml 15 | ca: 16 | cert: cluster-ca.crt 17 | privateKey: cluster-ca.key 18 | password: !!env CA_KEK 19 | ``` 20 | 21 | Run `karina provision` to provision a cluster and the shared CA will be injected into new instances allowing PKI based auth. 22 | 23 | 24 | !!! warning 25 | The CA will only be injected into a new master node, you will need to re-provision all existing masters for changes to take effect. 26 | 27 | To generate a new kubeconfig file to access a cluster using a CA run: 28 | 29 | ```bash 30 | karina kubeconfig admin --expiry 1680h --name $USER -c karina.yml 31 | ``` 32 | 33 | 34 | 35 | See [karina kubeconfig admin](/cli/karina_kubeconfig_admin.md) 36 | -------------------------------------------------------------------------------- /docs/admin-guide/provisioning/dns.md: -------------------------------------------------------------------------------- 1 | ### Dynamic DNS 2 | ```yaml 3 | dns: 4 | nameserver: NAMESERVER:53 5 | algorithm: hmac-md5 6 | key: !!env DNS_KEY 7 | keyName: k8s. 8 | zone: k8s 9 | ``` 10 | 11 | 12 | 13 | ### Route 53 14 | 15 | -------------------------------------------------------------------------------- /docs/admin-guide/provisioning/master-discovery.md: -------------------------------------------------------------------------------- 1 | Karina requires a service discovery mechanism to facilitate the initial connection to the kubernetes hosts. A containerised consul service discovery can be enabled on a host in the vsphere cluster using the konfigadm tool: 2 | 3 | 4 | ## Load Balancer 5 | 6 | ## DNS 7 | 8 | ## Consul 9 | 10 | ### Create consul.yml 11 | `consul.yml` 12 | ```yaml 13 | commands: 14 | - mkdir -p /opt/consul 15 | - chown -R 100:1000 /opt/consul 16 | - iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-ports 8500 17 | container_runtime: 18 | type: docker 19 | containers: 20 | - image: docker.io/consul:1.9.1 21 | docker_opts: --net=host 22 | args: agent -server -ui -data-dir /opt/consul -datacenter lab -bootstrap 23 | volumes: 24 | - /opt/consul:/opt/consul 25 | env: 26 | CONSUL_BIND_INTERFACE: ens160 27 | CONSUL_CLIENT_INTERFACE: ens160 28 | ``` 29 | 30 | ### Deploy consul 31 | ```bash 32 | karina provision vm -c karina.yml -k consul.yaml` 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /docs/admin-guide/provisioning/vcenter.md: -------------------------------------------------------------------------------- 1 | Configure your environment with `GOVC_*` variables and then map them into the configuration file using the `!!env` YAML tag: 2 | 3 | 4 | ## Install govc 5 | === "Linux" 6 | ```bash 7 | wget -nv -nc https://github.com/vmware/govc/releases/latest/download/govc_linux_amd64.gz && \ 8 | gzip -d govc_linux_amd64.gz && \ 9 | chmod +x govc_linux_amd64 && \ 10 | mv govc_linux_amd64 /usr/local/bin/govc 11 | ``` 12 | 13 | === "MacOSX" 14 | ```zsh 15 | wget -nv -nc https://github.com/vmware/govmomi/releases/latest/download/govc_darwin_amd64.gz && \ 16 | gzip -d govc_darwin_amd64.gz && \ 17 | chmod +x govc_darwin_amd64 && \ 18 | mv govc_darwin_amd64 /usr/local/bin/govc 19 | ``` 20 | 21 | 22 | ## Configure govc 23 | 24 | ```bash 25 | export GOVC_USER= 26 | export GOVC_DATACENTER= 27 | export GOVC_CLUSTER= 28 | export GOVC_FOLDER= 29 | export GOVC_DATASTORE= 30 | # can be found on the Datastore summary page 31 | export GOVC_DATASTORE_URL= 32 | export GOVC_PASS= 33 | export GOVC_FQDN= 34 | ``` 35 | 36 | ## Test Connection 37 | 38 | ```bash 39 | export GOVC_URL="$GOVC_USER:$GOVC_PASS@$GOVC_FQDN" 40 | govc about 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/admin-guide/rbac.md: -------------------------------------------------------------------------------- 1 | ### Setup RBAC permissions for users 2 | 3 | ```yaml 4 | kind: ClusterRole 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | metadata: 7 | name: test-rbac-ldap 8 | rules: 9 | - apiGroups: ["*"] 10 | resources: ["pods", "nodes"] 11 | verbs: ["list"] 12 | --- 13 | kind: ClusterRoleBinding 14 | apiVersion: rbac.authorization.k8s.io/v1 15 | metadata: 16 | name: test-rbac-role 17 | subjects: 18 | - apiGroup: "" 19 | kind: User 20 | name: test@example.com 21 | roleRef: 22 | apiGroup: "" 23 | kind: ClusterRole 24 | name: test-rbac-ldap 25 | ``` -------------------------------------------------------------------------------- /docs/admin-guide/sealed-secrets.md: -------------------------------------------------------------------------------- 1 | # Sealed Secrets 2 | 3 | `karina.yml` 4 | 5 | ```yaml 6 | sealedSecrets: 7 | version: "v0.10.0" 8 | certificate: 9 | cert: .certs/sealed-secrets.crt 10 | privateKey: .certs/sealed-secrets.key 11 | password: foobar 12 | ``` 13 | 14 | Deploy using: 15 | 16 | ```bash 17 | karina deploy sealed-secrets -c karina.yml 18 | ``` 19 | 20 | ### Certificate generation 21 | 22 | If certificate is not provided, sealed secrets controller will automatically generate one and will store it in a secret named `sealed-secret-keys` in the `sealed-secrets` namespace. 23 | 24 | You can override this settings and provide your own certificate for encrypting secrets. 25 | 26 | ```bash 27 | karina ca generate --name sealed-secrets \ 28 | --cert-path .certs/sealed-secrets.crt \ 29 | --private-key-path .certs/sealed-secrets-key.key \ 30 | --password foobar \ 31 | --expiry 1 32 | ``` 33 | 34 | -------------------------------------------------------------------------------- /docs/admin-guide/security.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/admin-guide/security.md -------------------------------------------------------------------------------- /docs/admin-guide/sso.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/admin-guide/sso.md -------------------------------------------------------------------------------- /docs/admin-guide/vsphere.md: -------------------------------------------------------------------------------- 1 | ### Setting vSphere CSI/CPI -------------------------------------------------------------------------------- /docs/cli/.gitignore: -------------------------------------------------------------------------------- 1 | *.md 2 | -------------------------------------------------------------------------------- /docs/crds.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/master/pkg/apis/monitoring/v1/types.go 2 | https://github.com/vmware-tanzu/velero/tree/main/pkg/apis/velero/v1 3 | -------------------------------------------------------------------------------- /docs/developer-guide/make-targets.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Make targets 4 | 5 | * `help` - Lists all valid targets 6 | * `build`(default) - Build binaries 7 | * `install` - Installs binary locally (needs admin priviliges) 8 | * `linux` - Build for Linux 9 | * `darwin` - Build for Darwin 10 | * `docker` - Build docker image 11 | * `compress` - Uses UPX to compress the executable 12 | * `serve-docs` - Serves the MkDocs docs locally 13 | * `build-api-docs` - Build golang docs 14 | * `build-docs` - Build MkDocs docs 15 | * `deploy-docs` - Deploy MkDocs to Netlify 16 | 17 | Normal first time use: 18 | ```shell 19 | make # do a local build 20 | make compress # compress the built executable 21 | sudo make install # install the executable to /usr/local/bin/ 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /docs/developer-guide/testing.md: -------------------------------------------------------------------------------- 1 | # Running Tests 2 | 3 | ```shell 4 | ./test/test.sh 5 | ``` 6 | -------------------------------------------------------------------------------- /docs/img/Cluster Lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/img/Cluster Lifecycle.png -------------------------------------------------------------------------------- /docs/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/img/favicon.png -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/img/logo.png -------------------------------------------------------------------------------- /docs/img/monitoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/img/monitoring.png -------------------------------------------------------------------------------- /docs/operators/consul.md: -------------------------------------------------------------------------------- 1 | ### Backup 2 | 3 | This command will create a consul snapshot and upload it to the S3 bucket provided in config. 4 | 5 | ```bash 6 | # Run snapshot one time 7 | karina consul backup --name consul-server --namespace vault 8 | # Deploy a cron job to create a snapshot every day at 04:00 AM 9 | karina consul backup --name consul-server --namespace vault --schedule "0 4 * * *" 10 | ``` 11 | 12 | See [karina consul backup](../../../cli/karina_consul_backup/) documentation for all command line arguments. 13 | 14 | 15 | ### Restore 16 | 17 | This command will restore a consul cluster from a snapshot stored in S3. 18 | 19 | ```bash 20 | karina consul restore --name consul-server --namespace vault s3://consul-backups/consul/backups/vault/consul-server/2020-04-03_01:02:03.snapshot 21 | ``` 22 | 23 | See [karina consul restore](../../../cli/karina_consul_restore/) documentation for all command line arguments. 24 | 25 | -------------------------------------------------------------------------------- /docs/operators/git.md: -------------------------------------------------------------------------------- 1 | `karina.yml` 2 | 3 | ```yaml 4 | gitOperator: 5 | version: 1.0.0 6 | ``` 7 | 8 | `karina deploy git-operator -c karina.yml` 9 | -------------------------------------------------------------------------------- /docs/operators/platform.md: -------------------------------------------------------------------------------- 1 | `karina.yml` 2 | 3 | ```yaml 4 | platformOperator: 5 | version: v0.1.9 6 | ``` 7 | 8 | `karina deploy platform-operator -c karina.yml` 9 | -------------------------------------------------------------------------------- /docs/operators/prometheus.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/operators/prometheus.md -------------------------------------------------------------------------------- /docs/operators/rabbitmq.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/operators/rabbitmq.md -------------------------------------------------------------------------------- /docs/operators/redis.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/operators/redis.md -------------------------------------------------------------------------------- /docs/overrides/content.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | {% if page.meta.source %} 5 | 10 | {% endif %} 11 | 12 | {{ page.content }} 13 | 14 | {% if page.meta.git_revision_date_localized %} 15 | Last update: {{ page.meta.git_revision_date_localized }} 16 | {% endif %} 17 | -------------------------------------------------------------------------------- /docs/overrides/icons/1.svg: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /docs/overrides/icons/2.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/overrides/icons/3.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/overrides/icons/4.svg: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /docs/overrides/icons/5.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/overrides/icons/6.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/overrides/icons/7.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /docs/overrides/icons/8.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/overrides/icons/9.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/overrides/icons/action.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/overrides/icons/alarm.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/alert.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/asterix.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/bash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/bomb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/overrides/icons/book.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/overrides/icons/dex.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/exclamation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/explode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/fire.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/hash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/kibaba.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/kibana.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | kibana-logo-color-64px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/overrides/icons/logstash.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logstash-logo-color-64px 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/overrides/icons/ok.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/opa.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/operator.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/question.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/rabbitmq.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/s3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/shell.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/silence.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/overrides/icons/silence2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/overrides/icons/snowflake.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/overrides/icons/speak.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /docs/overrides/icons/star.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/tag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/talk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/overrides/icons/terraform-enterprise.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/thanos.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/trafficlight.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/overrides/icons/vault.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/overrides/icons/warn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/overrides/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --md-admonition-icon--asterix: url('data:image/svg+xml;charset=utf-8, * ') 3 | } 4 | .md-typeset .admonition.asterix, 5 | .md-typeset details.asterix { 6 | border-color: #448aff; 7 | } 8 | .md-typeset .asterix > .admonition-title, 9 | .md-typeset .asterix > summary { 10 | background-color: rgba(68,138,255, 0.1); 11 | } 12 | .md-typeset .asterix > .admonition-title::before, 13 | .md-typeset .asterix > summary::before { 14 | background-color: #448aff; 15 | -webkit-mask-image: var(--md-admonition-icon--asterix); 16 | mask-image: var(--md-admonition-icon--asterix); 17 | } 18 | -------------------------------------------------------------------------------- /docs/reference/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/reference/.keep -------------------------------------------------------------------------------- /docs/reference/config.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/reference/config.md -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs-snippet-plugin 2 | mkdocs-same-dir 3 | mkdocs-autolinks-plugin 4 | mkdocs-material-extensions 5 | mkdocs-git-revision-date-plugin 6 | mkdocs-macros-plugin 7 | mkdocs-markdownextradata-plugin 8 | -------------------------------------------------------------------------------- /docs/user-guide/configuration.md: -------------------------------------------------------------------------------- 1 | ../configuration.md -------------------------------------------------------------------------------- /docs/user-guide/index.md: -------------------------------------------------------------------------------- 1 | [[% include './user-guide/install.md' %]] 2 | -------------------------------------------------------------------------------- /docs/user-guide/install.md: -------------------------------------------------------------------------------- 1 | ## kubectl 2 | 3 | === "Linux" 4 | ```bash 5 | wget -nv -nc https://dl.k8s.io/release/%%{ kubernetes.version }%%/bin/linx/amd64/kubectl && \ 6 | chmod +x kubectl && \ 7 | mv kubectl /usr/local/bin 8 | ``` 9 | 10 | === "MacOSX" 11 | ```bash 12 | brew install kubectl 13 | ``` 14 | 15 | === "Windows" 16 | ```bash 17 | wget -nv -nc -O https://dl.k8s.io/release/%%{ kubernetes.version }%%/bin/windows/amd64/kubectl 18 | ``` 19 | 20 | 21 | ## stern 22 | 23 | [stern](/user-guide/logging/#realtime-tailing) is a real-time log tailing tool for kubernetes 24 | 25 | === "Linux" 26 | ```bash 27 | wget -nv -nc -o stern https://github.com/wercker/stern/releases/latest/download/stern_linux_amd64 && \ 28 | chmod +x stern && \ 29 | mv stern /usr/local/bin/ 30 | ``` 31 | 32 | === "MacOSX" 33 | ```zsh 34 | brew install stern 35 | ``` 36 | 37 | === "Windows" 38 | ```zsh 39 | wget -nv -nc -o stern.exe https://github.com/wercker/stern/releases/latest/download/stern_windows_amd64.exe 40 | ``` 41 | 42 | 43 | Follow the frontend pods in canary release: 44 | 45 | ```shell 46 | stern frontend --selector release=canary 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/user-guide/opa.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/user-guide/opa.md -------------------------------------------------------------------------------- /docs/user-guide/secrets.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/docs/user-guide/secrets.md -------------------------------------------------------------------------------- /docs/user-guide/templating.md: -------------------------------------------------------------------------------- 1 | Karina supports deploying the same workload on multiple clusters, in order to facilitate this dynamic ingress names are supported. 2 | 3 | Create the ingress as usual and use `{{.Domain}}` where you would normally use the cluster wildcard DNS entry, The template will be replaced at runtime by Quack 4 | 5 | 6 | ```yaml 7 | apiVersion: networking.k8s.io/v1 8 | kind: Ingress 9 | metadata: 10 | name: kibana-ing 11 | namespace: eck 12 | annotations: 13 | nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 14 | spec: 15 | tls: 16 | - hosts: 17 | - kibana.{{.Domain}} 18 | rules: 19 | - host: kibana.{{.Domain}} 20 | http: 21 | paths: 22 | - backend: 23 | service: 24 | name: logs-kb-http 25 | port: 26 | number: 5601 27 | ``` 28 | 29 | 30 | 31 | ### Variables available for templating 32 | 33 | | Variable | Description | 34 | | -------- | ------------------------------------------------------------ | 35 | | Domain | Wildcard domain specified at cluster provisioning and at which DNS points to the ingress layer | 36 | | Name | Unique name of the cluster | 37 | 38 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Flanksource. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ -------------------------------------------------------------------------------- /manifests/cert-manager-clusterissuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: default-issuer 5 | spec: 6 | ca: 7 | secretName: default-issuer-ca 8 | -------------------------------------------------------------------------------- /manifests/crd/sealed-secrets.yaml: -------------------------------------------------------------------------------- 1 | # This file was generated by running 'make crd/sealed-secrets.yaml' in manifests directory 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: sealedsecrets.bitnami.com 6 | spec: 7 | group: bitnami.com 8 | names: 9 | kind: SealedSecret 10 | listKind: SealedSecretList 11 | plural: sealedsecrets 12 | singular: sealedsecret 13 | scope: Namespaced 14 | versions: 15 | - name: v1alpha1 16 | schema: 17 | openAPIV3Schema: 18 | properties: 19 | spec: 20 | type: object 21 | x-kubernetes-preserve-unknown-fields: true 22 | status: 23 | x-kubernetes-preserve-unknown-fields: true 24 | type: object 25 | served: true 26 | storage: true 27 | subresources: 28 | status: {} -------------------------------------------------------------------------------- /manifests/gatekeeper/block-nodeports.yaml: -------------------------------------------------------------------------------- 1 | #https://github.com/open-policy-agent/gatekeeper-library/blob/master/library/general/block-nodeport-services/template.yaml 2 | apiVersion: templates.gatekeeper.sh/v1beta1 3 | kind: ConstraintTemplate 4 | metadata: 5 | name: k8sblocknodeport 6 | annotations: 7 | description: Disallows all Services with type NodePort. 8 | spec: 9 | crd: 10 | spec: 11 | names: 12 | kind: K8sBlockNodePort 13 | targets: 14 | - target: admission.k8s.gatekeeper.sh 15 | rego: | 16 | package k8sblocknodeport 17 | violation[{"msg": msg}] { 18 | input.review.kind.kind == "Service" 19 | input.review.object.spec.type == "NodePort" 20 | msg := "User is not allowed to create service of type NodePort" 21 | } 22 | -------------------------------------------------------------------------------- /manifests/gatekeeper/deny-all.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: templates.gatekeeper.sh/v1beta1 2 | kind: ConstraintTemplate 3 | metadata: 4 | name: k8sdenyall 5 | spec: 6 | crd: 7 | spec: 8 | names: 9 | kind: K8sDenyAll 10 | targets: 11 | - target: admission.k8s.gatekeeper.sh 12 | rego: | 13 | package k8sdenyall 14 | 15 | violation[{"msg": msg}] { 16 | msg := sprintf("REVIEW OBJECT: %v", [input.review]) 17 | } 18 | -------------------------------------------------------------------------------- /manifests/images.yaml: -------------------------------------------------------------------------------- 1 | # prometheus operator doesn't explicitly specify the version, so we do it here so that it can be listed and synced 2 | # image: quay.io/prometheus/prometheus:v2.10.0 3 | -------------------------------------------------------------------------------- /manifests/karina-operator.yaml: -------------------------------------------------------------------------------- 1 | # This file was generated by running 'make karina-operator.yaml' in manifests directory 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | control-plane: karina-operator 7 | name: karina 8 | namespace: platform-system 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | control-plane: karina-operator 14 | template: 15 | metadata: 16 | labels: 17 | control-plane: karina-operator 18 | spec: 19 | containers: 20 | - args: 21 | - operator 22 | - --enable-leader-election 23 | - --log-level=debug 24 | command: 25 | - /bin/karina 26 | image: docker.io/flanksource/karina:{{.karinaOperator.version}} 27 | imagePullPolicy: IfNotPresent 28 | name: karina-operator 29 | resources: 30 | limits: 31 | cpu: 500m 32 | memory: 256Mi 33 | requests: 34 | cpu: 100m 35 | memory: 128Mi 36 | serviceAccountName: karina -------------------------------------------------------------------------------- /manifests/modsecurity-filebeat.yaml: -------------------------------------------------------------------------------- 1 | filebeat: 2 | inputs: 3 | - type: log 4 | paths: 5 | - /var/log/modsecurity/modsec_audit.log 6 | json.keys_under_root: true 7 | config: 8 | modules: 9 | path: /usr/share/filebeat/modules.d/*.yml 10 | reload: 11 | enabled: true 12 | 13 | output.elasticsearch: 14 | hosts: ['${ELASTIC_URL}'] 15 | username: '${ELASTIC_USERNAME}' 16 | password: '${ELASTIC_PASSWORD}' 17 | ssl: 18 | supported_protocols: ['TLSv1.2', 'TLSv1.3'] 19 | verification_mode: '$sslMode$' 20 | {{- if ne .nginx.modsecurity.index "" }} 21 | index: '{{.nginx.modsecurity.index }}-%{[agent.version]}-%{+yyyy.MM.dd}' 22 | setup: 23 | template: 24 | name: '{{.nginx.modsecurity.index }}' 25 | pattern: '{{.nginx.modsecurity.index }}-*' 26 | enabled: false 27 | ilm: 28 | rollover_alias: '{{.nginx.modsecurity.index }}-%{[agent.version]}' 29 | {{ end }} 30 | -------------------------------------------------------------------------------- /manifests/monitoring/kubernetes-rules.yaml.raw: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | labels: 5 | prometheus: k8s 6 | role: alert-rules 7 | name: kubernetes-rules 8 | namespace: monitoring 9 | spec: 10 | groups: 11 | - name: kubernetes-recording-rules 12 | rules: 13 | - expr: | 14 | sum(rate(apiserver_admission_webhook_admission_duration_seconds_sum[5m])) by (name) / 15 | sum(rate(apiserver_admission_webhook_admission_duration_seconds_count[5m])) by (name) 16 | record: kubernetes:PodAdmissionLatency:5m 17 | - name: kubernetes-alerts 18 | rules: 19 | - alert: PodAdmissionLatency 20 | annotations: 21 | message: pod admission latency for webhook {{ $labels.name }} is above 2 seconds for 5 minutes 22 | expr: kubernetes:PodAdmissionLatency:5m > 2 23 | for: "5m" 24 | labels: 25 | severity: warning 26 | -------------------------------------------------------------------------------- /manifests/monitoring/nginx-alerts.yaml.raw: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PrometheusRule 3 | metadata: 4 | labels: 5 | prometheus: k8s 6 | role: alert-rules 7 | name: prometheus-nginx-rules 8 | namespace: monitoring 9 | spec: 10 | groups: 11 | - name: nginx-alert.rules 12 | rules: 13 | - alert: NginxIngressConfigError 14 | annotations: 15 | message: Nginx Ingress controller has encountered errors parsing config 16 | expr: | 17 | sum(rate(nginx_ingress_controller_errors[1m])) > 0 18 | for: 1m 19 | labels: 20 | severity: critical -------------------------------------------------------------------------------- /manifests/monitoring/thanos/base.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: thanos-objstore-config 5 | namespace: monitoring 6 | type: Opaque 7 | stringData: 8 | thanos.yaml: |- 9 | type: S3 10 | config: 11 | bucket: {{.thanos.bucket}} 12 | endpoint: {{.s3.endpoint | strings.TrimPrefix "http://" | strings.TrimPrefix "https://" }} 13 | {{- if .s3.endpoint | strings.HasPrefix "http://" }} 14 | insecure: true 15 | http_config: 16 | insecure_skip_verify: true 17 | {{- end}} 18 | {{- if .s3.region }} 19 | region: {{.s3.region}} 20 | {{- end }} 21 | {{- if .s3.access_key }} 22 | access_key: {{.s3.access_key}} 23 | secret_key: {{.s3.secret_key}} 24 | {{- end}} 25 | -------------------------------------------------------------------------------- /manifests/static.go: -------------------------------------------------------------------------------- 1 | package manifests 2 | 3 | import "embed" 4 | 5 | //nolint 6 | //go:embed * 7 | var EmbeddedContent embed.FS 8 | -------------------------------------------------------------------------------- /manifests/test/argo-rollouts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Rollout 3 | metadata: 4 | name: rollouts-demo 5 | spec: 6 | replicas: 5 7 | strategy: 8 | canary: 9 | steps: 10 | - setWeight: 20 11 | - pause: {duration: 10} 12 | - setWeight: 40 13 | - pause: {duration: 10} 14 | - setWeight: 60 15 | - pause: {duration: 10} 16 | - setWeight: 80 17 | - pause: {duration: 10} 18 | revisionHistoryLimit: 2 19 | selector: 20 | matchLabels: 21 | app: rollouts-demo 22 | template: 23 | metadata: 24 | labels: 25 | app: rollouts-demo 26 | spec: 27 | containers: 28 | - name: rollouts-demo 29 | image: argoproj/rollouts-demo:blue 30 | ports: 31 | - name: http 32 | containerPort: 8080 33 | protocol: TCP 34 | resources: 35 | requests: 36 | memory: 32Mi 37 | cpu: 5m 38 | -------------------------------------------------------------------------------- /manifests/test/percona-server-mongodb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: psmdb.percona.com/v1-6-0 2 | kind: PerconaServerMongoDB 3 | metadata: 4 | name: my-cluster-name 5 | namespace: test-mongodb-operator 6 | spec: 7 | crVersion: 1.6.0 8 | image: percona/percona-server-mongodb:4.4.2-4 9 | imagePullPolicy: Always 10 | allowUnsafeConfigurations: false 11 | updateStrategy: SmartUpdate 12 | upgradeOptions: 13 | versionServiceEndpoint: https://check.percona.com 14 | apply: recommended 15 | schedule: "0 2 * * *" 16 | secrets: 17 | users: my-cluster-name-secrets 18 | replsets: 19 | - name: rs0 20 | size: 3 21 | affinity: 22 | antiAffinityTopologyKey: "none" # Set to none so it can work on single node Kubernetes cluster 23 | volumeSpec: 24 | persistentVolumeClaim: 25 | resources: 26 | requests: 27 | storage: 3Gi -------------------------------------------------------------------------------- /manifests/upstream/.gitignore: -------------------------------------------------------------------------------- 1 | */helm/generated_templates -------------------------------------------------------------------------------- /manifests/upstream/argo-rollouts/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: platform-system 2 | bases: 3 | - github.com/argoproj/argo-rollouts/manifests/base?ref=v1.1.1 4 | - github.com/argoproj/argo-rollouts/manifests/role?ref=v1.1.1 5 | resources: 6 | - https://raw.githubusercontent.com/argoproj/argo-rollouts/v1.1.1/manifests/cluster-install/argo-rollouts-clusterrolebinding.yaml 7 | images: 8 | - name: quay.io/argoproj/argo-rollouts 9 | newName: quay.io/argoproj/argo-rollouts 10 | newTag: "{{.argoRollouts.version}}" 11 | patchesStrategicMerge: 12 | - |- 13 | apiVersion: rbac.authorization.k8s.io/v1 14 | kind: ClusterRoleBinding 15 | metadata: 16 | name: argo-rollouts 17 | subjects: 18 | - kind: ServiceAccount 19 | name: argo-rollouts 20 | namespace: platform-system 21 | -------------------------------------------------------------------------------- /manifests/upstream/argo-rollouts/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | bases: 2 | - github.com/argoproj/argo-rollouts/manifests/crds?ref=v1.1.1 -------------------------------------------------------------------------------- /manifests/upstream/argocd-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | bases: 2 | - github.com/argoproj-labs/argocd-operator/config/crd?ref=v0.1.0 -------------------------------------------------------------------------------- /manifests/upstream/canary-checker/base/servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: canary-checker-monitor 5 | spec: 6 | jobLabel: canary-checker 7 | endpoints: 8 | - targetPort: 8080 9 | interval: 30s 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: canary-checker 13 | control-plane: canary-checker 14 | 15 | -------------------------------------------------------------------------------- /manifests/upstream/canary-checker/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ../helm/generated_templates/canary-checker/crds/crd.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/canary-checker/helm/chart.yaml: -------------------------------------------------------------------------------- 1 | repo: https://flanksource.github.io/charts 2 | chart_name: canary-checker 3 | version: 0.38.250 4 | namespace: platform-system 5 | -------------------------------------------------------------------------------- /manifests/upstream/canary-checker/helm/values.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | tag: 'latest' 3 | fullnameOverride: 'canary-checker' 4 | containerdSocket: true 5 | db: 6 | embedded: 7 | storage: 1Gi 8 | storageClass: local-path 9 | flanksource-ui: 10 | enabled: true 11 | backendURL: 'http://canary-checker.platform-system.svc.cluster.local:8080/' 12 | ingress: 13 | enabled: true 14 | host: canaries.{{.domain}} 15 | annotations: 16 | kubernetes.io/tls-acme: "true" 17 | tls: 18 | - hosts: 19 | - canaries.{{.domain}} 20 | secretName: canary-tls 21 | ingress: 22 | enabled: false 23 | -------------------------------------------------------------------------------- /manifests/upstream/cert-manager/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://github.com/jetstack/cert-manager/releases/download/v1.11.0/cert-manager.crds.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/eck/base/certificate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | annotations: 5 | cert-manager.io/allow-direct-injection: "true" 6 | name: elastic-webhook-server 7 | namespace: elastic-system 8 | spec: 9 | dnsNames: 10 | - elastic-webhook-server 11 | - elastic-webhook-server.elastic-system.svc 12 | - elastic-webhook-server.elastic-system.svc.cluster.local 13 | issuerRef: 14 | kind: ClusterIssuer 15 | name: default-issuer 16 | privateKey: 17 | algorithm: RSA 18 | size: 2048 19 | secretName: elastic-webhook-server-cert 20 | -------------------------------------------------------------------------------- /manifests/upstream/eck/base/delete-secret.yaml: -------------------------------------------------------------------------------- 1 | $patch: delete 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: elastic-webhook-server-cert 6 | namespace: elastic-system -------------------------------------------------------------------------------- /manifests/upstream/eck/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: elastic-system 2 | resources: 3 | - https://download.elastic.co/downloads/eck/2.1.0/operator.yaml 4 | - certificate.yaml 5 | images: 6 | - name: docker.elastic.co/eck/eck-operator 7 | newTag: "{{.eck.version}}" 8 | patches: 9 | - path: delete-secret.yaml 10 | - patch: |- 11 | $patch: delete 12 | apiVersion: v1 13 | kind: Namespace 14 | metadata: 15 | name: elastic-system 16 | -------------------------------------------------------------------------------- /manifests/upstream/eck/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/elastic/cloud-on-k8s/2.1.0/config/crds/v1/all-crds.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/external-dns/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: platform-system 2 | bases: 3 | - github.com/kubernetes-sigs/external-dns/kustomize?ref=v0.10.1 4 | images: 5 | - name: k8s.gcr.io/external-dns/external-dns 6 | newTag: '{{.externalDns.version | default "na" }}' 7 | patchesStrategicMerge: 8 | - |- 9 | apiVersion: apps/v1 10 | kind: Deployment 11 | metadata: 12 | name: external-dns 13 | spec: 14 | template: 15 | spec: 16 | containers: 17 | - name: external-dns 18 | args: 19 | - TEMPLATE_MARK 20 | -------------------------------------------------------------------------------- /manifests/upstream/flux/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://github.com/fluxcd/flux2/releases/download/v0.36.0/install.yaml 3 | commonAnnotations: 4 | cluster-autoscaler.kubernetes.io/safe-to-evict: "true" 5 | images: 6 | - name: ghcr.io/fluxcd/helm-controller 7 | newTag: '{{.flux.helmControllerVersion | default "v0.26.0" }}' 8 | - name: ghcr.io/fluxcd/image-automation-controller 9 | newTag: '{{.flux.imageAutomationControllerVersion | default "v0.26.1" }}' 10 | - name: ghcr.io/fluxcd/image-reflector-controller 11 | newTag: '{{.flux.imageReflectorControllerVersion | default "v0.22.1" }}' 12 | - name: ghcr.io/fluxcd/kustomize-controller 13 | newTag: '{{.flux.kustomizeControllerVersion | default "v0.30.0" }}' 14 | - name: fluxcd/notification-controller 15 | newTag: '{{.flux.notificationControllerVersion | default "v0.28.0" }}' 16 | newName: ghcr.io/fluxcd/notification-controller 17 | - name: ghcr.io/fluxcd/source-controller 18 | newTag: '{{.flux.sourceControllerVersion | default "v0.31.0" }}' 19 | -------------------------------------------------------------------------------- /manifests/upstream/flux/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - https://github.com/fluxcd/source-controller/releases/download/v0.31.0/source-controller.crds.yaml 5 | - https://github.com/fluxcd/kustomize-controller/releases/download/v0.30.0/kustomize-controller.crds.yaml 6 | - https://github.com/fluxcd/helm-controller/releases/download/v0.26.0/helm-controller.crds.yaml 7 | - https://github.com/fluxcd/notification-controller/releases/download/v0.28.0/notification-controller.crds.yaml 8 | - https://github.com/fluxcd/image-reflector-controller/releases/download/v0.22.1/image-reflector-controller.crds.yaml 9 | - https://github.com/fluxcd/image-automation-controller/releases/download/v0.26.1/image-automation-controller.crds.yaml 10 | -------------------------------------------------------------------------------- /manifests/upstream/gatekeeper/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | bases: 2 | - github.com/open-policy-agent/gatekeeper/config/crd?ref=v3.7.0&timeout=180 -------------------------------------------------------------------------------- /manifests/upstream/git-operator/base/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | namespace: platform-system 5 | labels: 6 | control-plane: git-operator 7 | name: git-operator 8 | spec: 9 | selector: 10 | control-plane: git-operator 11 | ports: 12 | - port: 8888 13 | targetPort: 8888 14 | --- 15 | apiVersion: networking.k8s.io/v1 16 | kind: Ingress 17 | metadata: 18 | name: git-operator-ing 19 | namespace: platform-system 20 | annotations: 21 | kubernetes.io/tls-acme: "true" 22 | spec: 23 | tls: 24 | - secretName: git-operator-tls 25 | hosts: 26 | - git-operator.{{.domain}} 27 | rules: 28 | - host: git-operator.{{.domain}} 29 | http: 30 | paths: 31 | - backend: 32 | service: 33 | name: git-operator 34 | port: 35 | number: 8888 36 | pathType: ImplementationSpecific -------------------------------------------------------------------------------- /manifests/upstream/git-operator/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/git-operator/v0.2.0/config/deploy/base.yml 3 | - ingress.yaml 4 | images: 5 | - name: flanksource/git-operator 6 | newName: docker.io/flanksource/git-operator 7 | newTag: '{{ .gitOperator.version | default "na" }}' 8 | patchesStrategicMerge: 9 | - |- 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | metadata: 13 | name: git-operator 14 | namespace: platform-system 15 | spec: 16 | template: 17 | spec: 18 | containers: 19 | - name: git-operator 20 | ports: 21 | - containerPort: 8888 -------------------------------------------------------------------------------- /manifests/upstream/git-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/git-operator/v0.1.0/config/deploy/crd.yml 3 | -------------------------------------------------------------------------------- /manifests/upstream/grafana-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/grafana-operator/grafana-operator/master/deploy/manifests/v4.4.1/crds.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/istio/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/istio/istio/1.12.1/manifests/charts/base/crds/crd-operator.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/karina-operator/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | bases: 2 | - github.com/flanksource/karina/config/operator/manager 3 | images: 4 | - name: docker.io/flanksource/karina 5 | newTag: "{{.karinaOperator.version}}" 6 | -------------------------------------------------------------------------------- /manifests/upstream/karina-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | bases: 2 | - github.com/flanksource/karina/config/crd 3 | -------------------------------------------------------------------------------- /manifests/upstream/logs-exporter/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/logs-exporter/v0.1.3/config/deploy/base.yml 3 | images: 4 | - name: flanksource/logs-exporter 5 | newName: docker.io/flanksource/logs-exporter 6 | newTag: "{{.logsExporter.version | default "v0.1.3"}}" 7 | patchesStrategicMerge: 8 | - |- 9 | apiVersion: apps/v1 10 | kind: Deployment 11 | metadata: 12 | name: logs-exporter-controller-manager 13 | namespace: platform-system 14 | spec: 15 | template: 16 | spec: 17 | containers: 18 | - name: manager 19 | args: 20 | - --metrics-addr=0.0.0.0:8080 21 | - "--sync-period={{ .templateOperator.syncPeriod | default \"5m\" }}" 22 | resources: 23 | limits: 24 | cpu: 150m 25 | memory: 200Mi 26 | requests: 27 | cpu: 100m 28 | memory: 150Mi -------------------------------------------------------------------------------- /manifests/upstream/logs-exporter/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/logs-exporter/v0.1.3/config/deploy/crd.yml -------------------------------------------------------------------------------- /manifests/upstream/mongo-db/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator-library/v0.1.6/config/crd/db/db.flanksource.com_mongodbs.yaml -------------------------------------------------------------------------------- /manifests/upstream/mongo-db/template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator-library/v0.1.6/config/templates/mongo-db.yaml -------------------------------------------------------------------------------- /manifests/upstream/mongodb-operator/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: "platform-system" 2 | 3 | resources: 4 | - https://raw.githubusercontent.com/percona/percona-server-mongodb-operator/v1.11.0/deploy/operator.yaml 5 | - rbac.yaml 6 | 7 | patchesStrategicMerge: 8 | - operator-patch.yaml 9 | 10 | images: 11 | - name: percona/percona-server-mongodb-operator 12 | newName: docker.io/percona/percona-server-mongodb-operator 13 | newTag: "{{.mongodbOperator.version}}" -------------------------------------------------------------------------------- /manifests/upstream/mongodb-operator/base/operator-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: percona-server-mongodb-operator 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: percona-server-mongodb-operator 10 | env: 11 | - name: WATCH_NAMESPACE 12 | value: "" 13 | valueFrom: null -------------------------------------------------------------------------------- /manifests/upstream/mongodb-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/percona/percona-server-mongodb-operator/v1.11.0/deploy/crd.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/monitoring/prometheus-operator-rules/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.10.0/manifests/prometheusOperator-prometheusRule.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/platform-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/platform-operator/v0.7.2/config/deploy/crd.yml 3 | -------------------------------------------------------------------------------- /manifests/upstream/postgres-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/zalando/postgres-operator/v1.7.1/manifests/postgresql.crd.yaml 3 | - https://raw.githubusercontent.com/zalando/postgres-operator/v1.7.1/manifests/operatorconfiguration.crd.yaml 4 | - https://raw.githubusercontent.com/zalando/postgres-operator/v1.7.1/manifests/postgresteam.crd.yaml 5 | -------------------------------------------------------------------------------- /manifests/upstream/postgresql-db/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator-library/v0.1.5/config/crd/db/db.flanksource.com_postgresqldbs.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/postgresql-db/template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator-library/v0.1.5/config/templates/postgresql-db.yaml 3 | -------------------------------------------------------------------------------- /manifests/upstream/prometheus/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0alertmanagerConfigCustomResourceDefinition.yaml 3 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0alertmanagerCustomResourceDefinition.yaml 4 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0podmonitorCustomResourceDefinition.yaml 5 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0probeCustomResourceDefinition.yaml 6 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0prometheusCustomResourceDefinition.yaml 7 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0prometheusruleCustomResourceDefinition.yaml 8 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0servicemonitorCustomResourceDefinition.yaml 9 | - https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/v0.11.0/manifests/setup/0thanosrulerCustomResourceDefinition.yaml 10 | -------------------------------------------------------------------------------- /manifests/upstream/redis-db/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator-library/v0.1.6/config/crd/db/db.flanksource.com_redisdbs.yaml -------------------------------------------------------------------------------- /manifests/upstream/redis-db/template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator-library/v0.1.6/config/templates/redis-db.yaml -------------------------------------------------------------------------------- /manifests/upstream/redis/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/spotahome/redis-operator/db1e3162b2e8a4dd8320d921a403e2c1dbe556e3/manifests/databases.spotahome.com_redisfailovers.yaml -------------------------------------------------------------------------------- /manifests/upstream/sealed-secrets/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/v0.17.1/helm/sealed-secrets/crds/sealedsecret-crd.yaml -------------------------------------------------------------------------------- /manifests/upstream/service-monitor/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.53.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml -------------------------------------------------------------------------------- /manifests/upstream/template-operator/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator/v0.6.0/config/base/deploy.yml 3 | namespace: platform-system 4 | images: 5 | - name: flanksource/template-operator 6 | newName: docker.io/flanksource/template-operator 7 | newTag: "{{.templateOperator.version}}" 8 | patches: 9 | - patch: |- 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | metadata: 13 | name: template-operator-controller-manager 14 | namespace: template-operator 15 | spec: 16 | template: 17 | spec: 18 | containers: 19 | - name: manager 20 | args: 21 | - --metrics-addr=0.0.0.0:8080 22 | - --enable-leader-election 23 | - "--sync-period={{ .templateOperator.syncPeriod | default \"5m\" }}" 24 | resources: 25 | limits: 26 | cpu: 500m 27 | memory: 1Gi 28 | requests: 29 | cpu: 100m 30 | memory: 200Mi 31 | - patch: |- 32 | $patch: delete 33 | apiVersion: v1 34 | kind: Namespace 35 | metadata: 36 | name: template-operator 37 | -------------------------------------------------------------------------------- /manifests/upstream/template-operator/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/flanksource/template-operator/v0.6.0/config/deploy/crd.yml 3 | -------------------------------------------------------------------------------- /manifests/upstream/vpa/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - https://raw.githubusercontent.com/kubernetes/autoscaler/c4bd38b17a92b7039bbd3a2de67e53cf102b6936/vertical-pod-autoscaler/deploy/vpa-v1-crd-gen.yaml -------------------------------------------------------------------------------- /pkg/api/calico/register.go: -------------------------------------------------------------------------------- 1 | // +kubebuilder:object:generate=true 2 | package calico 3 | -------------------------------------------------------------------------------- /pkg/api/operator/v1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // Package v1 contains API Schema definitions for the karina.flanksource.com v1 API group 2 | // +kubebuilder:object:generate=true 3 | // +groupName=karina.flanksource.com 4 | package v1 5 | 6 | import ( 7 | "k8s.io/apimachinery/pkg/runtime/schema" 8 | "sigs.k8s.io/controller-runtime/pkg/scheme" 9 | ) 10 | 11 | var ( 12 | // GroupVersion is group version used to register these objects 13 | GroupVersion = schema.GroupVersion{Group: "karina.flanksource.com", Version: "v1"} 14 | 15 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 16 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 17 | 18 | // AddToScheme adds the types in this group-version to the given scheme. 19 | AddToScheme = SchemeBuilder.AddToScheme 20 | ) 21 | -------------------------------------------------------------------------------- /pkg/api/platformoperator/v1/webhook_types.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | type PodMutaterConfig struct { 4 | AnnotationsMap map[string]bool 5 | Annotations []string 6 | RegistryWhitelist []string 7 | DefaultRegistryPrefix string 8 | DefaultImagePullSecret string 9 | TolerationsAnnotation string 10 | } 11 | -------------------------------------------------------------------------------- /pkg/api/postgres/cluster_config.go: -------------------------------------------------------------------------------- 1 | package postgres 2 | 3 | type ClusterConfig struct { 4 | Name string 5 | Databases []string 6 | Namespace string 7 | 8 | EnableWalArchiving bool 9 | EnableWalClusterID bool 10 | UseWalgRestore bool 11 | BackupSchedule string 12 | AwsCredentialsSecret string 13 | 14 | Clone *CloneConfig 15 | } 16 | 17 | type CloneConfig struct { 18 | ClusterName string 19 | ClusterID string 20 | Timestamp string 21 | } 22 | 23 | func NewClusterConfig(clusterName string, dbNames ...string) ClusterConfig { 24 | config := ClusterConfig{ 25 | Name: clusterName, 26 | Databases: dbNames, 27 | Namespace: "postgres-operator", 28 | EnableWalArchiving: true, 29 | EnableWalClusterID: false, 30 | BackupSchedule: "*/5 * * * *", 31 | UseWalgRestore: true, 32 | AwsCredentialsSecret: "postgres-operator-cluster-environment", 33 | } 34 | return config 35 | } 36 | -------------------------------------------------------------------------------- /pkg/api/prometheus/register.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The prometheus-operator Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package prometheus 16 | 17 | const ( 18 | GroupName = "monitoring.coreos.com" 19 | ) 20 | -------------------------------------------------------------------------------- /pkg/api/prometheus/v1/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The prometheus-operator Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +k8s:deepcopy-gen=package 16 | // +groupName=monitoring.coreos.com 17 | 18 | package v1 19 | -------------------------------------------------------------------------------- /pkg/ca/ca.go: -------------------------------------------------------------------------------- 1 | package ca 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/flanksource/commons/certs" 8 | "github.com/flanksource/commons/files" 9 | "github.com/flanksource/commons/is" 10 | "github.com/flanksource/karina/pkg/types" 11 | ) 12 | 13 | // ReadCA opens the CA stored in the file ca.Cert using the private key in ca.PrivateKey 14 | // with key password ca.Password. 15 | func ReadCA(ca *types.CA) (*certs.Certificate, error) { 16 | var cert, privateKey string 17 | if strings.HasPrefix(ca.Cert, "-----BEGIN CERTIFICATE-----") { 18 | cert = ca.Cert 19 | } else { 20 | cert = files.SafeRead(ca.Cert) 21 | } 22 | 23 | if strings.HasPrefix(ca.PrivateKey, "-----BEGIN RSA PRIVATE KEY-----") { 24 | privateKey = ca.PrivateKey 25 | } else if is.File(ca.PrivateKey) { 26 | privateKey = files.SafeRead(ca.PrivateKey) 27 | } else { 28 | privateKey = ca.PrivateKey 29 | } 30 | 31 | if cert == "" { 32 | return nil, fmt.Errorf("unable to read certificate %s", ca.Cert) 33 | } 34 | 35 | if privateKey == "" { 36 | return nil, fmt.Errorf("unable to read private key %s", ca.PrivateKey) 37 | } 38 | 39 | if ca.Password == "" { 40 | return certs.DecodeCertificate([]byte(cert), []byte(privateKey)) 41 | } 42 | return certs.DecryptCertificate([]byte(cert), []byte(privateKey), []byte(ca.Password)) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/ca/validate.go: -------------------------------------------------------------------------------- 1 | package ca 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/flanksource/commons/certs" 7 | "github.com/flanksource/commons/files" 8 | "github.com/pkg/errors" 9 | ) 10 | 11 | func ValidateCA(certPath, privateKeyPath, password string) error { 12 | certKey := files.SafeRead(certPath) 13 | privateKey := files.SafeRead(privateKeyPath) 14 | 15 | var cert *certs.Certificate 16 | var err error 17 | 18 | if password != "" { 19 | cert, err = certs.DecryptCertificate([]byte(certKey), []byte(privateKey), []byte(password)) 20 | if err != nil { 21 | return errors.Wrap(err, "failed to decrypt certificate") 22 | } 23 | } else { 24 | cert, err = certs.DecodeCertificate([]byte(certKey), []byte(privateKey)) 25 | if err != nil { 26 | return errors.Wrap(err, "failed to decrypt certificate") 27 | } 28 | } 29 | 30 | hash, err := cert.GetHash() 31 | if err != nil { 32 | return errors.Wrap(err, "failed to get certificate hash") 33 | } 34 | fmt.Printf("Certificate hash is %s\n", hash) 35 | 36 | fmt.Printf("Expires at: %s\n", cert.X509.NotAfter) 37 | 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /pkg/client/dns/dummy.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "github.com/flanksource/commons/logger" 5 | ) 6 | 7 | type DummyDNSClient struct { 8 | logger.Logger 9 | Zone string 10 | } 11 | 12 | func (d DummyDNSClient) Append(domain string, records ...string) error { 13 | domain = subdomain(domain, d.Zone) 14 | d.Debugf("[DNS Stub] Append %s.%s %v", domain, d.Zone, records) 15 | return nil 16 | } 17 | func (d DummyDNSClient) Get(domain string) ([]string, error) { return nil, nil } 18 | func (d DummyDNSClient) Update(domain string, records ...string) error { 19 | domain = subdomain(domain, d.Zone) 20 | d.Debugf("[DNS Stub] Update %s.%s %v", domain, d.Zone, records) 21 | return nil 22 | } 23 | func (d DummyDNSClient) Delete(domain string, records ...string) error { 24 | domain = subdomain(domain, d.Zone) 25 | d.Debugf("[DNS Stub] Delete %s.%s %v", domain, d.Zone, records) 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /pkg/client/postgres/restic.go: -------------------------------------------------------------------------------- 1 | package postgres 2 | 3 | import "time" 4 | 5 | type ResticSnapshot struct { 6 | Time time.Time 7 | Paths []string 8 | Tags []string 9 | ID string 10 | ShortID string `json:"short_id"` 11 | } 12 | -------------------------------------------------------------------------------- /pkg/constants/const.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const KubeSystem = "kube-system" 4 | const PlatformSystem = "platform-system" 5 | const DockerRuntime = "docker" 6 | const ContainerdRuntime = "containerd" 7 | const ValidatingWebhookConfiguration = "ValidatingWebhookConfiguration" 8 | const MutatingWebhookConfiguration = "MutatingWebhookConfiguration" 9 | const DefaultIssuer = "default-issuer" 10 | const DefaultIssuerCA = "default-issuer-ca" 11 | const MasterNodeLabel = "node-role.kubernetes.io/master" 12 | const NodePoolLabel = "karina.flanksource.com/pool" 13 | const NodeGroupTaint = "node.kubernetes.io/group" 14 | const ManagedBy = "apps.kubernetes.io/managed-by" 15 | const Karina = "karina" 16 | 17 | var PlatformNamespaces = []string{ 18 | "cert-manager", 19 | "dex", 20 | "eck", 21 | "elastic-system", 22 | "gatekeeper-system", 23 | "harbor", 24 | "ingress-nginx", 25 | "kube-system", 26 | "local-path-storage", 27 | "minio", 28 | "monitoring", 29 | "nsx-system", 30 | "opa", 31 | "platform-system", 32 | "postgres-operator", 33 | "sealed-secrets", 34 | "tekton", 35 | "vault", 36 | "velero", 37 | } 38 | -------------------------------------------------------------------------------- /pkg/constants/runtime_objects.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import ( 4 | "github.com/flanksource/kommons" 5 | appsv1beta1 "k8s.io/api/apps/v1beta1" 6 | v1 "k8s.io/api/core/v1" 7 | extensionsv1beta1 "k8s.io/api/extensions/v1beta1" 8 | ) 9 | 10 | var RuntimeObjects = map[string]kommons.RuntimeObjectWithMetadata{ 11 | "configmap": &v1.ConfigMap{}, 12 | "daemonset": &extensionsv1beta1.DaemonSet{}, 13 | "deployment": &extensionsv1beta1.Deployment{}, 14 | "namespace": &v1.Namespace{}, 15 | "node": &v1.Node{}, 16 | "persistentvolumeclaims": &v1.PersistentVolumeClaim{}, 17 | "persistentvolume": &v1.PersistentVolume{}, 18 | "pod": &v1.Pod{}, 19 | "secret": &v1.Secret{}, 20 | "service": &v1.Service{}, 21 | "statefulset": &appsv1beta1.StatefulSet{}, 22 | } 23 | -------------------------------------------------------------------------------- /pkg/phases/antrea/install.go: -------------------------------------------------------------------------------- 1 | package antrea 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/flanksource/karina/pkg/platform" 7 | ) 8 | 9 | const ( 10 | Namespace = "kube-system" 11 | Controller = "antrea-controller" 12 | DaemonSet = "antrea-agent" 13 | ) 14 | 15 | func Install(p *platform.Platform) error { 16 | if !p.Calico.IsDisabled() && !p.Antrea.IsDisabled() { 17 | p.Fatalf("both calico and antrea are enabled. Please disable one of them to continue") 18 | } 19 | 20 | if p.Antrea.IsDisabled() { 21 | return p.DeleteSpecs(Namespace, "antrea.yaml") 22 | } 23 | p.Antrea.IsCertReady = false 24 | if err := p.ApplySpecs(Namespace, "antrea.yaml"); err != nil { 25 | return err 26 | } 27 | 28 | if err := p.WaitForDeployment(Namespace, Controller, 10*time.Minute); err != nil { 29 | return err 30 | } 31 | return p.WaitForDaemonSet(Namespace, DaemonSet, 10*time.Minute) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/phases/antrea/test.go: -------------------------------------------------------------------------------- 1 | package antrea 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.Antrea.IsDisabled() { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestDeploy(client, Namespace, "antrea-controller", test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/apacheds/install.go: -------------------------------------------------------------------------------- 1 | package apacheds 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const Namespace = "ldap" 8 | 9 | func Install(platform *platform.Platform) error { 10 | if platform.Ldap == nil || platform.Ldap.Disabled || !platform.Ldap.E2E.Mock { 11 | return platform.DeleteSpecs(Namespace, "apacheds.yaml") 12 | } 13 | 14 | if err := platform.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 15 | return err 16 | } 17 | 18 | return platform.ApplySpecs(Namespace, "apacheds.yaml") 19 | } 20 | -------------------------------------------------------------------------------- /pkg/phases/apacheds/test.go: -------------------------------------------------------------------------------- 1 | package apacheds 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | client, _ := p.GetClientset() 11 | if p.Ldap.E2E.Mock { 12 | kommons.TestNamespace(client, Namespace, test) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pkg/phases/argocdoperator/install.go: -------------------------------------------------------------------------------- 1 | package argocdoperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const ( 8 | Namespace = "argocd" 9 | ) 10 | 11 | func Deploy(platform *platform.Platform) error { 12 | if platform.ArgocdOperator.IsDisabled() { 13 | return platform.DeleteSpecs(Namespace, "argocd-operator.yaml", "argocd-rbac.yaml") 14 | } 15 | 16 | if err := platform.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 17 | return err 18 | } 19 | 20 | return platform.ApplySpecs(Namespace, "argocd-operator.yaml", "argocd-rbac.yaml") 21 | } 22 | -------------------------------------------------------------------------------- /pkg/phases/argorollouts/install.go: -------------------------------------------------------------------------------- 1 | package argorollouts 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Deploy(platform *platform.Platform) error { 9 | if platform.ArgoRollouts.IsDisabled() { 10 | return platform.DeleteSpecs("", "argo-rollouts.yaml") 11 | } 12 | 13 | if err := platform.CreateOrUpdateNamespace(constants.PlatformSystem, nil, nil); err != nil { 14 | return err 15 | } 16 | 17 | return platform.ApplySpecs(constants.PlatformSystem, "argo-rollouts.yaml") 18 | } 19 | -------------------------------------------------------------------------------- /pkg/phases/auditbeat/install.go: -------------------------------------------------------------------------------- 1 | package auditbeat 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Deploy(p *platform.Platform) error { 9 | if p.Auditbeat.IsDisabled() { 10 | return p.DeleteSpecs(constants.PlatformSystem, "auditbeat.yaml") 11 | } 12 | 13 | return p.ApplySpecs(constants.PlatformSystem, "auditbeat.yaml") 14 | } 15 | -------------------------------------------------------------------------------- /pkg/phases/base/install.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/flanksource/karina/pkg/constants" 7 | "github.com/flanksource/karina/pkg/platform" 8 | ) 9 | 10 | func Install(platform *platform.Platform) error { 11 | os.Mkdir(".bin", 0755) // nolint: errcheck 12 | 13 | if err := platform.ApplySpecs("", "rbac.yaml"); err != nil { 14 | platform.Errorf("Error deploying base rbac: %s", err) 15 | } 16 | 17 | if err := platform.CreateOrUpdateNamespace(constants.KubeSystem, nil, nil); err != nil { 18 | platform.Errorf("Error deploying base kube-system labels/annotations: %s", err) 19 | } 20 | 21 | if err := platform.CreateOrUpdateNamespace("monitoring", nil, nil); err != nil { 22 | platform.Errorf("Error deploying base monitoring labels/annotations: %s", err) 23 | } 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /pkg/phases/calico/install.go: -------------------------------------------------------------------------------- 1 | package calico 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/flanksource/karina/pkg/platform" 7 | ) 8 | 9 | const ( 10 | Namespace = "kube-system" 11 | Controller = "calico-kube-controllers" 12 | DaemonSet = "calico-node" 13 | ) 14 | 15 | func Install(platform *platform.Platform) error { 16 | if !platform.Calico.IsDisabled() && !platform.Antrea.IsDisabled() { 17 | platform.Fatalf("both calico and antrea are enabled. Please disable one of them to continue") 18 | } 19 | 20 | if platform.Calico.IsDisabled() { 21 | return platform.DeleteSpecs(Namespace, "calico.yaml") 22 | } 23 | 24 | if err := platform.ApplySpecs(Namespace, "calico.yaml"); err != nil { 25 | return err 26 | } 27 | 28 | if err := platform.WaitForDeployment(Namespace, Controller, 2*time.Minute); err != nil { 29 | return err 30 | } 31 | return platform.WaitForDaemonSet(Namespace, DaemonSet, 2*time.Minute) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/phases/calico/test.go: -------------------------------------------------------------------------------- 1 | package calico 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.Calico.IsDisabled() { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestDeploy(client, Namespace, "calico-kube-controllers", test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/canary/deploy.go: -------------------------------------------------------------------------------- 1 | package canary 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | ) 7 | 8 | var specs = []string{"canary-checker.yaml", "canary-checker-monitoring.yaml.raw"} 9 | 10 | // Deploy deploys the canary-checker into the monitoring namespace 11 | func Deploy(p *platform.Platform) error { 12 | if p.CanaryChecker.IsDisabled() { 13 | return nil 14 | } 15 | 16 | return p.ApplySpecs(v1.NamespaceAll, specs...) 17 | } 18 | -------------------------------------------------------------------------------- /pkg/phases/canary/test.go: -------------------------------------------------------------------------------- 1 | package canary 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/constants" 6 | "github.com/flanksource/karina/pkg/platform" 7 | "github.com/flanksource/kommons" 8 | ) 9 | 10 | const testName = "canary-checker" 11 | 12 | func TestCanary(p *platform.Platform, test *console.TestResults) { 13 | if p.CanaryChecker.IsDisabled() { 14 | return 15 | } 16 | 17 | client, err := p.GetClientset() 18 | if err != nil { 19 | test.Failf(testName, "couldn't get clientset: %v", err) 20 | return 21 | } 22 | 23 | kommons.TestStatefulSet(client, constants.PlatformSystem, "canary-checker", test) 24 | } 25 | -------------------------------------------------------------------------------- /pkg/phases/certmanager/test.go: -------------------------------------------------------------------------------- 1 | package certmanager 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | client, _ := p.GetClientset() 11 | kommons.TestNamespace(client, Namespace, test) 12 | } 13 | -------------------------------------------------------------------------------- /pkg/phases/configmapreloader/install.go: -------------------------------------------------------------------------------- 1 | package configmapreloader 2 | 3 | import ( 4 | "github.com/flanksource/commons/utils" 5 | 6 | "github.com/flanksource/karina/pkg/constants" 7 | "github.com/flanksource/karina/pkg/platform" 8 | ) 9 | 10 | func Deploy(p *platform.Platform) error { 11 | if p.ConfigMapReloader.Disabled { 12 | if err := p.DeleteSpecs(constants.PlatformSystem, "configmap-reloader.yaml"); err != nil { 13 | p.Warnf("failed to delete specs: %v", err) 14 | } 15 | return nil 16 | } 17 | 18 | if p.ConfigMapReloader.Version == "" { 19 | p.ConfigMapReloader.Version = "v0.0.56" 20 | } else { 21 | p.ConfigMapReloader.Version = utils.NormalizeVersion(p.ConfigMapReloader.Version) 22 | } 23 | 24 | if err := p.CreateOrUpdateNamespace(constants.PlatformSystem, nil, nil); err != nil { 25 | return err 26 | } 27 | return p.ApplySpecs("", "configmap-reloader.yaml") 28 | } 29 | -------------------------------------------------------------------------------- /pkg/phases/conformance.go: -------------------------------------------------------------------------------- 1 | package phases 2 | 3 | import ( 4 | "fmt" 5 | 6 | log "github.com/sirupsen/logrus" 7 | 8 | "github.com/flanksource/karina/pkg/platform" 9 | ) 10 | 11 | func ConformanceTest(p *platform.Platform, options ConformanceTestOptions) error { 12 | sonobuoy := p.GetBinaryWithKubeConfig("sonobuoy") 13 | args := "" 14 | args += fmt.Sprintf(" --wait=%d --wait-output Spinner", options.Wait) 15 | 16 | if options.Quick { 17 | args += " --mode quick" 18 | } 19 | 20 | if log.IsLevelEnabled(log.DebugLevel) { 21 | args += " -v 1" 22 | } else if log.IsLevelEnabled(log.TraceLevel) { 23 | args += " -v 2" 24 | } 25 | 26 | if err := sonobuoy("run %s", args); err != nil { 27 | return fmt.Errorf("error submitting sonobuoy tests: %v", err) 28 | } 29 | if err := sonobuoy("retrieve %s", options.OutputDir); err != nil { 30 | return fmt.Errorf("error retrieving sonobuoy test results: %v", err) 31 | } 32 | return sonobuoy("delete --all") 33 | } 34 | 35 | type ConformanceTestOptions struct { 36 | Certification, KubeBench, Quick bool 37 | Wait int 38 | OutputDir string 39 | } 40 | -------------------------------------------------------------------------------- /pkg/phases/csi/localpath/install.go: -------------------------------------------------------------------------------- 1 | package localpath 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const Namespace = "local-path-storage" 8 | 9 | func Install(platform *platform.Platform) error { 10 | if platform.LocalPath.Disabled { 11 | return platform.DeleteSpecs(Namespace, "local-path.yaml") 12 | } 13 | 14 | if err := platform.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 15 | return err 16 | } 17 | return platform.ApplySpecs(Namespace, "local-path.yaml") 18 | } 19 | -------------------------------------------------------------------------------- /pkg/phases/csi/localpath/test.go: -------------------------------------------------------------------------------- 1 | package localpath 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.LocalPath.Disabled { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestNamespace(client, Namespace, test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/csi/nfs/install.go: -------------------------------------------------------------------------------- 1 | package nfs 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | const Namespace = constants.KubeSystem 9 | 10 | func Install(platform *platform.Platform) error { 11 | if platform.NFS == nil { 12 | return platform.DeleteSpecs(Namespace, "nfs.yaml") 13 | } 14 | return platform.ApplySpecs(Namespace, "nfs.yaml") 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/csi/nfs/test.go: -------------------------------------------------------------------------------- 1 | package nfs 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.NFS == nil { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestDeploy(client, Namespace, "nfs-client-provisioner", test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/csi/s3/install.go: -------------------------------------------------------------------------------- 1 | package s3 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | const Namespace = constants.KubeSystem 9 | 10 | func Install(platform *platform.Platform) error { 11 | if !platform.S3.CSIVolumes { 12 | return platform.DeleteSpecs(Namespace, "csi-s3.yaml") 13 | } 14 | 15 | err := platform.CreateOrUpdateSecret("csi-s3-secret", Namespace, map[string][]byte{ 16 | "accessKeyID": []byte(platform.S3.AccessKey), 17 | "secretAccessKey": []byte(platform.S3.SecretKey), 18 | "endpoint": []byte("https://" + platform.S3.Endpoint), 19 | "region": []byte(platform.S3.Region), 20 | }) 21 | if err != nil { 22 | return err 23 | } 24 | return platform.ApplySpecs(Namespace, "csi-s3.yaml") 25 | } 26 | -------------------------------------------------------------------------------- /pkg/phases/csi/s3/test.go: -------------------------------------------------------------------------------- 1 | package s3 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if !p.S3.CSIVolumes { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestDeploy(client, Namespace, "csi-attacher-s3", test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/dashboard/install.go: -------------------------------------------------------------------------------- 1 | package dashboard 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | const ( 9 | Namespace = constants.KubeSystem 10 | ) 11 | 12 | func Install(p *platform.Platform) error { 13 | if p.Dashboard.IsDisabled() { 14 | return p.DeleteSpecs(Namespace, "k8s-dashboard.yaml") 15 | } 16 | 17 | return p.ApplySpecs(Namespace, "k8s-dashboard.yaml") 18 | } 19 | -------------------------------------------------------------------------------- /pkg/phases/eck/install.go: -------------------------------------------------------------------------------- 1 | package eck 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/flanksource/karina/pkg/platform" 7 | ) 8 | 9 | const Namespace = "elastic-system" 10 | 11 | func Deploy(p *platform.Platform) error { 12 | if p.ECK.IsDisabled() { 13 | return nil 14 | } 15 | p.Infof("Deploying ECK %s", p.ECK.Version) 16 | if err := p.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 17 | return fmt.Errorf("install: failed to create/update namespace: %v", err) 18 | } 19 | 20 | return p.ApplySpecs(Namespace, "eck.yaml") 21 | } 22 | -------------------------------------------------------------------------------- /pkg/phases/eck/test.go: -------------------------------------------------------------------------------- 1 | package eck 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | client, _ := p.GetClientset() 11 | if p.ECK.IsDisabled() { 12 | return 13 | } 14 | kommons.TestNamespace(client, Namespace, test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/elasticsearch/install.go: -------------------------------------------------------------------------------- 1 | package elasticsearch 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | "github.com/flanksource/karina/pkg/types" 6 | ) 7 | 8 | const Namespace = "eck" 9 | 10 | func Deploy(p *platform.Platform) error { 11 | if p.Elasticsearch == nil || p.Elasticsearch.Disabled { 12 | return nil 13 | } 14 | 15 | if err := p.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 16 | return err 17 | } 18 | if p.Elasticsearch.Mem == nil { 19 | p.Elasticsearch.Mem = &types.Memory{Limits: "3G", Requests: "2G"} 20 | } 21 | if p.Elasticsearch.Replicas == 0 { 22 | p.Elasticsearch.Replicas = 3 23 | } 24 | if p.OAuth2Proxy == nil { 25 | p.OAuth2Proxy = &types.OAuth2Proxy{ 26 | Disabled: true, 27 | } 28 | } 29 | 30 | if p.Elasticsearch.Persistence == nil { 31 | p.Elasticsearch.Persistence = &types.Persistence{ 32 | XEnabled: types.XEnabled{ 33 | Disabled: true, 34 | }, 35 | StorageClass: "", 36 | Capacity: "", 37 | } 38 | } 39 | 40 | return p.ApplySpecs(Namespace, "elasticsearch.yaml") 41 | } 42 | -------------------------------------------------------------------------------- /pkg/phases/eventrouter/deploy.go: -------------------------------------------------------------------------------- 1 | package eventrouter 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Deploy(p *platform.Platform) error { 9 | if p.EventRouter.IsDisabled() { 10 | return p.DeleteSpecs(constants.PlatformSystem, "eventrouter.yaml") 11 | } 12 | 13 | return p.ApplySpecs(constants.PlatformSystem, "eventrouter.yaml") 14 | } 15 | -------------------------------------------------------------------------------- /pkg/phases/externaldns/install.go: -------------------------------------------------------------------------------- 1 | package externaldns 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const ( 8 | Namespace = "platform-system" 9 | ) 10 | 11 | func Install(p *platform.Platform) error { 12 | if p.ExternalDNS.IsDisabled() { 13 | return p.DeleteSpecs(Namespace, "external-dns.yaml") 14 | } 15 | 16 | return p.ApplySpecs(Namespace, "external-dns.yaml") 17 | } 18 | -------------------------------------------------------------------------------- /pkg/phases/externaldns/test.go: -------------------------------------------------------------------------------- 1 | package externaldns 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.ExternalDNS.IsDisabled() { 11 | return 12 | } 13 | 14 | client, _ := p.GetClientset() 15 | 16 | kommons.TestDeploy(client, Namespace, "external-dns", test) 17 | } 18 | -------------------------------------------------------------------------------- /pkg/phases/flux/fluxv2.go: -------------------------------------------------------------------------------- 1 | package flux 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/flanksource/karina/pkg/platform" 7 | ) 8 | 9 | const Namespace = "flux-system" 10 | 11 | func InstallV2(p *platform.Platform) error { 12 | if p.Flux == nil || !p.Flux.Enabled { 13 | return nil 14 | } 15 | 16 | if err := p.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 17 | return fmt.Errorf("install: failed to create/update namespace: %v", err) 18 | } 19 | 20 | return p.ApplySpecs(Namespace, "flux.yaml") 21 | } 22 | -------------------------------------------------------------------------------- /pkg/phases/gitoperator/install.go: -------------------------------------------------------------------------------- 1 | package gitoperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const ( 8 | Namespace = "platform-system" 9 | ) 10 | 11 | func Install(p *platform.Platform) error { 12 | if p.GitOperator.IsDisabled() { 13 | return p.DeleteSpecs(Namespace, "git-operator.yaml") 14 | } 15 | 16 | return p.ApplySpecs(Namespace, "git-operator.yaml") 17 | } 18 | -------------------------------------------------------------------------------- /pkg/phases/gitoperator/test.go: -------------------------------------------------------------------------------- 1 | package gitoperator 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.GitOperator.IsDisabled() { 11 | return 12 | } 13 | 14 | client, _ := p.GetClientset() 15 | kommons.TestDeploy(client, Namespace, "git-operator-controller-manager", test) 16 | } 17 | -------------------------------------------------------------------------------- /pkg/phases/harbor/test.go: -------------------------------------------------------------------------------- 1 | package harbor 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.Harbor.IsDisabled() { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestNamespace(client, "harbor", test) 15 | harbor, err := NewClient(p) 16 | if err != nil { 17 | test.Failf(Namespace, "failed to get harbor client: %v", err) 18 | return 19 | } 20 | var status *Status 21 | status, err = harbor.GetStatus() 22 | if err != nil { 23 | test.Failf("Harbor", "Failed to get harbor status %v", err) 24 | return 25 | } 26 | 27 | for _, component := range status.Components { 28 | if component.Status == "healthy" { 29 | test.Passf("Harbor", component.Name) 30 | } else { 31 | test.Failf("Harbor", "%s is %s", component.Name, component.Status) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pkg/phases/ingress/install.go: -------------------------------------------------------------------------------- 1 | package ingress 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/phases/nginx" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Install(p *platform.Platform) error { 9 | return nginx.Install(p) 10 | } 11 | -------------------------------------------------------------------------------- /pkg/phases/istiooperator/install.go: -------------------------------------------------------------------------------- 1 | package istiooperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const ( 8 | Namespace = "istio-operator" 9 | ) 10 | 11 | func Install(p *platform.Platform) error { 12 | if p.IstioOperator.IsDisabled() { 13 | return p.DeleteSpecs(Namespace, "istio-operator.yaml") 14 | } 15 | 16 | return p.ApplySpecs(Namespace, "istio-operator.yaml") 17 | } 18 | -------------------------------------------------------------------------------- /pkg/phases/istiooperator/test.go: -------------------------------------------------------------------------------- 1 | package istiooperator 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/flanksource/commons/console" 7 | "github.com/flanksource/karina/pkg/platform" 8 | "github.com/flanksource/kommons" 9 | ) 10 | 11 | func Test(p *platform.Platform, test *console.TestResults) { 12 | if p.IstioOperator.IsDisabled() { 13 | return 14 | } 15 | 16 | client, err := p.GetClientset() 17 | if err != nil { 18 | test.Failf(Namespace, "Could not connect to Platform client: %v", err) 19 | return 20 | } 21 | _ = p.WaitForNamespace(Namespace, 60*time.Second) 22 | kommons.TestNamespace(client, Namespace, test) 23 | } 24 | -------------------------------------------------------------------------------- /pkg/phases/journalbeat/install.go: -------------------------------------------------------------------------------- 1 | package journalbeat 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Deploy(p *platform.Platform) error { 9 | if p.Journalbeat.IsDisabled() { 10 | return p.DeleteSpecs(constants.PlatformSystem, "journalbeat.yaml") 11 | } 12 | 13 | return p.ApplySpecs(constants.PlatformSystem, "journalbeat.yaml") 14 | } 15 | -------------------------------------------------------------------------------- /pkg/phases/karinaoperator/install.go: -------------------------------------------------------------------------------- 1 | package karinaoperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const ( 8 | Namespace = "platform-system" 9 | ) 10 | 11 | func Install(p *platform.Platform) error { 12 | if p.KarinaOperator.IsDisabled() { 13 | return p.DeleteSpecs(Namespace, "karina-operator.yaml") 14 | } 15 | 16 | return p.ApplySpecs(Namespace, "karina-operator.yaml") 17 | } 18 | -------------------------------------------------------------------------------- /pkg/phases/karinaoperator/test.go: -------------------------------------------------------------------------------- 1 | package karinaoperator 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.KarinaOperator.IsDisabled() { 11 | return 12 | } 13 | 14 | client, _ := p.GetClientset() 15 | kommons.TestDeploy(client, Namespace, "karina-operator", test) 16 | } 17 | -------------------------------------------------------------------------------- /pkg/phases/logsexporter/install.go: -------------------------------------------------------------------------------- 1 | package logsexporter 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Install(p *platform.Platform) error { 9 | if p.LogsExporter.IsDisabled() { 10 | return p.DeleteSpecs(constants.PlatformSystem, "logs-exporter.yaml") 11 | } 12 | 13 | return p.ApplySpecs(constants.PlatformSystem, "logs-exporter.yaml") 14 | } 15 | -------------------------------------------------------------------------------- /pkg/phases/minio/install.go: -------------------------------------------------------------------------------- 1 | package minio 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/flanksource/karina/pkg/platform" 7 | ) 8 | 9 | const ( 10 | Namespace = "minio" 11 | Name = "minio" 12 | ) 13 | 14 | func Install(platform *platform.Platform) error { 15 | if platform.Minio.Replicas == 0 { 16 | platform.Minio.Replicas = 1 17 | } 18 | if platform.Minio.IsDisabled() { 19 | return platform.DeleteSpecs(Namespace, "minio.yaml") 20 | } 21 | if err := platform.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 22 | return err 23 | } 24 | 25 | if err := platform.ApplySpecs(Namespace, "minio.yaml"); err != nil { 26 | return nil 27 | } 28 | 29 | return platform.WaitForStatefulSet(Namespace, Name, 120*time.Second) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/phases/mongodboperator/install.go: -------------------------------------------------------------------------------- 1 | package mongodboperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Deploy(platform *platform.Platform) error { 9 | if platform.MongodbOperator.IsDisabled() { 10 | return platform.DeleteSpecs("", "mongodb-operator.yaml", "template/mongo-db.yaml.raw") 11 | } 12 | 13 | if err := platform.CreateOrUpdateNamespace(constants.PlatformSystem, nil, nil); err != nil { 14 | return err 15 | } 16 | 17 | // Trim the first character e.g. v1.6.0 -> 1.6.0 18 | platform.MongodbOperator.Version = platform.MongodbOperator.Version[1:] 19 | 20 | return platform.ApplySpecs(constants.PlatformSystem, "mongodb-operator.yaml", "template/mongo-db.yaml.raw") 21 | } 22 | -------------------------------------------------------------------------------- /pkg/phases/nginx/test.go: -------------------------------------------------------------------------------- 1 | package nginx 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.Nginx != nil && p.Nginx.Disabled { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestNamespace(client, Namespace, test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/nodelocaldns/install.go: -------------------------------------------------------------------------------- 1 | package nodelocaldns 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/flanksource/karina/pkg/constants" 8 | "github.com/flanksource/karina/pkg/platform" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | ) 11 | 12 | const Namespace = constants.KubeSystem 13 | 14 | func Install(platform *platform.Platform) error { 15 | if platform.NodeLocalDNS.Disabled { 16 | return platform.DeleteSpecs(Namespace, "node-local-dns.yaml") 17 | } 18 | client, err := platform.GetClientset() 19 | if err != nil { 20 | return err 21 | } 22 | 23 | kubeDNS, err := client.CoreV1().Services("kube-system").Get(context.TODO(), "kube-dns", metav1.GetOptions{}) 24 | if err != nil { 25 | return fmt.Errorf("install: Failed to get service: %v", err) 26 | } 27 | 28 | platform.NodeLocalDNS.DNSServer = kubeDNS.Spec.ClusterIP 29 | 30 | platform.NodeLocalDNS.LocalDNS = "169.254.20.10" 31 | platform.NodeLocalDNS.DNSDomain = "cluster.local" 32 | 33 | return platform.ApplySpecs(Namespace, "node-local-dns.yaml") 34 | } 35 | -------------------------------------------------------------------------------- /pkg/phases/nodelocaldns/test.go: -------------------------------------------------------------------------------- 1 | package nodelocaldns 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.NodeLocalDNS.Disabled { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | kommons.TestDeploy(client, Namespace, "node-local-dns", test) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/phases/packetbeat/deploy.go: -------------------------------------------------------------------------------- 1 | package packetbeat 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Deploy(p *platform.Platform) error { 9 | if p.Packetbeat.IsDisabled() { 10 | return p.DeleteSpecs(constants.PlatformSystem, "packetbeat.yaml") 11 | } 12 | return p.ApplySpecs(constants.PlatformSystem, "packetbeat.yaml") 13 | } 14 | -------------------------------------------------------------------------------- /pkg/phases/pre/install.go: -------------------------------------------------------------------------------- 1 | package pre 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/phases/certmanager" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | func Install(platform *platform.Platform) error { 9 | // If more preinstall functions are needed, add per function error checking 10 | return certmanager.PreInstall(platform) 11 | } 12 | -------------------------------------------------------------------------------- /pkg/phases/rabbitmqoperator/install.go: -------------------------------------------------------------------------------- 1 | package rabbitmqoperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const ( 8 | Namespace = "rabbitmq-system" 9 | ) 10 | 11 | func Install(p *platform.Platform) error { 12 | if p.RabbitmqOperator.IsDisabled() { 13 | return p.DeleteSpecs(Namespace, "rabbitmq.yaml") 14 | } 15 | 16 | if err := p.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 17 | return err 18 | } 19 | 20 | return p.ApplySpecs(Namespace, "rabbitmq.yaml") 21 | } 22 | -------------------------------------------------------------------------------- /pkg/phases/rabbitmqoperator/test.go: -------------------------------------------------------------------------------- 1 | package rabbitmqoperator 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.RabbitmqOperator.IsDisabled() { 11 | return 12 | } 13 | 14 | client, _ := p.GetClientset() 15 | kommons.TestNamespace(client, Namespace, test) 16 | } 17 | -------------------------------------------------------------------------------- /pkg/phases/redisoperator/install.go: -------------------------------------------------------------------------------- 1 | package redisoperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/platform" 5 | ) 6 | 7 | const ( 8 | Namespace = "redis-operator" 9 | ) 10 | 11 | func Install(p *platform.Platform) error { 12 | if p.RedisOperator.IsDisabled() { 13 | return p.DeleteSpecs(Namespace, "redis-operator.yaml") 14 | } 15 | 16 | if err := p.CreateOrUpdateNamespace(Namespace, nil, nil); err != nil { 17 | return err 18 | } 19 | 20 | return p.ApplySpecs(Namespace, "redis-operator.yaml", "template/redis-db.yaml.raw") 21 | } 22 | -------------------------------------------------------------------------------- /pkg/phases/redisoperator/test.go: -------------------------------------------------------------------------------- 1 | package redisoperator 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.RedisOperator.IsDisabled() { 11 | return 12 | } 13 | 14 | client, _ := p.GetClientset() 15 | kommons.TestNamespace(client, Namespace, test) 16 | } 17 | -------------------------------------------------------------------------------- /pkg/phases/registrycreds/install.go: -------------------------------------------------------------------------------- 1 | package registrycreds 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/pkg/errors" 7 | ) 8 | 9 | func Install(p *platform.Platform) error { 10 | if p.RegistryCredentials == nil || p.RegistryCredentials.Disabled { 11 | return nil 12 | } 13 | if p.RegistryCredentials.Namespace == "" { 14 | p.RegistryCredentials.Namespace = constants.PlatformSystem 15 | } 16 | namespace := p.RegistryCredentials.Namespace 17 | 18 | if err := p.CreateOrUpdateNamespace(namespace, nil, nil); err != nil { 19 | return errors.Wrapf(err, "install: failed to create/update namespace: %s", namespace) 20 | } 21 | 22 | if err := p.ApplySpecs(namespace, "registry-creds-secrets.yaml"); err != nil { 23 | return errors.Wrap(err, "install: failed to apply registry-creds-secrets.yaml") 24 | } 25 | 26 | if err := p.ApplySpecs(namespace, "registry-creds.yaml"); err != nil { 27 | return errors.Wrap(err, "install: failed to apply registry-creds.yaml") 28 | } 29 | 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /pkg/phases/templateoperator/install.go: -------------------------------------------------------------------------------- 1 | package templateoperator 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | const ( 9 | Namespace = constants.PlatformSystem 10 | Name = "template-operator-controller-manager" 11 | ) 12 | 13 | func Install(p *platform.Platform) error { 14 | if p.TemplateOperator.IsDisabled() { 15 | return p.DeleteSpecs(Namespace, "template-operator.yaml") 16 | } 17 | 18 | if err := p.CreateOrUpdateNamespace(constants.PlatformSystem, nil, nil); err != nil { 19 | return err 20 | } 21 | 22 | return p.ApplySpecs(Namespace, "template-operator.yaml") 23 | } 24 | -------------------------------------------------------------------------------- /pkg/phases/templateoperator/test.go: -------------------------------------------------------------------------------- 1 | package templateoperator 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/flanksource/commons/console" 7 | "github.com/flanksource/karina/pkg/platform" 8 | ) 9 | 10 | func Test(p *platform.Platform, test *console.TestResults) { 11 | if p.TemplateOperator.IsDisabled() { 12 | return 13 | } 14 | 15 | if err := p.WaitForDeployment(Namespace, Name, 60*time.Second); err != nil { 16 | test.Failf(Name, "template-operator did not become ready") 17 | return 18 | } 19 | test.Passf(Name, "template-operator is ready") 20 | } 21 | -------------------------------------------------------------------------------- /pkg/phases/vault/test.go: -------------------------------------------------------------------------------- 1 | package vault 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | 6 | "github.com/flanksource/karina/pkg/platform" 7 | "github.com/flanksource/kommons" 8 | ) 9 | 10 | func Test(p *platform.Platform, test *console.TestResults) { 11 | if p.Vault == nil || p.Vault.Disabled { 12 | return 13 | } 14 | 15 | client, _ := p.GetClientset() 16 | kommons.TestNamespace(client, Namespace, test) 17 | } 18 | -------------------------------------------------------------------------------- /pkg/phases/velero/test.go: -------------------------------------------------------------------------------- 1 | package velero 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.Velero.IsDisabled() { 11 | return 12 | } 13 | client, err := p.GetClientset() 14 | if err != nil { 15 | test.Failf("velero", "Failed to get k8s client %v", err) 16 | return 17 | } 18 | 19 | kommons.TestNamespace(client, Namespace, test) 20 | 21 | if !p.E2E { 22 | return 23 | } 24 | 25 | if backup, err := CreateBackup(p); err != nil { 26 | test.Failf("velero", "Failed to create backup: %v", err) 27 | } else { 28 | test.Passf("velero", "Backup %s created successfully in %s", backup.Metadata.Name, backup.Status.CompletionTimestamp.Sub(backup.Status.StartTimestamp.Time)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pkg/phases/vpa/deploy.go: -------------------------------------------------------------------------------- 1 | package vpa 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/constants" 5 | "github.com/flanksource/karina/pkg/platform" 6 | ) 7 | 8 | const ( 9 | Namespace = constants.KubeSystem 10 | ) 11 | 12 | func Install(p *platform.Platform) error { 13 | if p.VPA.IsDisabled() { 14 | return p.DeleteSpecs(Namespace, "vpa.yaml") 15 | } 16 | 17 | return p.ApplySpecs(Namespace, "vpa.yaml") 18 | } 19 | -------------------------------------------------------------------------------- /pkg/phases/vpa/test.go: -------------------------------------------------------------------------------- 1 | package vpa 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(p *platform.Platform, test *console.TestResults) { 10 | if p.VPA.IsDisabled() { 11 | return 12 | } 13 | client, _ := p.GetClientset() 14 | 15 | for _, deployment := range []string{"vpa-admission-controller", "vpa-recommender", "vpa-updater"} { 16 | kommons.TestDeploy(client, Namespace, deployment, test) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pkg/phases/vsphere/test.go: -------------------------------------------------------------------------------- 1 | package vsphere 2 | 3 | import ( 4 | "github.com/flanksource/commons/console" 5 | "github.com/flanksource/karina/pkg/platform" 6 | "github.com/flanksource/kommons" 7 | ) 8 | 9 | func Test(platform *platform.Platform, test *console.TestResults) { 10 | if platform.Vsphere == nil { 11 | return 12 | } 13 | client, _ := platform.GetClientset() 14 | 15 | if platform.Vsphere.CPIVersion != "" { 16 | kommons.TestDaemonSet(client, Namespace, "vsphere-cloud-controller-manager", test) 17 | } 18 | if platform.Vsphere.CSIVersion != "" { 19 | kommons.TestDeploy(client, Namespace, "vsphere-csi-controller", test) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pkg/platform/kind.go: -------------------------------------------------------------------------------- 1 | package platform 2 | 3 | import ( 4 | "github.com/flanksource/karina/pkg/types" 5 | ) 6 | 7 | type KindProvider struct { 8 | } 9 | 10 | func (kind KindProvider) BeforeProvision(platform *Platform, machine *types.VM) error { 11 | return nil 12 | } 13 | 14 | func (kind KindProvider) AfterProvision(platform *Platform, machine types.Machine) error { 15 | return nil 16 | } 17 | 18 | func (kind KindProvider) BeforeTerminate(platform *Platform, machine types.Machine) error { 19 | return nil 20 | } 21 | 22 | func (kind KindProvider) AfterTerminate(platform *Platform, machine types.Machine) error { 23 | return nil 24 | } 25 | 26 | func (kind KindProvider) GetControlPlaneEndpoint(platform *Platform) (string, error) { 27 | return "localhost:8443", nil 28 | } 29 | 30 | func (kind KindProvider) GetExternalEndpoints(platform *Platform) ([]string, error) { 31 | return []string{"localhost"}, nil 32 | } 33 | 34 | func (kind KindProvider) String() string { 35 | return "kind" 36 | } 37 | -------------------------------------------------------------------------------- /pkg/platform/vm.go: -------------------------------------------------------------------------------- 1 | package platform 2 | -------------------------------------------------------------------------------- /pkg/provision/vm.go: -------------------------------------------------------------------------------- 1 | package provision 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/flanksource/karina/pkg/platform" 7 | "github.com/flanksource/karina/pkg/types" 8 | konfigadm "github.com/flanksource/konfigadm/pkg/types" 9 | ) 10 | 11 | // VM provisions a new standalone VM 12 | func VM(platform *platform.Platform, vm *types.VM, konfigs ...string) error { 13 | if err := WithVmwareCluster(platform); err != nil { 14 | return err 15 | } 16 | 17 | konfig, err := konfigadm.NewConfig(konfigs...).Build() 18 | if err != nil { 19 | return fmt.Errorf("vm: failed to get new config: %v", err) 20 | } 21 | platform.Infof("Using konfigadm spec: %s\n", konfigs) 22 | machine, err := platform.Clone(*vm, konfig) 23 | 24 | if err != nil { 25 | return fmt.Errorf("vm: failed to clone %v", err) 26 | } 27 | platform.Infof("Provisioned %s -> %s\n", machine.Name(), machine.IP()) 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /pkg/provision/vmware/list.go: -------------------------------------------------------------------------------- 1 | package vmware 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/vmware/govmomi/object" 8 | 9 | "github.com/flanksource/karina/pkg/types" 10 | ) 11 | 12 | func (s Session) GetVMs(ctx context.Context, prefix string, vm *types.VM) ([]*object.VirtualMachine, error) { 13 | if vm != nil && vm.Prefix != "" { 14 | prefix += "-" + vm.Prefix 15 | } 16 | list, err := s.Finder.VirtualMachineList(ctx, prefix+"*") 17 | if err != nil { 18 | return nil, fmt.Errorf("getCdrom: getVMs to list VMs: %v", err) 19 | } 20 | return list, nil 21 | } 22 | -------------------------------------------------------------------------------- /pkg/types/default.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | func DefaultPlatformConfig() PlatformConfig { 4 | config := PlatformConfig{ 5 | CertManager: CertManager{ 6 | Version: "v1.6.1", 7 | }, 8 | TemplateOperator: TemplateOperator{ 9 | XDisabled: XDisabled{Version: "v0.1.9"}, 10 | }, 11 | Ldap: &Ldap{ 12 | GroupObjectClass: "group", 13 | GroupNameAttr: "name", 14 | }, 15 | Kubernetes: Kubernetes{ 16 | APIServerExtraArgs: map[string]string{}, 17 | ControllerExtraArgs: map[string]string{}, 18 | SchedulerExtraArgs: map[string]string{}, 19 | KubeletExtraArgs: map[string]string{}, 20 | EtcdExtraArgs: map[string]string{}, 21 | ContainerRuntime: "docker", 22 | Managed: false, 23 | }, 24 | Nginx: &Nginx{ 25 | Default: true, 26 | Version: "v1.1.1", 27 | }, 28 | } 29 | return config 30 | } 31 | -------------------------------------------------------------------------------- /pkg/types/inline.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type Boolean bool 4 | 5 | type XEnabled struct { 6 | // +optional 7 | Disabled Boolean `yaml:"disabled" json:"disabled"` 8 | } 9 | 10 | func (d *XEnabled) IsDisabled() bool { 11 | return bool(d.Disabled) 12 | } 13 | 14 | type XDisabled struct { 15 | // +optional 16 | Disabled Boolean `yaml:"disabled" json:"disabled"` 17 | // +optional 18 | Version string `yaml:"version" json:"version"` 19 | } 20 | 21 | func (d XDisabled) IsDisabled() bool { 22 | if d.Disabled { 23 | return true 24 | } 25 | return d.Version == "" 26 | } 27 | -------------------------------------------------------------------------------- /scripts/golint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.24.0 4 | 5 | make 6 | mkdir -p test-results 7 | GOGC=1 golangci-lint run --verbose --print-resources-usage --out-format=junit-xml > test-results/lint.xml 8 | -------------------------------------------------------------------------------- /test/_minio.yaml: -------------------------------------------------------------------------------- 1 | s3: 2 | endpoint: http://minio.minio.svc:9000 3 | access_key: minio 4 | secret_key: minio123 5 | region: us-east1 6 | usePathStyle: true 7 | skipTLSVerify: true 8 | minio: 9 | version: RELEASE.2020-09-02T18-19-50Z 10 | access_key: minio 11 | secret_key: minio123 12 | replicas: 1 13 | -------------------------------------------------------------------------------- /test/_monitoring.yaml: -------------------------------------------------------------------------------- 1 | monitoring: 2 | prometheus: 3 | version: v2.31.1 4 | persistence: 5 | capacity: 10Gi 6 | grafana: 7 | version: 8.5.5 8 | alertmanager: 9 | version: v0.24.0 10 | s3: 11 | endpoint: http://minio.minio.svc:9000 12 | access_key: minio 13 | secret_key: minio123 14 | region: us-east1 15 | usePathStyle: true 16 | skipTLSVerify: true 17 | minio: 18 | version: RELEASE.2020-09-02T18-19-50Z 19 | access_key: minio 20 | secret_key: minio123 21 | replicas: 1 22 | -------------------------------------------------------------------------------- /test/canary-checker.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | canaryChecker: 4 | version: v0.38.154 5 | persistence: 6 | capacity: 1Gi 7 | 8 | -------------------------------------------------------------------------------- /test/cicd.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | templateOperator: 4 | version: v0.1.19 5 | syncPeriod: 15s 6 | mongodbOperator: 7 | version: v1.6.0 8 | configmapReloader: 9 | disabled: true 10 | flux: 11 | enabled: true 12 | test: 13 | exclude: 14 | - dex 15 | - audit 16 | - encryption 17 | - platform-operator 18 | -------------------------------------------------------------------------------- /test/coredns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: coredns 5 | namespace: kube-system 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | k8s-app: kube-dns 11 | template: 12 | spec: 13 | containers: 14 | - name: coredns 15 | resources: 16 | limits: 17 | memory: 170Mi 18 | requests: 19 | cpu: 10m 20 | memory: 70Mi 21 | -------------------------------------------------------------------------------- /test/fixtures/canary-config.yaml: -------------------------------------------------------------------------------- 1 | http: 2 | - endpoints: 3 | - https://httpstat.us/200 4 | thresholdMillis: 3000 5 | responseCodes: [201,200,301] 6 | responseContent: "" 7 | maxSSLExpiry: 7 -------------------------------------------------------------------------------- /test/fixtures/encryption-config.yaml: -------------------------------------------------------------------------------- 1 | # Starting with example config from 2 | # https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#encrypting-your-data 3 | apiVersion: apiserver.config.k8s.io/v1 4 | kind: EncryptionConfiguration 5 | resources: 6 | - resources: 7 | - secrets 8 | providers: 9 | - aescbc: 10 | keys: 11 | # Key secret generated with: 12 | # `head -c 32 /dev/urandom | base64` 13 | - name: demokey 14 | secret: busQyI67d2EnNqIkWhSWJaF2Wz1UnUCu8DNn07nb1fA= 15 | - identity: {} -------------------------------------------------------------------------------- /test/fixtures/konfigadm-template.yaml: -------------------------------------------------------------------------------- 1 | pre_commands: 2 | - "echo 'hello cloud-init'" 3 | containers: 4 | - image: "docker.io/nginxdemos/hello:latest" 5 | docker_args: "-p 9191:80" 6 | post_commands: 7 | - "echo 'goodbye cloud-init'" 8 | -------------------------------------------------------------------------------- /test/fixtures/ldap.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | ldap: 3 | adminGroup: NA1 4 | username: uid=admin,ou=system 5 | password: secret 6 | port: 10636 7 | host: apacheds.ldap 8 | userDN: ou=users,dc=example,dc=com 9 | groupDN: ou=groups,dc=example,dc=com 10 | groupObjectClass: groupOfNames 11 | groupNameAttr: DN -------------------------------------------------------------------------------- /test/fixtures/overwrite.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | domain: 127.0.0.1.nip.io 3 | kubernetes: 4 | version: v1.16.3 5 | calico: 6 | ipip: Never 7 | vxlan: Never 8 | version: v3.8.2 9 | -------------------------------------------------------------------------------- /test/fixtures/simple.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | domain: 127.0.0.1.nip.io 3 | kubernetes: 4 | version: v1.15.7 5 | -------------------------------------------------------------------------------- /test/fixtures/template-test.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: template-test-file 5 | namespace: default 6 | labels: 7 | template: test 8 | data: 9 | configuredValue: "some value" 10 | --- 11 | kind: ConfigMap 12 | apiVersion: v1 13 | metadata: 14 | name: template-test-direct 15 | namespace: default 16 | labels: 17 | template: test 18 | data: 19 | configuredValue: "some value" 20 | -------------------------------------------------------------------------------- /test/fixtures/unrecognized-fields.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | domain: 127.0.0.1.nip.io 3 | kubernetes: 4 | version: v1.15.7 5 | unrecognized: 6 | - 1 7 | -------------------------------------------------------------------------------- /test/gatekeeper.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | gatekeeper: 4 | version: "v3.7.0" 5 | constraints: opa/constraints 6 | auditInterval: 10 7 | e2e: 8 | fixtures: opa/gatekeeper-fixtures 9 | test: 10 | exclude: 11 | - dex 12 | - audit 13 | - encryption 14 | - platform-operator 15 | - gitops 16 | - configmap-reloader 17 | -------------------------------------------------------------------------------- /test/harbor2.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | - _minio.yaml 4 | harbor: 5 | replicas: 1 6 | bucket: karina-harbor-e2e 7 | version: v2.2.1 8 | s3: 9 | access_key: minio 10 | secret_key: minio123 11 | endpoint: http://minio.minio.svc:9000 12 | postgresOperator: 13 | version: v1.7.1 14 | test: 15 | exclude: 16 | - postgres-operator 17 | - platform-operator 18 | - configmap-reloader 19 | - dex 20 | - audit 21 | - encryption 22 | - gitops 23 | -------------------------------------------------------------------------------- /test/hosted-tests.yaml: -------------------------------------------------------------------------------- 1 | patches: 2 | - ./test/patch1.yaml 3 | -------------------------------------------------------------------------------- /test/linter.yaml: -------------------------------------------------------------------------------- 1 | yamlCheck: 2 | ignore: 3 | - .circleci/config.yml 4 | - .github/workflows/(.*) 5 | - .github/(.*) 6 | - .goreleaser.yml 7 | - mkdocs.yml 8 | - docs/mkdocs.yml 9 | - .git/(.*) 10 | - .golangci.yml 11 | - config/deploy/(.*) 12 | -------------------------------------------------------------------------------- /test/managed.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | - _monitoring.yaml 4 | thanos: 5 | version: v0.13.0 6 | mode: client 7 | bucket: thanos 8 | kubernetes: 9 | version: !!env KUBERNETES_VERSION 10 | kubeletExtraArgs: 11 | node-labels: "ingress-ready=true" 12 | authorization-mode: "AlwaysAllow" 13 | containerRuntime: containerd 14 | managed: True 15 | -------------------------------------------------------------------------------- /test/manifests/elastic/eval.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ $(uname -s) == "Darwin" ]]; then 3 | END_TIME=$(date -v +5M +%s) 4 | else 5 | TIMEOUT="10 minute" 6 | END_TIME=$(date -ud "$TIMEOUT" +%s) 7 | fi 8 | 9 | SUCCESS="f" 10 | while [[ $(date -u +%s) -le $END_TIME ]] 11 | do 12 | echo "Waiting for elastic to become available..." 13 | if kubectl -n eck get elasticsearch logs | grep -q Ready; then 14 | SUCCESS="t" 15 | echo "Elastic up successfully" 16 | break 17 | fi 18 | sleep 5 19 | done 20 | if [[ "$SUCCESS" != "t" ]]; then 21 | set -x 22 | echo "==== elasticsearch object ====" 23 | kubectl -n eck get elasticsearch logs 24 | echo "==== elasticsearch object ====" 25 | kubectl -n eck describe elasticsearch logs 26 | echo "==== pods ====" 27 | kubectl -n eck describe pods 28 | echo "==== pod logs ====" 29 | kubectl -n eck logs logs-es-default-0 30 | echo "==== operator logs ====" 31 | kubectl -n elastic-system logs elastic-operator-0 32 | exit 1 33 | fi 34 | exit 0 35 | -------------------------------------------------------------------------------- /test/manifests/elastic/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - elastic.yaml 3 | -------------------------------------------------------------------------------- /test/monitoring.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | - _monitoring.yaml 4 | thanos: 5 | version: v0.29.0 6 | enableCompactor: true 7 | mode: observability 8 | retention: 10d 9 | bucket: thanos 10 | -------------------------------------------------------------------------------- /test/nosql.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | rabbitmqOperator: 4 | version: 0.48.0 5 | redisOperator: 6 | version: v1.0.0 7 | -------------------------------------------------------------------------------- /test/opa/bundles/.manifest: -------------------------------------------------------------------------------- 1 | { 2 | "roots": ["automobile"] 3 | } 4 | 5 | -------------------------------------------------------------------------------- /test/opa/bundles/automobile.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flanksource/karina/e0a79818185cc974e2e22a4493e2649820c2d287/test/opa/bundles/automobile.tar.gz -------------------------------------------------------------------------------- /test/opa/bundles/automobile/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "companies": { 3 | "company-x": [ 4 | "Company-X-Service-One", 5 | "Company-X-Service-Two" 6 | ], 7 | "company-y": [ 8 | "Company-Y-Service-One", 9 | "Company-Y-Service-Two" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/opa/constraints/ban-latest-tag.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sBannedImageTags 3 | metadata: 4 | name: ban-latest-tag 5 | spec: 6 | enforcementAction: dryrun 7 | match: 8 | kinds: 9 | - apiGroups: [""] 10 | kinds: ["Pod"] 11 | - apiGroups: ["*"] 12 | kinds: ["CronJob"] 13 | - apiGroups: ["*"] 14 | kinds: ["Deployment", "ReplicationController", "ReplicaSet", "DaemonSet", "StatefulSet", "Job"] 15 | parameters: 16 | tags: 17 | - "latest" -------------------------------------------------------------------------------- /test/opa/constraints/must-have-probes.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sRequiredProbes 3 | metadata: 4 | name: must-have-probes 5 | spec: 6 | enforcementAction: dryrun 7 | match: 8 | kinds: 9 | - apiGroups: [""] 10 | kinds: ["Pod"] 11 | - apiGroups: ["*"] 12 | kinds: ["CronJob"] 13 | - apiGroups: ["*"] 14 | kinds: ["Deployment", "ReplicationController", "ReplicaSet", "DaemonSet", "StatefulSet", "Job"] 15 | parameters: 16 | probes: ["readinessProbe", "livenessProbe"] 17 | probeTypes: ["tcpSocket", "httpGet", "exec"] -------------------------------------------------------------------------------- /test/opa/constraints/whitelist-registries.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: constraints.gatekeeper.sh/v1beta1 2 | kind: K8sAllowedRepos 3 | metadata: 4 | name: whitelist-registries 5 | spec: 6 | enforcementAction: dryrun 7 | match: 8 | kinds: 9 | - apiGroups: [""] 10 | kinds: ["Pod"] 11 | - apiGroups: ["*"] 12 | kinds: ["CronJob"] 13 | - apiGroups: ["*"] 14 | kinds: ["Deployment", "ReplicationController", "ReplicaSet", "DaemonSet", "StatefulSet", "Job"] 15 | parameters: 16 | repos: 17 | - "k8s.gcr.io" 18 | - "docker.io" 19 | - "quay.io" -------------------------------------------------------------------------------- /test/opa/gatekeeper-fixtures/accepted/deployment-valid.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: goproxy 5 | namespace: opa-test-qa 6 | labels: 7 | app: goproxy 8 | spec: 9 | replicas: 2 10 | selector: 11 | matchLabels: 12 | app: goproxy 13 | template: 14 | metadata: 15 | labels: 16 | app: goproxy 17 | spec: 18 | containers: 19 | - name: goproxy 20 | image: k8s.gcr.io/goproxy:0.1 21 | ports: 22 | - containerPort: 8080 23 | resources: 24 | limits: 25 | memory: "15Mi" 26 | cpu: "15m" 27 | requests: 28 | memory: "10Mi" 29 | cpu: "10m" 30 | readinessProbe: 31 | tcpSocket: 32 | port: 8080 33 | initialDelaySeconds: 5 34 | periodSeconds: 10 35 | livenessProbe: 36 | tcpSocket: 37 | port: 8080 38 | initialDelaySeconds: 15 39 | periodSeconds: 20 40 | -------------------------------------------------------------------------------- /test/opa/gatekeeper-fixtures/accepted/pod-valid.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: goproxy-test 5 | namespace: opa-test-qa 6 | labels: 7 | app: goproxy 8 | spec: 9 | containers: 10 | - name: goproxy-test 11 | image: k8s.gcr.io/goproxy:0.1 12 | ports: 13 | - containerPort: 8080 14 | resources: 15 | limits: 16 | memory: "15Mi" 17 | cpu: "15m" 18 | requests: 19 | memory: "10Mi" 20 | cpu: "10m" 21 | readinessProbe: 22 | tcpSocket: 23 | port: 8080 24 | initialDelaySeconds: 5 25 | periodSeconds: 10 26 | livenessProbe: 27 | tcpSocket: 28 | port: 8080 29 | initialDelaySeconds: 15 30 | periodSeconds: 20 31 | -------------------------------------------------------------------------------- /test/opa/gatekeeper-fixtures/resources/resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | team-name: opa-test 6 | annotations: 7 | ingress-whitelist: "*.acmecorp.com" 8 | registry-whitelist: "nginx,grafana,prom,k8s.gcr.io" 9 | name: opa-test-production 10 | --- 11 | apiVersion: v1 12 | kind: Namespace 13 | metadata: 14 | labels: 15 | team-name: opa-test 16 | annotations: 17 | ingress-whitelist: "*.qa.acmecorp.com,*.internal.acmecorp.com" 18 | registry-whitelist: "nginx,grafana,prom,k8s.gcr.io" 19 | name: opa-test-qa 20 | --- 21 | apiVersion: v1 22 | kind: Namespace 23 | metadata: 24 | labels: 25 | team-name: opa-test 26 | annotations: 27 | ingress-whitelist: "*.acmecorp.com" 28 | registry-whitelist: "nginx,grafana,prom,k8s.gcr.io" 29 | name: opa-test-staging 30 | --- 31 | apiVersion: networking.k8s.io/v1 32 | kind: Ingress 33 | metadata: 34 | name: sample-ingress 35 | namespace: opa-test-production 36 | spec: 37 | rules: 38 | - host: signin.acmecorp.com 39 | http: 40 | paths: 41 | - backend: 42 | service: 43 | name: nginx 44 | port: 45 | number: 80 46 | pathType: ImplementationSpecific 47 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/accepted/deployment-valid.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: goproxy 5 | namespace: opa-test-qa 6 | labels: 7 | app: goproxy 8 | spec: 9 | replicas: 2 10 | selector: 11 | matchLabels: 12 | app: goproxy 13 | template: 14 | metadata: 15 | labels: 16 | app: goproxy 17 | spec: 18 | containers: 19 | - name: goproxy 20 | image: k8s.gcr.io/goproxy:0.1 21 | ports: 22 | - containerPort: 8080 23 | resources: 24 | limits: 25 | memory: "15Mi" 26 | cpu: "15m" 27 | requests: 28 | memory: "10Mi" 29 | cpu: "10m" 30 | readinessProbe: 31 | tcpSocket: 32 | port: 8080 33 | initialDelaySeconds: 5 34 | periodSeconds: 10 35 | livenessProbe: 36 | tcpSocket: 37 | port: 8080 38 | initialDelaySeconds: 15 39 | periodSeconds: 20 40 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/accepted/ingress-whitelisted.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: sample-ingress 5 | namespace: opa-test-production 6 | spec: 7 | rules: 8 | - host: signin.acmecorp.com 9 | http: 10 | paths: 11 | - backend: 12 | service: 13 | name: nginx 14 | port: 15 | number: 80 16 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/accepted/namespace-valid.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: valid-namespace 5 | labels: 6 | company: company-x 7 | service: Company-X-Service-One -------------------------------------------------------------------------------- /test/opa/opa-fixtures/accepted/pod-valid.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: goproxy-test 5 | namespace: opa-test-qa 6 | labels: 7 | app: goproxy 8 | spec: 9 | containers: 10 | - name: goproxy-test 11 | image: k8s.gcr.io/goproxy:0.1 12 | ports: 13 | - containerPort: 8080 14 | resources: 15 | limits: 16 | memory: "15Mi" 17 | cpu: "15m" 18 | requests: 19 | memory: "10Mi" 20 | cpu: "10m" 21 | readinessProbe: 22 | tcpSocket: 23 | port: 8080 24 | initialDelaySeconds: 5 25 | periodSeconds: 10 26 | livenessProbe: 27 | tcpSocket: 28 | port: 8080 29 | initialDelaySeconds: 15 30 | periodSeconds: 20 31 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/deployment-invalid-no-tag.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | namespace: opa-test-qa 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: nginx 10 | replicas: 2 # tells deployment to run 2 pods matching the template 11 | template: 12 | metadata: 13 | labels: 14 | app: nginx 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: nginx 19 | ports: 20 | - containerPort: 80 21 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/deployment-invalid-probes-liveness.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: goproxy 5 | namespace: opa-test-qa 6 | labels: 7 | app: goproxy 8 | spec: 9 | replicas: 2 10 | selector: 11 | matchLabels: 12 | app: goproxy 13 | template: 14 | metadata: 15 | labels: 16 | app: goproxy 17 | spec: 18 | containers: 19 | - name: goproxy 20 | image: k8s.gcr.io/goproxy:0.1 21 | ports: 22 | - containerPort: 8080 23 | livenessProbe: 24 | tcpSocket: 25 | port: 8080 26 | initialDelaySeconds: 15 27 | periodSeconds: 20 28 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/deployment-invalid-probes-readiness.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: goproxy 5 | namespace: opa-test-qa 6 | labels: 7 | app: goproxy 8 | spec: 9 | replicas: 2 10 | selector: 11 | matchLabels: 12 | app: goproxy 13 | template: 14 | metadata: 15 | labels: 16 | app: goproxy 17 | spec: 18 | containers: 19 | - name: goproxy 20 | image: k8s.gcr.io/goproxy:0.1 21 | ports: 22 | - containerPort: 8080 23 | readinessProbe: 24 | tcpSocket: 25 | port: 8080 26 | initialDelaySeconds: 5 27 | periodSeconds: 10 28 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/deployment-invalid-wrong-tag.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | namespace: opa-test-qa 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: nginx 10 | replicas: 2 # tells deployment to run 2 pods matching the template 11 | template: 12 | metadata: 13 | labels: 14 | app: nginx 15 | spec: 16 | containers: 17 | - name: nginx 18 | image: nginx:latest 19 | ports: 20 | - containerPort: 80 21 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/ingress-invalid-conflict.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: sample-ingress 5 | namespace: opa-test-staging 6 | spec: 7 | rules: 8 | - host: signin.acmecorp.com 9 | http: 10 | paths: 11 | - backend: 12 | service: 13 | name: nginx 14 | port: 15 | number: 80 16 | pathType: ImplementationSpecific 17 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/ingress-invalid-not-whitelisted.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: sample-ingress 5 | namespace: opa-test-qa 6 | spec: 7 | rules: 8 | - host: signin.acmecorp.com 9 | http: 10 | paths: 11 | - backend: 12 | service: 13 | name: nginx 14 | port: 15 | number: 80 16 | pathType: ImplementationSpecific 17 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/namespace-invalid-no-company-lables.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: no-company-lables-namespace 5 | annotations: 6 | ingress-whitelist: "*.acmecorp.com" 7 | registry-whitelist: "nginx,grafana,prom" -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/namespace-invalid-wrong-company.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: invalid-namespace-wrong-company 5 | labels: 6 | company: company-z 7 | service: Company-Z-Service-One 8 | 9 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/namespace-invalid-wrong-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: invalid-namespace-wrong-service 5 | labels: 6 | company: company-x 7 | service: Company-Y-Service-One 8 | 9 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/pod-invalid-no-tag.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 # for versions before 1.9.0 use apps/v1beta2 2 | kind: Pod 3 | metadata: 4 | name: nginx-deployment 5 | namespace: opa-test-qa 6 | spec: 7 | containers: 8 | - name: nginx 9 | image: nginx 10 | ports: 11 | - containerPort: 80 12 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/pod-invalid-probes.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: goproxy 5 | namespace: opa-test-qa 6 | labels: 7 | app: goproxy 8 | spec: 9 | containers: 10 | - name: goproxy 11 | image: k8s.gcr.io/goproxy:0.1 12 | ports: 13 | - containerPort: 8080 14 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/pod-invalid-registry.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: memory-demo 5 | namespace: opa-test-qa 6 | spec: 7 | containers: 8 | - name: memory-demo-ctr 9 | image: polinux/stress 10 | resources: 11 | limits: 12 | memory: "200Mi" 13 | requests: 14 | memory: "100Mi" 15 | command: ["stress"] 16 | args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"] -------------------------------------------------------------------------------- /test/opa/opa-fixtures/rejected/pod-invalid-wrong-tag.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 # for versions before 1.9.0 use apps/v1beta2 2 | kind: Pod 3 | metadata: 4 | name: nginx-deployment 5 | namespace: opa-test-qa 6 | spec: 7 | containers: 8 | - name: nginx 9 | image: nginx:latest 10 | ports: 11 | - containerPort: 80 12 | -------------------------------------------------------------------------------- /test/opa/opa-fixtures/resources/resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | team-name: opa-test 6 | annotations: 7 | ingress-whitelist: "*.acmecorp.com" 8 | registry-whitelist: "nginx,grafana,prom,k8s.gcr.io" 9 | name: opa-test-production 10 | --- 11 | apiVersion: v1 12 | kind: Namespace 13 | metadata: 14 | labels: 15 | team-name: opa-test 16 | annotations: 17 | ingress-whitelist: "*.qa.acmecorp.com,*.internal.acmecorp.com" 18 | registry-whitelist: "nginx,grafana,prom,k8s.gcr.io" 19 | name: opa-test-qa 20 | --- 21 | apiVersion: v1 22 | kind: Namespace 23 | metadata: 24 | labels: 25 | team-name: opa-test 26 | annotations: 27 | ingress-whitelist: "*.acmecorp.com" 28 | registry-whitelist: "nginx,grafana,prom,k8s.gcr.io" 29 | name: opa-test-staging 30 | --- 31 | apiVersion: networking.k8s.io/v1 32 | kind: Ingress 33 | metadata: 34 | name: sample-ingress 35 | namespace: opa-test-production 36 | spec: 37 | rules: 38 | - host: signin.acmecorp.com 39 | http: 40 | paths: 41 | - backend: 42 | service: 43 | name: nginx 44 | port: 45 | number: 80 46 | pathType: ImplementationSpecific 47 | -------------------------------------------------------------------------------- /test/opa/policies/check-ingress-conflict.rego: -------------------------------------------------------------------------------- 1 | package kubernetes.admission 2 | 3 | import data.kubernetes.ingresses 4 | 5 | deny[msg] { 6 | some other_ns, other_ingress 7 | input.request.kind.kind == "Ingress" 8 | input.request.operation == "CREATE" 9 | host := input.request.object.spec.rules[_].host 10 | ingress := ingresses[other_ns][other_ingress] 11 | other_ns != input.request.namespace 12 | ingress.spec.rules[_].host == host 13 | msg = sprintf("invalid ingress host %q (conflicts with %v/%v)", [host, other_ns, other_ingress]) 14 | } 15 | -------------------------------------------------------------------------------- /test/opa/policies/check-ingress-whitelist.rego: -------------------------------------------------------------------------------- 1 | package kubernetes.admission 2 | 3 | import data.kubernetes.namespaces 4 | 5 | operations = {"CREATE", "UPDATE"} 6 | 7 | deny[msg] { 8 | input.request.kind.kind == "Ingress" 9 | operations[input.request.operation] 10 | host := input.request.object.spec.rules[_].host 11 | not fqdn_matches_any(host, valid_ingress_hosts) 12 | msg := sprintf("invalid ingress host %q", [host]) 13 | } 14 | 15 | valid_ingress_hosts = {host | 16 | whitelist := namespaces[input.request.namespace].metadata.annotations["ingress-whitelist"] 17 | hosts := split(whitelist, ",") 18 | host := hosts[_] 19 | } 20 | 21 | fqdn_matches_any(str, patterns) { 22 | fqdn_matches(str, patterns[_]) 23 | } 24 | 25 | fqdn_matches(str, pattern) { 26 | pattern_parts := split(pattern, ".") 27 | pattern_parts[0] == "*" 28 | str_parts := split(str, ".") 29 | n_pattern_parts := count(pattern_parts) 30 | n_str_parts := count(str_parts) 31 | suffix := trim(pattern, "*.") 32 | endswith(str, suffix) 33 | } 34 | 35 | fqdn_matches(str, pattern) { 36 | not contains(pattern, "*") 37 | str == pattern 38 | } 39 | -------------------------------------------------------------------------------- /test/opa/policies/check-liveness.rego: -------------------------------------------------------------------------------- 1 | package kubernetes.admission 2 | 3 | import data.kubernetes.namespaces 4 | 5 | probes_operations = {"CREATE", "UPDATE"} 6 | probes_kinds = {"Deployment", "ReplicationController", "ReplicaSet", "DaemonSet", "StatefulSet"} 7 | 8 | has_key(x, k) { _ = x[k] } 9 | get_container(kind) = input.request.object.spec.template.spec.containers[_] { probes_kinds[kind] } 10 | get_container(kind) = input.request.object.spec.containers[_] { kind == "Pod" } 11 | 12 | deny[msg1] { 13 | probes_operations[input.request.operation] 14 | container = get_container(input.request.kind.kind) 15 | not has_key(container,"livenessProbe") 16 | msg1 = "liveness probe is not set" 17 | } 18 | -------------------------------------------------------------------------------- /test/opa/policies/check-readiness.rego: -------------------------------------------------------------------------------- 1 | package kubernetes.admission 2 | 3 | import data.kubernetes.namespaces 4 | 5 | probes_operations = {"CREATE", "UPDATE"} 6 | probes_kinds = {"Deployment", "ReplicationController", "ReplicaSet", "DaemonSet", "StatefulSet"} 7 | 8 | has_key(x, k) { _ = x[k] } 9 | get_container(kind) = input.request.object.spec.template.spec.containers[_] { probes_kinds[kind] } 10 | get_container(kind) = input.request.object.spec.containers[_] { kind == "Pod" } 11 | 12 | deny[msg2] { 13 | probes_operations[input.request.operation] 14 | container = get_container(input.request.kind.kind) 15 | not has_key(container,"readinessProbe") 16 | msg2 := "readiness probe is not set" 17 | } 18 | 19 | # deny[msg2] { 20 | # probes_operations[input.request.operation] 21 | # container = get_container(input.request.kind.kind) 22 | # not has_key(container,"livenessProbe") 23 | # msg2 := "liveness probe is not set" 24 | # } 25 | -------------------------------------------------------------------------------- /test/platform.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | - _minio.yaml 4 | velero: 5 | bucket: karina-velero 6 | configmapReloader: 7 | version: "v0.0.56" 8 | sealedSecrets: 9 | version: "v0.10.0" 10 | certificate: 11 | cert: ../.certs/sealed-secrets-crt.pem 12 | privateKey: ../.certs/sealed-secrets-key.pem 13 | password: foobar 14 | registryCredentials: 15 | disabled: true # quarantine registry creds 16 | version: "v1.10.flanksource.2" 17 | namespace: "registry-credentials" 18 | aws: 19 | enabled: true 20 | accessKey: !!env AWS_ACCESS_KEY_ID 21 | secretKey: !!env AWS_SECRET_ACCESS_KEY 22 | account: 745897381572 23 | region: us-east-1 24 | platformOperator: 25 | version: v0.7.0 26 | enableClusterResourceQuota: true 27 | whitelistedPodAnnotations: 28 | # used by filebeat 29 | - com.flanksource.infra.logs/enabled 30 | - co.elastic.logs/enabled 31 | # used in e2e tests 32 | - foo.flanksource.com/bar 33 | - foo.flanksource.com/baz 34 | test: 35 | exclude: 36 | - dex 37 | - audit 38 | - encryption 39 | - monitoring 40 | istioOperator: 41 | disabled: False 42 | version: 1.8.2 43 | -------------------------------------------------------------------------------- /test/postgres.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | - _minio.yaml 4 | templateOperator: 5 | version: v0.7.0 6 | syncPeriod: 15s 7 | postgresOperator: 8 | version: v1.7.1 9 | defaultBackupBucket: cicd-pg-backup 10 | backupPassword: password123456 11 | defaultBackupRetention: 12 | keepLast: 5 13 | keepHourly: 2 14 | keepDaily: 1 15 | -------------------------------------------------------------------------------- /test/quarantine.yaml: -------------------------------------------------------------------------------- 1 | importConfigs: 2 | - minimal.yaml 3 | argocdOperator: 4 | version: v0.0.15 5 | argoRollouts: 6 | version: v0.10.2 7 | test: 8 | exclude: 9 | - dex 10 | - audit 11 | - encryption 12 | - platform-operator 13 | -------------------------------------------------------------------------------- /test/secure.yaml: -------------------------------------------------------------------------------- 1 | # in order to connect to cluster after provisioning 2 | # the kubeconfig cluster name needs to match this name 3 | name: !!template kind-{{ getenv "SUITE" }}-{{ getenv "KUBERNETES_VERSION" }} 4 | domain: 127.0.0.1.nip.io 5 | dex: 6 | disabled: true 7 | ldap: 8 | disabled: true 9 | kubernetes: 10 | version: !!env KUBERNETES_VERSION 11 | kubeletExtraArgs: 12 | node-labels: "ingress-ready=true" 13 | authorization-mode: "AlwaysAllow" 14 | containerRuntime: containerd 15 | versions: 16 | sonobuoy: 0.16.4 17 | ketall: v1.3.0 18 | apacheds: 0.7.0 19 | kind: 0.9.0 20 | templateOperator: 21 | version: v0.1.11 22 | podSubnet: 10.200.0.0/16 23 | serviceSubnet: 10.201.0.0/16 24 | platformOperator: 25 | version: v0.6.14 26 | calico: 27 | version: v3.8.2 28 | configFrom: 29 | - sops: encrypted.yaml.enc 30 | importConfigs: 31 | - _minio.yaml 32 | test: 33 | exclude: 34 | - configmap-reloader 35 | - dex 36 | - audit 37 | - encryption 38 | - platform-operator 39 | -------------------------------------------------------------------------------- /test/templatePatch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This ConfigMap is used to verify template 3 | # value injection 4 | kind: ConfigMap 5 | apiVersion: v1 6 | metadata: 7 | name: template-test-file 8 | namespace: default 9 | labels: 10 | template: test 11 | data: 12 | configuredValue: !!env CONFIGURED_VALUE --------------------------------------------------------------------------------