diff --git a/apis/installer/v1alpha1/ace_billing_types.go b/apis/installer/v1alpha1/ace_billing_types.go
index 130f2ff0a..7d34b0d09 100644
--- a/apis/installer/v1alpha1/ace_billing_types.go
+++ b/apis/installer/v1alpha1/ace_billing_types.go
@@ -54,8 +54,8 @@ type BillingSpec struct {
//+optional
NameOverride string `json:"nameOverride"`
//+optional
- FullnameOverride string `json:"fullnameOverride"`
- ServiceAccount LocalObjectReference `json:"serviceAccount"`
+ FullnameOverride string `json:"fullnameOverride"`
+ ServiceAccount ServiceAccountSpec `json:"serviceAccount"`
//+optional
PodAnnotations map[string]string `json:"podAnnotations"`
//+optional
diff --git a/apis/installer/v1alpha1/zz_generated.deepcopy.go b/apis/installer/v1alpha1/zz_generated.deepcopy.go
index 59121fd34..51404cb9e 100644
--- a/apis/installer/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/installer/v1alpha1/zz_generated.deepcopy.go
@@ -2629,7 +2629,7 @@ func (in *BillingSpec) DeepCopyInto(out *BillingSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
- out.ServiceAccount = in.ServiceAccount
+ in.ServiceAccount.DeepCopyInto(&out.ServiceAccount)
if in.PodAnnotations != nil {
in, out := &in.PodAnnotations, &out.PodAnnotations
*out = make(map[string]string, len(*in))
diff --git a/charts/billing/README.md b/charts/billing/README.md
index 885150c2e..32f223f1a 100644
--- a/charts/billing/README.md
+++ b/charts/billing/README.md
@@ -56,7 +56,9 @@ The following table lists the configurable parameters of the `billing` chart and
| imagePullSecrets | | [] |
| nameOverride | | "" |
| fullnameOverride | | "" |
-| serviceAccount.name | | "" |
+| serviceAccount.create | Specifies whether a service account should be created | true |
+| serviceAccount.annotations | Annotations to add to the service account | {} |
+| serviceAccount.name | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | "" |
| podAnnotations | | {} |
| podSecurityContext.fsGroup | | 65534 |
| securityContext | Security options this container should run with | {"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}} |
diff --git a/charts/billing/templates/_helpers.tpl b/charts/billing/templates/_helpers.tpl
index 4a3fb1ab5..deccdc769 100644
--- a/charts/billing/templates/_helpers.tpl
+++ b/charts/billing/templates/_helpers.tpl
@@ -54,8 +54,12 @@ app.kubernetes.io/instance: {{ .Release.Name }}
Create the name of the service account to use
*/}}
{{- define "appscode.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "billing.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
+{{- end }}
{{/*
Returns the registry used for image docker image
diff --git a/charts/billing/templates/rbac/rbac.yaml b/charts/billing/templates/rbac/rbac.yaml
new file mode 100644
index 000000000..8170b945a
--- /dev/null
+++ b/charts/billing/templates/rbac/rbac.yaml
@@ -0,0 +1,154 @@
+{{- /*
+appscode:license-checker and appscode:license-reader are shared with the ace
+chart (via platform-api), which templates them identically. Both charts declare
+them as pre-install/pre-upgrade hooks with hook-delete-policy
+before-hook-creation, so a hook run deletes and recreates whatever is already
+there - the chart reconciled last would win. Create them here only when they are
+absent so the ace chart stays authoritative and billing never overwrites them.
+Permissions billing needs on top of the shared set belong in the billing-owned
+ClusterRole at the bottom of this file, which is never contested.
+*/}}
+{{- if not (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "appscode:license-checker") }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: appscode:license-checker
+ annotations:
+ "helm.sh/hook": pre-install,pre-upgrade
+ "helm.sh/hook-delete-policy": before-hook-creation
+rules:
+# Get cluster id
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ verbs: ["get"]
+# Issue license
+- apiGroups:
+ - proxyserver.licenses.appscode.com
+ resources:
+ - licenserequests
+ verbs: ["create"]
+# Detect workload/owner of operator pod
+- apiGroups:
+ - ""
+ resources:
+ - pods
+ verbs: ["get"]
+- apiGroups:
+ - apps
+ resources:
+ - deployments
+ - replicasets
+ verbs: ["get"]
+# Write events in case of license verification failure
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs: ["get", "list", "create", "patch"]
+{{- end }}
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "billing.fullname" . }}-license-checker
+ labels:
+ {{- include "billing.labels" . | nindent 4 }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: appscode:license-checker
+subjects:
+- kind: ServiceAccount
+ name: {{ include "appscode.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+
+---
+
+{{- if not (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "appscode:license-reader") }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: appscode:license-reader
+ annotations:
+ "helm.sh/hook": pre-install,pre-upgrade
+ "helm.sh/hook-delete-policy": before-hook-creation
+rules:
+# Detect license server endpoint for kubedb addons
+- apiGroups:
+ - apiregistration.k8s.io
+ resources:
+ - apiservices
+ verbs: ["get"]
+- nonResourceURLs:
+ - /appscode/license
+ verbs: ["get"]
+{{- end }}
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "billing.fullname" . }}-license-reader
+ labels:
+ {{- include "billing.labels" . | nindent 4 }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: appscode:license-reader
+subjects:
+- kind: ServiceAccount
+ name: {{ include "appscode.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "billing.fullname" . }}
+ labels:
+ {{- include "billing.labels" . | nindent 4 }}
+rules:
+# Read the cluster metadata the license enforcer and the site info publisher
+# need. Kept here rather than in appscode:license-checker because that role is
+# shared with the ace chart and would lose this rule the next time the ace
+# chart reconciles it.
+- apiGroups:
+ - ""
+ resources:
+ - configmaps
+ verbs: ["get"]
+ resourceNames: ["ace-info"]
+# for site info
+- apiGroups:
+ - ""
+ resources:
+ - nodes
+ verbs: ["get", "list", "watch"]
+- apiGroups:
+ - storage.k8s.io
+ resources:
+ - storageclasses
+ verbs: ["get", "list", "watch"]
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "billing.fullname" . }}
+ labels:
+ {{- include "billing.labels" . | nindent 4 }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "billing.fullname" . }}
+subjects:
+- kind: ServiceAccount
+ name: {{ include "appscode.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
diff --git a/charts/billing/templates/rbac/serviceaccount.yaml b/charts/billing/templates/rbac/serviceaccount.yaml
new file mode 100644
index 000000000..6734bd7e2
--- /dev/null
+++ b/charts/billing/templates/rbac/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "appscode.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "billing.labels" . | nindent 4 }}
+ {{- with .Values.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/billing/values.openapiv3_schema.yaml b/charts/billing/values.openapiv3_schema.yaml
index a69560cb0..ace58f8a1 100644
--- a/charts/billing/values.openapiv3_schema.yaml
+++ b/charts/billing/values.openapiv3_schema.yaml
@@ -762,10 +762,16 @@ properties:
type: object
serviceAccount:
properties:
+ annotations:
+ additionalProperties:
+ type: string
+ type: object
+ create:
+ type: boolean
name:
type: string
required:
- - name
+ - create
type: object
settings:
properties:
diff --git a/charts/billing/values.yaml b/charts/billing/values.yaml
index 916058df1..3eb6807dc 100644
--- a/charts/billing/values.yaml
+++ b/charts/billing/values.yaml
@@ -23,6 +23,12 @@ nameOverride: ""
fullnameOverride: ""
serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}