diff --git a/chart/kubeapps/.gitignore b/chart/kubeapps/.gitignore new file mode 100644 index 00000000000..948259a7b67 --- /dev/null +++ b/chart/kubeapps/.gitignore @@ -0,0 +1 @@ +charts/*.tgz diff --git a/chart/kubeapps/.helmignore b/chart/kubeapps/.helmignore new file mode 100644 index 00000000000..f0c13194444 --- /dev/null +++ b/chart/kubeapps/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/chart/kubeapps/Chart.yaml b/chart/kubeapps/Chart.yaml new file mode 100644 index 00000000000..63eb0ad17bb --- /dev/null +++ b/chart/kubeapps/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +name: kubeapps +version: 0.1.0 +appVersion: 1.0.0.alpha.4 +description: Kubeapps is a dashboard for your Kubernetes cluster that makes it easy to deploy and manage applications in your cluster using Helm +icon: https://raw.githubusercontent.com/kubeapps/kubeapps/master/docs/img/logo.png +keywords: +- helm +- dashboard +- service catalog +- deployment +home: https://kubeapps.com +sources: +- https://github.com/kubeapps/kubeapps +maintainers: +- name: bitnami-bot + email: containers@bitnami.com +- name: prydonius + email: adnan@bitnami.com diff --git a/chart/kubeapps/requirements.lock b/chart/kubeapps/requirements.lock new file mode 100644 index 00000000000..4ff3be9bb88 --- /dev/null +++ b/chart/kubeapps/requirements.lock @@ -0,0 +1,6 @@ +dependencies: +- name: mongodb + repository: https://kubernetes-charts.storage.googleapis.com + version: 4.0.4 +digest: sha256:415440e73af7d4b02a10a15f28bb2fc095cbdffdc2e1676d76e0f0eaa1632d50 +generated: 2018-08-01T11:50:24.777058724-07:00 diff --git a/chart/kubeapps/requirements.yaml b/chart/kubeapps/requirements.yaml new file mode 100644 index 00000000000..50a0b6ee7a4 --- /dev/null +++ b/chart/kubeapps/requirements.yaml @@ -0,0 +1,4 @@ +dependencies: +- name: mongodb + version: ">= 0" + repository: https://kubernetes-charts.storage.googleapis.com diff --git a/chart/kubeapps/templates/NOTES.txt b/chart/kubeapps/templates/NOTES.txt new file mode 100644 index 00000000000..62b10e50e08 --- /dev/null +++ b/chart/kubeapps/templates/NOTES.txt @@ -0,0 +1,19 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + echo http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} +{{- end }} +{{- else if contains "NodePort" .Values.frontend.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "kubeapps.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.frontend.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status by running 'kubectl get svc -w {{ template "kubeapps.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "kubeapps.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.frontend.service.port }} +{{- else if contains "ClusterIP" .Values.frontend.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "kubeapps.fullname" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME 8080:8080 +{{- end }} diff --git a/chart/kubeapps/templates/_helpers.tpl b/chart/kubeapps/templates/_helpers.tpl new file mode 100644 index 00000000000..b10cefaab9f --- /dev/null +++ b/chart/kubeapps/templates/_helpers.tpl @@ -0,0 +1,97 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kubeapps.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kubeapps.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Render image reference +*/}} +{{- define "kubeapps.image" -}} +{{ .registry }}/{{ .repository }}:{{ .tag }} +{{- end -}} + +{{/* +Create a default fully qualified app name for MongoDB dependency. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "kubeapps.mongodb.fullname" -}} +{{- $name := default "mongodb" .Values.mongodb.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kubeapps.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create name for the apprepository-controller based on the fullname +*/}} +{{- define "kubeapps.apprepository.fullname" -}} +{{ template "kubeapps.fullname" . }}-apprepository-controller +{{- end -}} + +{{/* +Create name for the apprepository bootstrap job +*/}} +{{- define "kubeapps.apprepository-jobs-bootstrap.fullname" -}} +{{ template "kubeapps.fullname" . }}-apprepository-jobs-bootstrap +{{- end -}} + +{{/* +Create name for the chartsvc based on the fullname +*/}} +{{- define "kubeapps.chartsvc.fullname" -}} +{{ template "kubeapps.fullname" . }}-chartsvc +{{- end -}} + +{{/* +Create name for the dashboard based on the fullname +*/}} +{{- define "kubeapps.dashboard.fullname" -}} +{{ template "kubeapps.fullname" . }}-dashboard +{{- end -}} + +{{/* +Create name for the dashboard config based on the fullname +*/}} +{{- define "kubeapps.dashboard-config.fullname" -}} +{{ template "kubeapps.fullname" . }}-dashboard-config +{{- end -}} + +{{/* +Create name for the frontend config based on the fullname +*/}} +{{- define "kubeapps.frontend-config.fullname" -}} +{{ template "kubeapps.fullname" . }}-frontend-config +{{- end -}} + +{{/* +Create name for the tiller-proxy based on the fullname +*/}} +{{- define "kubeapps.tiller-proxy.fullname" -}} +{{ template "kubeapps.fullname" . }}-tiller-proxy +{{- end -}} diff --git a/chart/kubeapps/templates/apprepository-crd.yaml b/chart/kubeapps/templates/apprepository-crd.yaml new file mode 100644 index 00000000000..84c8ea050d5 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-crd.yaml @@ -0,0 +1,17 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: apprepositories.kubeapps.com + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + group: kubeapps.com + names: + kind: AppRepository + plural: apprepositories + shortNames: + - apprepos + version: v1alpha1 diff --git a/chart/kubeapps/templates/apprepository-deployment.yaml b/chart/kubeapps/templates/apprepository-deployment.yaml new file mode 100644 index 00000000000..c1f058ae6b0 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-deployment.yaml @@ -0,0 +1,47 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "kubeapps.apprepository.fullname" . }} + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "kubeapps.apprepository.fullname" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + release: {{ .Release.Name }} + spec: + serviceAccountName: {{ template "kubeapps.apprepository.fullname" . }} + containers: + - name: controller + image: {{ template "kubeapps.image" .Values.apprepository.image }} + command: + - /apprepository-controller + args: + - --logtostderr + - --repo-sync-image={{ template "kubeapps.image" .Values.apprepository.syncImage }} + - --namespace={{ .Release.Namespace }} + - --mongo-url={{ template "kubeapps.mongodb.fullname" . }} + - --mongo-secret-name={{ template "kubeapps.mongodb.fullname" . }} + resources: +{{ toYaml .Values.apprepository.resources | indent 12 }} + {{- with .Values.apprepository.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.apprepository.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.apprepository.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/chart/kubeapps/templates/apprepository-jobs-bootstrap-config.yaml b/chart/kubeapps/templates/apprepository-jobs-bootstrap-config.yaml new file mode 100644 index 00000000000..400eabe5884 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-jobs-bootstrap-config.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + annotations: + helm.sh/hook: post-install + helm.sh/hook-delete-policy: hook-succeeded + helm.sh/hook-weight: "-10" + labels: + app: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + apprepositories.yaml: |- + {{- range .Values.apprepository.initialRepos }} + apiVersion: kubeapps.com/v1alpha1 + kind: AppRepository + metadata: + name: {{ .name }} + labels: + app: {{ template "kubeapps.apprepository.fullname" $ }} + chart: {{ template "kubeapps.chart" $ }} + release: {{ $.Release.Name }} + heritage: {{ $.Release.Service }} + spec: + type: helm + url: {{ .url }} + --- + {{ end -}} diff --git a/chart/kubeapps/templates/apprepository-jobs-bootstrap-rbac.yaml b/chart/kubeapps/templates/apprepository-jobs-bootstrap-rbac.yaml new file mode 100644 index 00000000000..3a80c058f22 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-jobs-bootstrap-rbac.yaml @@ -0,0 +1,44 @@ +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + annotations: + helm.sh/hook: post-install + helm.sh/hook-delete-policy: hook-succeeded + helm.sh/hook-weight: "-10" + labels: + app: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: +- apiGroups: + - kubeapps.com + resources: + - apprepositories + verbs: + - get + - create + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + annotations: + helm.sh/hook: post-install + helm.sh/hook-delete-policy: hook-succeeded + helm.sh/hook-weight: "-10" + labels: + app: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + namespace: {{ .Release.Namespace }} diff --git a/chart/kubeapps/templates/apprepository-jobs-bootstrap-serviceaccount.yaml b/chart/kubeapps/templates/apprepository-jobs-bootstrap-serviceaccount.yaml new file mode 100644 index 00000000000..fb5527f5888 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-jobs-bootstrap-serviceaccount.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + annotations: + helm.sh/hook: post-install + helm.sh/hook-delete-policy: hook-succeeded + helm.sh/hook-weight: "-10" + labels: + app: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} diff --git a/chart/kubeapps/templates/apprepository-jobs-bootstrap.yaml b/chart/kubeapps/templates/apprepository-jobs-bootstrap.yaml new file mode 100644 index 00000000000..05b3d557e58 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-jobs-bootstrap.yaml @@ -0,0 +1,50 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + annotations: + helm.sh/hook: post-install + helm.sh/hook-delete-policy: hook-succeeded + labels: + app: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + template: + metadata: + labels: + app: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + release: {{ .Release.Name }} + spec: + containers: + - name: kubectl + image: {{ template "kubeapps.image" .Values.apprepository.jobsImage }} + command: + - kubectl + - apply + - -f + - /tmp/apprepositories/apprepositories.yaml + volumeMounts: + - mountPath: /tmp/apprepositories + name: apprepositories-config + resources: +{{ toYaml .Values.apprepository.resources | indent 12 }} + volumes: + - name: apprepositories-config + configMap: + name: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + restartPolicy: OnFailure + serviceAccountName: {{ template "kubeapps.apprepository-jobs-bootstrap.fullname" . }} + {{- with .Values.apprepository.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.apprepository.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.apprepository.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/chart/kubeapps/templates/apprepository-rbac.yaml b/chart/kubeapps/templates/apprepository-rbac.yaml new file mode 100644 index 00000000000..e670fa096a6 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-rbac.yaml @@ -0,0 +1,99 @@ +# Need a cluster role because client-go v5.0.1 does not support namespaced +# informers +# TODO: remove when we update to client-go v6.0.0 +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "kubeapps.apprepository.fullname" . }} + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: +- apiGroups: + - batch + resources: + - cronjobs + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kubeapps.apprepository.fullname" . }} + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kubeapps.apprepository.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "kubeapps.apprepository.fullname" . }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ template "kubeapps.apprepository.fullname" . }} + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create +- apiGroups: + - batch + resources: + - cronjobs + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create +- apiGroups: + - kubeapps.com + resources: + - apprepositories + verbs: + - get + - list + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ template "kubeapps.apprepository.fullname" . }} + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "kubeapps.apprepository.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "kubeapps.apprepository.fullname" . }} + namespace: {{ .Release.Namespace }} diff --git a/chart/kubeapps/templates/apprepository-serviceaccount.yaml b/chart/kubeapps/templates/apprepository-serviceaccount.yaml new file mode 100644 index 00000000000..7fc1f5a8ae3 --- /dev/null +++ b/chart/kubeapps/templates/apprepository-serviceaccount.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kubeapps.apprepository.fullname" . }} + labels: + app: {{ template "kubeapps.apprepository.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} diff --git a/chart/kubeapps/templates/chartsvc-deployment.yaml b/chart/kubeapps/templates/chartsvc-deployment.yaml new file mode 100644 index 00000000000..692f95ca1db --- /dev/null +++ b/chart/kubeapps/templates/chartsvc-deployment.yaml @@ -0,0 +1,52 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "kubeapps.chartsvc.fullname" . }} + labels: + app: {{ template "kubeapps.chartsvc.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "kubeapps.chartsvc.fullname" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "kubeapps.chartsvc.fullname" . }} + release: {{ .Release.Name }} + spec: + containers: + - name: chartsvc + image: {{ template "kubeapps.image" .Values.chartsvc.image }} + command: + - /chartsvc + args: + - --mongo-user=root + - --mongo-url={{ template "kubeapps.mongodb.fullname" . }} + env: + - name: MONGO_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "kubeapps.mongodb.fullname" . }} + key: mongodb-root-password + ports: + - name: http + containerPort: {{ .Values.chartsvc.service.port }} + resources: +{{ toYaml .Values.chartsvc.resources | indent 12 }} + {{- with .Values.chartsvc.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.chartsvc.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.chartsvc.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/chart/kubeapps/templates/chartsvc-service.yaml b/chart/kubeapps/templates/chartsvc-service.yaml new file mode 100644 index 00000000000..8ddc3116b0c --- /dev/null +++ b/chart/kubeapps/templates/chartsvc-service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kubeapps.chartsvc.fullname" . }} + labels: + app: {{ template "kubeapps.name" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.chartsvc.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app: {{ template "kubeapps.chartsvc.fullname" . }} + release: {{ .Release.Name }} diff --git a/chart/kubeapps/templates/dashboard-config.yaml b/chart/kubeapps/templates/dashboard-config.yaml new file mode 100644 index 00000000000..109ca84be9a --- /dev/null +++ b/chart/kubeapps/templates/dashboard-config.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kubeapps.dashboard-config.fullname" . }} + labels: + app: {{ template "kubeapps.dashboard-config.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + vhost.conf: |- + server { + listen 8080; + server_name _; + + gzip on; + gzip_static on; + + location / { + try_files $uri /index.html; + } + } + config.json: |- + { + "namespace": "{{ .Release.Namespace }}" + } diff --git a/chart/kubeapps/templates/dashboard-deployment.yaml b/chart/kubeapps/templates/dashboard-deployment.yaml new file mode 100644 index 00000000000..bf78a9d6a3a --- /dev/null +++ b/chart/kubeapps/templates/dashboard-deployment.yaml @@ -0,0 +1,66 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "kubeapps.dashboard.fullname" . }} + labels: + app: {{ template "kubeapps.dashboard.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "kubeapps.dashboard.fullname" . }} + release: {{ .Release.Name }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/dashboard-config.yaml") . | sha256sum }} + labels: + app: {{ template "kubeapps.dashboard.fullname" . }} + release: {{ .Release.Name }} + spec: + containers: + - name: dashboard + image: {{ template "kubeapps.image" .Values.dashboard.image }} + livenessProbe: +{{ toYaml .Values.dashboard.livenessProbe | indent 10 }} + readinessProbe: +{{ toYaml .Values.dashboard.readinessProbe | indent 10 }} + volumeMounts: + - name: vhost + mountPath: /bitnami/nginx/conf/vhosts + - name: config + mountPath: /app/config.json + subPath: config.json + ports: + - name: http + containerPort: 8080 + resources: +{{ toYaml .Values.dashboard.resources | indent 12 }} + volumes: + - name: vhost + configMap: + name: {{ template "kubeapps.dashboard-config.fullname" . }} + items: + - key: vhost.conf + path: vhost.conf + - name: config + configMap: + name: {{ template "kubeapps.dashboard-config.fullname" . }} + items: + - key: config.json + path: config.json + {{- with .Values.dashboard.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.dashboard.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.dashboard.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/chart/kubeapps/templates/dashboard-service.yaml b/chart/kubeapps/templates/dashboard-service.yaml new file mode 100644 index 00000000000..9215cab3b4a --- /dev/null +++ b/chart/kubeapps/templates/dashboard-service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kubeapps.dashboard.fullname" . }} + labels: + app: {{ template "kubeapps.name" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.dashboard.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app: {{ template "kubeapps.dashboard.fullname" . }} + release: {{ .Release.Name }} diff --git a/chart/kubeapps/templates/ingress.yaml b/chart/kubeapps/templates/ingress.yaml new file mode 100644 index 00000000000..b78a7ad5849 --- /dev/null +++ b/chart/kubeapps/templates/ingress.yaml @@ -0,0 +1,38 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "kubeapps.fullname" . -}} +{{- $ingressPath := .Values.ingress.path -}} +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ include "kubeapps.name" . }} + chart: {{ include "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ . | quote }} + http: + paths: + - path: {{ $ingressPath }} + backend: + serviceName: {{ $fullName }} + servicePort: http + {{- end }} +{{- end }} diff --git a/chart/kubeapps/templates/kubeapps-frontend-config.yaml b/chart/kubeapps/templates/kubeapps-frontend-config.yaml new file mode 100644 index 00000000000..1ddbadfd915 --- /dev/null +++ b/chart/kubeapps/templates/kubeapps-frontend-config.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kubeapps.frontend-config.fullname" . }} + labels: + app: {{ template "kubeapps.frontend-config.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + vhost.conf: |- + # Retain the default nginx handling of requests without a "Connection" header + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + # Allow websocket connections + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + server { + listen 8080; + server_name _; + + location /healthz { + access_log off; + default_type text/plain; + return 200 "healthy\n"; + } + + location /api/kube { + rewrite /api/kube/(.*) /$1 break; + rewrite /api/kube / break; + proxy_pass https://kubernetes.default; + # Disable buffering for log streaming + proxy_buffering off; + # Hide Www-Authenticate to prevent it triggering a basic auth prompt in + # the browser with some clusters + proxy_hide_header Www-Authenticate; + } + + location /api/chartsvc { + rewrite /api/chartsvc/(.*) /$1 break; + rewrite /api/chartsvc / break; + proxy_pass http://{{ template "kubeapps.chartsvc.fullname" . }}:{{ .Values.chartsvc.service.port }}; + } + + location /api/tiller-deploy { + rewrite /api/tiller-deploy/(.*) /$1 break; + rewrite /api/tiller-deploy / break; + proxy_pass http://{{ template "kubeapps.tiller-proxy.fullname" . }}:{{ .Values.tillerProxy.service.port }}; + } + + location / { + proxy_pass http://{{ template "kubeapps.dashboard.fullname" . }}:{{ .Values.dashboard.service.port }}; + } + } diff --git a/chart/kubeapps/templates/kubeapps-frontend-deployment.yaml b/chart/kubeapps/templates/kubeapps-frontend-deployment.yaml new file mode 100644 index 00000000000..8d7bcaf47c1 --- /dev/null +++ b/chart/kubeapps/templates/kubeapps-frontend-deployment.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "kubeapps.fullname" . }} + labels: + app: {{ template "kubeapps.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "kubeapps.fullname" . }} + release: {{ .Release.Name }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/kubeapps-frontend-config.yaml") . | sha256sum }} + labels: + app: {{ template "kubeapps.fullname" . }} + release: {{ .Release.Name }} + spec: + containers: + - name: nginx + image: {{ template "kubeapps.image" .Values.frontend.image }} + livenessProbe: +{{ toYaml .Values.frontend.livenessProbe | indent 10 }} + readinessProbe: +{{ toYaml .Values.frontend.readinessProbe | indent 10 }} + volumeMounts: + - name: vhost + mountPath: /bitnami/nginx/conf/vhosts + ports: + - name: http + containerPort: 8080 + resources: +{{ toYaml .Values.frontend.resources | indent 12 }} + volumes: + - name: vhost + configMap: + name: {{ template "kubeapps.frontend-config.fullname" . }} + {{- with .Values.frontend.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.frontend.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.frontend.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/chart/kubeapps/templates/kubeapps-frontend-service.yaml b/chart/kubeapps/templates/kubeapps-frontend-service.yaml new file mode 100644 index 00000000000..2e02056129e --- /dev/null +++ b/chart/kubeapps/templates/kubeapps-frontend-service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kubeapps.fullname" . }} + labels: + app: {{ template "kubeapps.name" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: {{ .Values.frontend.service.type }} + ports: + - port: {{ .Values.frontend.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app: {{ template "kubeapps.fullname" . }} + release: {{ .Release.Name }} diff --git a/chart/kubeapps/templates/tiller-proxy-deployment.yaml b/chart/kubeapps/templates/tiller-proxy-deployment.yaml new file mode 100644 index 00000000000..dbfc199ce6b --- /dev/null +++ b/chart/kubeapps/templates/tiller-proxy-deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "kubeapps.tiller-proxy.fullname" . }} + labels: + app: {{ template "kubeapps.tiller-proxy.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "kubeapps.tiller-proxy.fullname" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "kubeapps.tiller-proxy.fullname" . }} + release: {{ .Release.Name }} + spec: + containers: + - name: proxy + image: {{ template "kubeapps.image" .Values.tillerProxy.image }} + command: + - /proxy + args: + - --host={{ .Values.tillerProxy.host }} + {{- if .Values.tillerProxy.tls }} + - --tls + {{- if .Values.tillerProxy.tls.verify }} + - --tls-verify + {{- end }} + env: + - name: HELM_HOME + value: /etc/certs + volumeMounts: + - name: tiller-certs + mountPath: /etc/certs + {{- end }} + ports: + - name: http + containerPort: {{ .Values.chartsvc.service.port }} + resources: +{{ toYaml .Values.tillerProxy.resources | indent 12 }} + {{- if .Values.tillerProxy.tls }} + volumes: + - name: tiller-certs + secret: + secretName: {{ template "kubeapps.tiller-proxy.fullname" . }} + {{- end }} + {{- with .Values.tillerProxy.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tillerProxy.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tillerProxy.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/chart/kubeapps/templates/tiller-proxy-secret.yaml b/chart/kubeapps/templates/tiller-proxy-secret.yaml new file mode 100644 index 00000000000..f8d1c0e2949 --- /dev/null +++ b/chart/kubeapps/templates/tiller-proxy-secret.yaml @@ -0,0 +1,18 @@ +{{- if .Values.tillerProxy.tls -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kubeapps.tiller-proxy.fullname" . }} + labels: + app: {{ template "kubeapps.tiller-proxy.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + ca.crt: |- +{{ .Values.tillerProxy.tls.ca | b64enc | indent 4 }} + tls.crt: |- +{{ .Values.tillerProxy.tls.cert | b64enc | indent 4 }} + tls.key: |- +{{ .Values.tillerProxy.tls.key | b64enc | indent 4 }} +{{- end -}} diff --git a/chart/kubeapps/templates/tiller-proxy-service.yaml b/chart/kubeapps/templates/tiller-proxy-service.yaml new file mode 100644 index 00000000000..76a95aa5226 --- /dev/null +++ b/chart/kubeapps/templates/tiller-proxy-service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kubeapps.tiller-proxy.fullname" . }} + labels: + app: {{ template "kubeapps.name" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.tillerProxy.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app: {{ template "kubeapps.tiller-proxy.fullname" . }} + release: {{ .Release.Name }} diff --git a/chart/kubeapps/templates/user-rbac.yaml b/chart/kubeapps/templates/user-rbac.yaml new file mode 100644 index 00000000000..6255b68a124 --- /dev/null +++ b/chart/kubeapps/templates/user-rbac.yaml @@ -0,0 +1,152 @@ +# Preset Roles and ClusterRoles that can be bound to users for use with Kubeapps +# See https://github.com/kubeapps/kubeapps/blob/master/docs/user/access-control.md + +{{- define "kubeapps.user-rbac.labels" -}} + labels: + app: {{ template "kubeapps.fullname" . }} + chart: {{ template "kubeapps.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- end }} + +# kubeapps-applications-read +# Gives read-only access to all the elements within a Namespace. +# Usage: +# Apply kubeapps-applications-read clusterrole to user/serviceaccount in the desired namespace +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: kubeapps-applications-read +{{ template "kubeapps.user-rbac.labels" . }} +rules: +- apiGroups: + - "*" + resources: + - "*" + verbs: + - list + - get + - watch +--- +# kubeapps-service-catalog-read +# Gives read-only access to Service Instances and Bindings within a Namespace in Kubeapps. +# Usage: +# Apply kubeapps-service-catalog-read clusterrole to user/serviceaccount in the desired namespace +# AND apply kubeapps-service-catalog-browse to user/serviceaccount in all namespaces. +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: kubeapps-service-catalog-browse +{{ template "kubeapps.user-rbac.labels" . }} +rules: +- apiGroups: + - servicecatalog.k8s.io + resources: + - clusterservicebrokers + - clusterserviceclasses + - clusterserviceplans + verbs: + - list +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: kubeapps-service-catalog-read +{{ template "kubeapps.user-rbac.labels" . }} +rules: +- apiGroups: + - servicecatalog.k8s.io + resources: + - serviceinstances + - servicebindings + verbs: + - list + - get + # Allows viewing Service Binding credentials. +- apiGroups: + - "" + resources: + - secrets + verbs: + - get +--- +# kubeapps-service-catalog-write +# Gives write access to Service Instances and Bindings within a Namespace in Kubeapps. +# Usage: +# Apply kubeapps-service-catalog-write clusterrole to user/serviceaccount in the desired namespace. +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: kubeapps-service-catalog-write +{{ template "kubeapps.user-rbac.labels" . }} +rules: +- apiGroups: + - servicecatalog.k8s.io + resources: + - serviceinstances + - servicebindings + verbs: + - create + - delete +--- +# kubeapps-service-catalog-admin +# Gives admin access for the Service Broker configuration page in Kubeapps. +# Usage: +# Apply kubeapps-service-catalog-admin clusterrole to user/serviceaccount in all namespaces. +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: kubeapps-service-catalog-admin +{{ template "kubeapps.user-rbac.labels" . }} +rules: +- apiGroups: + - servicecatalog.k8s.io + resources: + - clusterservicebrokers + verbs: + - patch +--- +# kubeapps-repositories-read +# Gives read-only access to App Repositories in Kubeapps. +# Usage: +# Apply kubeapps-repositories-read role to user/serviceaccount in the kubeapps namespace. +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: kubeapps-repositories-read +{{ template "kubeapps.user-rbac.labels" . }} +rules: +- apiGroups: + - kubeapps.com + resources: + - apprepositories + verbs: + - list + - get +--- +# kubeapps-repositories-write +# Gives write access to App Repositories in Kubeapps. +# Usage: +# Apply kubeapps-repositories-write role to user/serviceaccount in the kubeapps namespace. +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: kubeapps-repositories-write +{{ template "kubeapps.user-rbac.labels" . }} +rules: +- apiGroups: + - kubeapps.com + resources: + - apprepositories + verbs: + - get + - create + - update + - delete + # Allows creating secrets for storing repository credentials +- apiGroups: + - "" + resources: + - secrets + verbs: + - create diff --git a/chart/kubeapps/values.yaml b/chart/kubeapps/values.yaml new file mode 100644 index 00000000000..c598f5a168d --- /dev/null +++ b/chart/kubeapps/values.yaml @@ -0,0 +1,175 @@ +# Default values for kubeapps. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +apprepository: + image: + registry: docker.io + repository: kubeapps/apprepository-controller + tag: latest + # Image used to perform chart repository syncs + syncImage: + registry: docker.io + repository: kubeapps/chart-repo + tag: latest + # This image is used in a Helm post-install hook to bootstrap the initialRepos below + jobsImage: + registry: docker.io + repository: lachlanevenson/k8s-kubectl + tag: v1.9.9 + initialRepos: + - name: stable + url: https://kubernetes-charts.storage.googleapis.com + - name: incubator + url: https://kubernetes-charts-incubator.storage.googleapis.com + - name: svc-cat + url: https://svc-catalog-charts.storage.googleapis.com + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + +chartsvc: + image: + registry: docker.io + repository: kubeapps/chartsvc + tag: latest + service: + port: 8080 + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + +dashboard: + image: + registry: docker.io + repository: kubeapps/dashboard + tag: latest + service: + port: 8080 + livenessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 60 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 0 + timeoutSeconds: 5 + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + +frontend: + image: + registry: docker.io + repository: bitnami/nginx + tag: 1.14 + service: + port: 80 + type: ClusterIP + livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 60 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 0 + timeoutSeconds: 5 + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + +tillerProxy: + image: + registry: docker.io + repository: kubeapps/tiller-proxy + tag: latest + service: + port: 8080 + host: tiller-deploy.kube-system:44134 + tls: {} + # ca: + # cert: + # key: + # verify: false + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + +ingress: + enabled: false + # annotations: {} + annotations: + kubernetes.io/ingress.class: addon-http-application-routing + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - kubeapps.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +mongodb: + # Kubeapps uses MongoDB as a cache and persistence is not required + persistence: + enabled: false + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/cmd/apprepository-controller/controller.go b/cmd/apprepository-controller/controller.go index be5256775ea..e654b25e45c 100644 --- a/cmd/apprepository-controller/controller.go +++ b/cmd/apprepository-controller/controller.go @@ -472,7 +472,7 @@ func cleanupJobSpec(repoName string) batchv1.JobSpec { Name: "MONGO_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "mongodb"}, + LocalObjectReference: corev1.LocalObjectReference{Name: mongoSecretName}, Key: "mongodb-root-password", }, }, @@ -506,7 +506,7 @@ func deleteJobName(reponame string) string { func apprepoSyncJobArgs(apprepo *apprepov1alpha1.AppRepository) []string { return []string{ "sync", - "--mongo-url=mongodb.kubeapps", + "--mongo-url=" + mongoURL, "--mongo-user=root", apprepo.GetName(), apprepo.Spec.URL, @@ -520,7 +520,7 @@ func apprepoSyncJobEnvVars(apprepo *apprepov1alpha1.AppRepository) []corev1.EnvV Name: "MONGO_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "mongodb"}, + LocalObjectReference: corev1.LocalObjectReference{Name: mongoSecretName}, Key: "mongodb-root-password", }, }, @@ -541,7 +541,7 @@ func apprepoCleanupJobArgs(repoName string) []string { return []string{ "delete", repoName, - "--mongo-url=mongodb.kubeapps", + "--mongo-url=" + mongoURL, "--mongo-user=root", } } diff --git a/cmd/apprepository-controller/controller_test.go b/cmd/apprepository-controller/controller_test.go index 0bbf1537dfa..c677b75bc01 100644 --- a/cmd/apprepository-controller/controller_test.go +++ b/cmd/apprepository-controller/controller_test.go @@ -13,6 +13,8 @@ import ( ) func Test_newCronJob(t *testing.T) { + mongoURL = "mongodb.kubeapps" + mongoSecretName = "mongodb" tests := []struct { name string apprepo *apprepov1alpha1.AppRepository @@ -186,6 +188,8 @@ func Test_newCronJob(t *testing.T) { } func Test_newSyncJob(t *testing.T) { + mongoURL = "mongodb.kubeapps" + mongoSecretName = "mongodb" tests := []struct { name string apprepo *apprepov1alpha1.AppRepository @@ -349,6 +353,8 @@ func Test_newSyncJob(t *testing.T) { } func Test_newCleanupJob(t *testing.T) { + mongoURL = "mongodb.kubeapps" + mongoSecretName = "mongodb" tests := []struct { name string repoName string diff --git a/cmd/apprepository-controller/main.go b/cmd/apprepository-controller/main.go index 08bc8d1ce9d..20dbe48a7ec 100644 --- a/cmd/apprepository-controller/main.go +++ b/cmd/apprepository-controller/main.go @@ -32,9 +32,12 @@ import ( ) var ( - masterURL string - kubeconfig string - repoSyncImage string + masterURL string + kubeconfig string + repoSyncImage string + namespace string + mongoURL string + mongoSecretName string ) func main() { @@ -59,7 +62,7 @@ func main() { } kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, 0) - apprepoInformerFactory := informers.NewFilteredSharedInformerFactory(apprepoClient, 0, "kubeapps", nil) + apprepoInformerFactory := informers.NewFilteredSharedInformerFactory(apprepoClient, 0, namespace, nil) controller := NewController(kubeClient, apprepoClient, kubeInformerFactory, apprepoInformerFactory) @@ -75,4 +78,7 @@ func init() { flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.") flag.StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.") flag.StringVar(&repoSyncImage, "repo-sync-image", "kubeapps/chart-repo:latest", "container repo/image to use in CronJobs") + flag.StringVar(&namespace, "namespace", "kubeapps", "Namespace to discover AppRepository resources") + flag.StringVar(&mongoURL, "mongo-url", "localhost", "MongoDB URL (see https://godoc.org/labix.org/v2/mgo#Dial for format)") + flag.StringVar(&mongoSecretName, "mongo-secret-name", "mongodb", "Kubernetes secret name for MongoDB credentials") } diff --git a/cmd/chartsvc/main.go b/cmd/chartsvc/main.go index 1d2cc3299cb..3339c93fa39 100644 --- a/cmd/chartsvc/main.go +++ b/cmd/chartsvc/main.go @@ -77,6 +77,6 @@ func main() { port = "8080" } addr := ":" + port - log.WithFields(log.Fields{"addr": addr}).Info("Started RateSvc") + log.WithFields(log.Fields{"addr": addr}).Info("Started chartsvc") http.ListenAndServe(addr, n) } diff --git a/dashboard/public/config.json b/dashboard/public/config.json new file mode 100644 index 00000000000..fd8dda62cb1 --- /dev/null +++ b/dashboard/public/config.json @@ -0,0 +1,3 @@ +{ + "namespace": "default" +} diff --git a/dashboard/src/components/Card/CardIcon.css b/dashboard/src/components/Card/CardIcon.css index e4dfe7f4754..29d4459fc56 100644 --- a/dashboard/src/components/Card/CardIcon.css +++ b/dashboard/src/components/Card/CardIcon.css @@ -7,4 +7,5 @@ .Card__icon img { max-height: 72px; + max-width: 160px; } diff --git a/dashboard/src/shared/AppRepository.ts b/dashboard/src/shared/AppRepository.ts index cecaca347ab..fe10a4bf97f 100644 --- a/dashboard/src/shared/AppRepository.ts +++ b/dashboard/src/shared/AppRepository.ts @@ -1,29 +1,30 @@ import { axios } from "./Auth"; +import Config from "./Config"; import { IAppRepository, IAppRepositoryList } from "./types"; export class AppRepository { public static async list() { - const { data } = await axios.get(AppRepository.APIEndpoint); + const { data } = await axios.get(await AppRepository.getResourceLink()); return data; } public static async get(name: string) { - const { data } = await axios.get(AppRepository.getSelfLink(name)); + const { data } = await axios.get(await AppRepository.getResourceLink(name)); return data; } public static async update(name: string, newApp: IAppRepository) { - const { data } = await axios.put(AppRepository.getSelfLink(name), newApp); + const { data } = await axios.put(await AppRepository.getResourceLink(name), newApp); return data; } public static async delete(name: string) { - const { data } = await axios.delete(AppRepository.getSelfLink(name)); + const { data } = await axios.delete(await AppRepository.getResourceLink(name)); return data; } public static async create(name: string, url: string, auth: any) { - const { data } = await axios.post(AppRepository.APIEndpoint, { + const { data } = await axios.post(await AppRepository.getResourceLink(), { apiVersion: "kubeapps.com/v1alpha1", kind: "AppRepository", metadata: { @@ -34,8 +35,12 @@ export class AppRepository { return data; } - private static APIEndpoint: string = "/api/kube/apis/kubeapps.com/v1alpha1/namespaces/kubeapps/apprepositories"; - private static getSelfLink(name: string): string { - return `${AppRepository.APIEndpoint}/${name}`; + private static APIBase: string = "/api/kube"; + private static APIEndpoint: string = `${AppRepository.APIBase}/apis/kubeapps.com/v1alpha1`; + private static async getResourceLink(name?: string) { + const { namespace } = await Config.getConfig(); + return `${AppRepository.APIEndpoint}/namespaces/${namespace}/apprepositories${ + name ? `/${name}` : "" + }`; } } diff --git a/dashboard/src/shared/Chart.ts b/dashboard/src/shared/Chart.ts index d3c3c17cbfe..561777f1e53 100644 --- a/dashboard/src/shared/Chart.ts +++ b/dashboard/src/shared/Chart.ts @@ -1,7 +1,5 @@ import axios from "axios"; -// import { IFunction, IFunctionList, IResource, IStatus } from "./types"; - export default class Chart { public static async getReadme(id: string, version: string) { const url = `${Chart.APIEndpoint}/assets/${id}/versions/${version}/README.md`; diff --git a/dashboard/src/shared/Config.ts b/dashboard/src/shared/Config.ts new file mode 100644 index 00000000000..056e32f0628 --- /dev/null +++ b/dashboard/src/shared/Config.ts @@ -0,0 +1,20 @@ +import axios from "axios"; + +interface IConfig { + namespace: string; +} + +export default class Config { + public static async getConfig() { + if (Config.config) { + return Config.config; + } + const url = `${Config.APIEndpoint}`; + const { data } = await axios.get(url); + Config.config = data; + return Config.config; + } + + private static config: IConfig; + private static APIEndpoint: string = "/config.json"; +} diff --git a/docs/user/access-control.md b/docs/user/access-control.md index 8fcb19c3020..231cafe62b2 100644 --- a/docs/user/access-control.md +++ b/docs/user/access-control.md @@ -55,40 +55,20 @@ kubectl create -n default rolebinding example-view \ In order to create, update and delete Applications in a namespace, apply the `edit` ClusterRole in the desired namespace and the `kubeapps-repositories-read` -Role in the `kubeapps` namespace. The `edit` ClusterRole should be available in most -Kubernetes distributions, you can find more information about that role [here](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles). +Role in the namespace Kubeapps is installed in. The `edit` ClusterRole should be +available in most Kubernetes distributions, you can find more information about +that role +[here](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles). ``` kubectl create -n default rolebinding example-edit \ --clusterrole=edit \ --serviceaccount default:example -kubectl create -n kubeapps rolebinding example-kubeapps-repositories-read \ +kubectl create -n $KUBEAPPS_NAMESPACE rolebinding example-kubeapps-repositories-read \ --role=kubeapps-repositories-read \ --serviceaccount default:example ``` -### Functions - -#### Read access to Functions within a namespace - -In order to list and view Functions in a namespace, apply the -`kubeapps-functions-read` ClusterRole in the desired namespace and the -`kubeapps-kubeless-config-read` Role in the `kubeless` namespace: - -``` -kubectl create -n default rolebinding example-kubeapps-functions-read --clusterrole=kubeapps-functions-read --serviceaccount default:example -kubectl create -n kubeless rolebinding example-kubeapps-kubeless-config-read --role=kubeapps-kubeless-config-read --serviceaccount default:example -``` - -#### Write access to Functions within a namespace - -In order to create, update and delete Functions in a namespace, apply the -`kubeapps-functions-write` ClusterRole in the desired namespace. - -``` -kubectl create -n default rolebinding example-kubeapps-functions-write --clusterrole=kubeapps-functions-write --serviceaccount default:example -``` - ### Service Catalog, Service Instances and Bindings #### Read access to Service Instances and Bindings within a namespaces @@ -131,19 +111,19 @@ kubectl create clusterrolebinding example-kubeapps-service-catalog-admin --clust #### Read access to App Repositories In order to list the configured App Repositories in Kubeapps, apply the -`kubeapps-repositories-read` Role in the kubeapps namespace. +`kubeapps-repositories-read` Role in the namespace Kubeapps is installed in. ``` -kubectl create -n kubeapps rolebinding example-kubeapps-repositories-read --role=kubeapps-repositories-read --serviceaccount default:example +kubectl create -n $KUBEAPPS_NAMESPACE rolebinding example-kubeapps-repositories-read --role=kubeapps-repositories-read --serviceaccount default:example ``` #### Write access to App Repositories In order to create and refresh App Repositories in Kubeapps, apply the -`kubeapps-repositories-write` Role in the kubeapps namespace. +`kubeapps-repositories-write` Role in the namespace Kubeapps is installed in. ``` -kubectl create -n kubeapps rolebinding example-kubeapps-repositories-write --role=kubeapps-repositories-write --serviceaccount default:example +kubectl create -n $KUBEAPPS_NAMESPACE rolebinding example-kubeapps-repositories-write --role=kubeapps-repositories-write --serviceaccount default:example ``` ### Assigning roles across multiple namespaces @@ -157,8 +137,8 @@ kubectl create -n example rolebinding example-kubeapps-applications-write --clus kubectl create -n example rolebinding example-kubeapps-applications-write --clusterrole=kubeapps-applications-write --serviceaccount default:example ``` -Note that there's no need to recreate the RoleBinding in the kubeapps namespace -that is also needed, since that has already been created. +Note that there's no need to recreate the RoleBinding in the namespace Kubeapps +is installed in that is also needed, since that has already been created. If you want to give access for every namespace, simply create a ClusterRoleBinding instead of a RoleBinding. For example, to give the "example" user permissions to manage Applications in _any_ namespace: