diff --git a/charts/template-controller/.helmignore b/charts/template-controller/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/template-controller/.helmignore @@ -0,0 +1,23 @@ +# 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 +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/template-controller/Chart.yaml b/charts/template-controller/Chart.yaml new file mode 100644 index 0000000..1abbbf4 --- /dev/null +++ b/charts/template-controller/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: template-controller +maintainers: + - name: kluctl + url: https://github.com/kluctl/charts + - email: aljoscha.poertner@posteo.de + name: AljoschaP + - email: ablock84@gmail.com + name: codablock +description: A Helm chart for the template-controller +type: application +version: 0.1.0 +appVersion: "v0.4.1" diff --git a/charts/template-controller/crds/templates.kluctl.io_listgithubpullrequests.yaml b/charts/template-controller/crds/templates.kluctl.io_listgithubpullrequests.yaml new file mode 100644 index 0000000..dbf93c1 --- /dev/null +++ b/charts/template-controller/crds/templates.kluctl.io_listgithubpullrequests.yaml @@ -0,0 +1,170 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: listgithubpullrequests.templates.kluctl.io +spec: + group: templates.kluctl.io + names: + kind: ListGithubPullRequests + listKind: ListGithubPullRequestsList + plural: listgithubpullrequests + singular: listgithubpullrequests + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ListGithubPullRequests is the Schema for the listgithubpullrequests + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ListGithubPullRequestsSpec defines the desired state of ListGithubPullRequests + properties: + base: + type: string + head: + type: string + interval: + default: 5m + description: Interval is the interval at which to query the Gitlab + API. Defaults to 5m. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + labels: + description: Labels is used to filter the MRs that you want to target + items: + type: string + type: array + limit: + default: 100 + description: Limit limits the maximum number of pull requests to fetch. + Defaults to 100 + type: integer + owner: + type: string + repo: + type: string + state: + default: all + description: 'State is an additional PR filter to get only those with + a certain state. Default: "all"' + enum: + - all + - open + - closed + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - limit + - owner + - repo + type: object + status: + description: ListGithubPullRequestsStatus defines the observed state of + ListGithubPullRequests + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + pullRequests: + items: + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/template-controller/crds/templates.kluctl.io_listgitlabmergerequests.yaml b/charts/template-controller/crds/templates.kluctl.io_listgitlabmergerequests.yaml new file mode 100644 index 0000000..c2d7b92 --- /dev/null +++ b/charts/template-controller/crds/templates.kluctl.io_listgitlabmergerequests.yaml @@ -0,0 +1,174 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: listgitlabmergerequests.templates.kluctl.io +spec: + group: templates.kluctl.io + names: + kind: ListGitlabMergeRequests + listKind: ListGitlabMergeRequestsList + plural: listgitlabmergerequests + singular: listgitlabmergerequests + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ListGitlabMergeRequests is the Schema for the listgitlabmergerequests + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ListGitlabMergeRequestsSpec defines the desired state of + ListGitlabMergeRequests + properties: + api: + description: The GitLab API URL to talk to. If blank, uses https://gitlab.com/. + type: string + interval: + default: 5m + description: Interval is the interval at which to query the Gitlab + API. Defaults to 5m. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + labels: + description: Labels is used to filter the MRs that you want to target + items: + type: string + type: array + limit: + default: 100 + description: Limit limits the maximum number of pull requests to fetch. + Defaults to 100 + type: integer + project: + description: GitLab project to scan. Required. + type: string + sourceBranch: + type: string + state: + default: all + description: 'PullRequestState is an additional MRs filter to get + only those with a certain state. Default: "all"' + enum: + - all + - opened + - closed + - locked + - merged + type: string + targetBranch: + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - limit + - project + type: object + status: + description: ListGitlabMergeRequestsStatus defines the observed state + of ListGitlabMergeRequests + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + mergeRequests: + items: + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/template-controller/crds/templates.kluctl.io_objecthandlers.yaml b/charts/template-controller/crds/templates.kluctl.io_objecthandlers.yaml new file mode 100644 index 0000000..3387040 --- /dev/null +++ b/charts/template-controller/crds/templates.kluctl.io_objecthandlers.yaml @@ -0,0 +1,369 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: objecthandlers.templates.kluctl.io +spec: + group: templates.kluctl.io + names: + kind: ObjectHandler + listKind: ObjectHandlerList + plural: objecthandlers + singular: objecthandler + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ObjectHandler is the Schema for the objecthandlers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ObjectHandlerSpec defines the desired state of ObjectHandler + properties: + forObject: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - apiVersion + - kind + - name + type: object + handlers: + items: + properties: + pullRequestApprove: + properties: + github: + properties: + owner: + type: string + pullRequestId: + type: integer + repo: + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + description: The GitLab API URL to talk to. If blank, + uses https://gitlab.com/. + type: string + mergeRequestId: + description: The merge request id + type: integer + project: + description: GitLab project to scan. Required. + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + missingReadyConditionIsError: + default: false + type: boolean + type: object + pullRequestCommand: + properties: + commands: + items: + properties: + actions: + items: + properties: + annotate: + properties: + annotation: + type: string + value: + type: string + required: + - annotation + - value + type: object + jsonPatch: + items: + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + description: + type: string + name: + type: string + required: + - actions + - name + type: object + type: array + github: + properties: + owner: + type: string + pullRequestId: + type: integer + repo: + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + description: The GitLab API URL to talk to. If blank, + uses https://gitlab.com/. + type: string + mergeRequestId: + description: The merge request id + type: integer + project: + description: GitLab project to scan. Required. + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + postHelpComment: + type: boolean + required: + - commands + type: object + pullRequestComment: + properties: + github: + properties: + owner: + type: string + pullRequestId: + type: integer + repo: + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + description: The GitLab API URL to talk to. If blank, + uses https://gitlab.com/. + type: string + mergeRequestId: + description: The merge request id + type: integer + project: + description: GitLab project to scan. Required. + type: string + tokenRef: + description: Authentication token reference. + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + type: object + type: object + type: array + interval: + default: 1m + type: string + required: + - forObject + - handlers + - interval + type: object + status: + description: ObjectHandlerStatus defines the observed state of ObjectHandler + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + handlerStatus: + items: + properties: + error: + type: string + key: + type: string + pullRequestApprove: + properties: + approved: + type: boolean + type: object + pullRequestCommand: + properties: + helpNoteBodyHash: + type: string + helpNoteId: + type: string + lastProcessedCommentTime: + type: string + type: object + pullRequestComment: + properties: + lastPostedStatusHash: + type: string + noteId: + type: string + type: object + required: + - key + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/template-controller/crds/templates.kluctl.io_objecttemplates.yaml b/charts/template-controller/crds/templates.kluctl.io_objecttemplates.yaml new file mode 100644 index 0000000..5a59510 --- /dev/null +++ b/charts/template-controller/crds/templates.kluctl.io_objecttemplates.yaml @@ -0,0 +1,208 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: objecttemplates.templates.kluctl.io +spec: + group: templates.kluctl.io + names: + kind: ObjectTemplate + listKind: ObjectTemplateList + plural: objecttemplates + singular: objecttemplate + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ObjectTemplate is the Schema for the objecttemplates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ObjectTemplateSpec defines the desired state of ObjectTemplate + properties: + interval: + default: 30s + type: string + matrix: + items: + properties: + list: + items: + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + name: + type: string + object: + properties: + expandLists: + type: boolean + jsonPath: + type: string + ref: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - apiVersion + - kind + - name + type: object + required: + - ref + type: object + required: + - name + type: object + type: array + prune: + default: false + type: boolean + serviceAccountName: + description: The name of the Kubernetes service account to impersonate + when reconciling this ObjectTemplate. If omitted, the "default" + service account is used. + type: string + suspend: + default: false + type: boolean + templates: + items: + properties: + object: + type: object + x-kubernetes-preserve-unknown-fields: true + raw: + type: string + type: object + type: array + required: + - interval + - matrix + - templates + type: object + status: + description: ObjectTemplateStatus defines the observed state of ObjectTemplate + properties: + appliedResources: + items: + properties: + error: + type: string + ref: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - apiVersion + - kind + - name + type: object + success: + type: boolean + required: + - ref + - success + type: object + type: array + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/template-controller/templates/NOTES.txt b/charts/template-controller/templates/NOTES.txt new file mode 100644 index 0000000..43e598e --- /dev/null +++ b/charts/template-controller/templates/NOTES.txt @@ -0,0 +1,16 @@ +1. Get the application URL by running these commands: +{{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "template-controller.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.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "template-controller.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "template-controller.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "template-controller.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/charts/template-controller/templates/_helpers.tpl b/charts/template-controller/templates/_helpers.tpl new file mode 100644 index 0000000..6a4aa4d --- /dev/null +++ b/charts/template-controller/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "template-controller.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 "template-controller.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 }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "template-controller.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "template-controller.labels" -}} +helm.sh/chart: {{ include "template-controller.chart" . }} +{{ include "template-controller.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "template-controller.selectorLabels" -}} +app.kubernetes.io/name: {{ include "template-controller.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "template-controller.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "template-controller.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/template-controller/templates/clusterrole.yaml b/charts/template-controller/templates/clusterrole.yaml new file mode 100644 index 0000000..8fe5c86 --- /dev/null +++ b/charts/template-controller/templates/clusterrole.yaml @@ -0,0 +1,348 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: {{ include "template-controller.fullname" . }}-manager-role +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list + - watch +- apiGroups: + - templates.kluctl.io + resources: + - listgithubpullrequests + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - listgithubpullrequests/finalizers + verbs: + - update +- apiGroups: + - templates.kluctl.io + resources: + - listgithubpullrequests/status + verbs: + - get + - patch + - update +- apiGroups: + - templates.kluctl.io + resources: + - listgitlabmergerequests + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - listgitlabmergerequests/finalizers + verbs: + - update +- apiGroups: + - templates.kluctl.io + resources: + - listgitlabmergerequests/status + verbs: + - get + - patch + - update +- apiGroups: + - templates.kluctl.io + resources: + - objecthandlers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - objecthandlers/finalizers + verbs: + - update +- apiGroups: + - templates.kluctl.io + resources: + - objecthandlers/status + verbs: + - get + - patch + - update +- apiGroups: + - templates.kluctl.io + resources: + - objecttemplates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - objecttemplates/finalizers + verbs: + - update +- apiGroups: + - templates.kluctl.io + resources: + - objecttemplates/status + verbs: + - get + - patch + - update +--- +# permissions for end users to edit listgithubpullrequests. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: {{ include "template-controller.fullname" . }}-clusterrole + app.kubernetes.io/instance: listgithubpullrequests-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: template-controller + app.kubernetes.io/part-of: template-controller + app.kubernetes.io/managed-by: kustomize + name: {{ include "template-controller.fullname" . }}-listgithubpullrequests-editor-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - listgithubpullrequests + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - listgithubpullrequests/status + verbs: + - get +--- +# permissions for end users to view listgithubpullrequests. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: {{ include "template-controller.fullname" . }}-clusterrole + app.kubernetes.io/instance: listgithubpullrequests-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: template-controller + app.kubernetes.io/part-of: template-controller + app.kubernetes.io/managed-by: kustomize + name: {{ include "template-controller.fullname" . }}-listgithubpullrequests-viewer-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - listgithubpullrequests + verbs: + - get + - list + - watch +- apiGroups: + - templates.kluctl.io + resources: + - listgithubpullrequests/status + verbs: + - get +--- +# permissions for end users to edit listgitlabmergerequests. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: {{ include "template-controller.fullname" . }}-clusterrole + app.kubernetes.io/instance: listgitlabmergerequests-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: template-controller + app.kubernetes.io/part-of: template-controller + app.kubernetes.io/managed-by: kustomize + name: {{ include "template-controller.fullname" . }}-listgitlabmergerequests-editor-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - listgitlabmergerequests + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - listgitlabmergerequests/status + verbs: + - get +--- +# permissions for end users to view listgitlabmergerequests. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: {{ include "template-controller.fullname" . }}-clusterrole + app.kubernetes.io/instance: listgitlabmergerequests-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: template-controller + app.kubernetes.io/part-of: template-controller + app.kubernetes.io/managed-by: kustomize + name: {{ include "template-controller.fullname" . }}-listgitlabmergerequests-viewer-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - listgitlabmergerequests + verbs: + - get + - list + - watch +- apiGroups: + - templates.kluctl.io + resources: + - listgitlabmergerequests/status + verbs: + - get +--- +# permissions for end users to edit objecthandlers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "template-controller.fullname" . }}-objecthandler-editor-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - objecthandlers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - objecthandlers/status + verbs: + - get +--- +# permissions for end users to view objecthandlers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "template-controller.fullname" . }}-objecthandler-viewer-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - objecthandlers + verbs: + - get + - list + - watch +- apiGroups: + - templates.kluctl.io + resources: + - objecthandlers/status + verbs: + - get +--- +# permissions for end users to edit objecttemplates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "template-controller.fullname" . }}-objecttemplate-editor-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - objecttemplates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - templates.kluctl.io + resources: + - objecttemplates/status + verbs: + - get +--- +# permissions for end users to view objecttemplates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "template-controller.fullname" . }}-objecttemplate-viewer-role +rules: +- apiGroups: + - templates.kluctl.io + resources: + - objecttemplates + verbs: + - get + - list + - watch +- apiGroups: + - templates.kluctl.io + resources: + - objecttemplates/status + verbs: + - get +--- diff --git a/charts/template-controller/templates/clusterrolebinding.yaml b/charts/template-controller/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..d634f81 --- /dev/null +++ b/charts/template-controller/templates/clusterrolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "template-controller.fullname" . }}-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "template-controller.fullname" . }}-manager-role +subjects: + - kind: ServiceAccount + name: {{ include "template-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/template-controller/templates/deployment.yaml b/charts/template-controller/templates/deployment.yaml new file mode 100644 index 0000000..320033d --- /dev/null +++ b/charts/template-controller/templates/deployment.yaml @@ -0,0 +1,70 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "template-controller.fullname" . }} + labels: + {{- include "template-controller.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "template-controller.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "template-controller.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "template-controller.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + args: + - --watch-all-namespaces + - --leader-elect + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http-prom + containerPort: 8080 + protocol: TCP + - name: healthz + containerPort: 8081 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: healthz + readinessProbe: + httpGet: + path: /readyz + port: healthz + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/template-controller/templates/role.yaml b/charts/template-controller/templates/role.yaml new file mode 100644 index 0000000..d485091 --- /dev/null +++ b/charts/template-controller/templates/role.yaml @@ -0,0 +1,38 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "template-controller.fullname" . }}-leader-election-role +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- diff --git a/charts/template-controller/templates/rolebinding.yaml b/charts/template-controller/templates/rolebinding.yaml new file mode 100644 index 0000000..9b33aad --- /dev/null +++ b/charts/template-controller/templates/rolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "template-controller.fullname" . }}-leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "template-controller.fullname" . }}-leader-election-role +subjects: + - kind: ServiceAccount + name: {{ include "template-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/template-controller/templates/service.yaml b/charts/template-controller/templates/service.yaml new file mode 100644 index 0000000..1e89ced --- /dev/null +++ b/charts/template-controller/templates/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "template-controller.fullname" . }} + labels: + {{- include "template-controller.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.prometheus.port }} + targetPort: http-prom + protocol: TCP + name: http-prom + - port: {{ .Values.service.health.port }} + targetPort: healthz + protocol: TCP + name: healthz + selector: + {{- include "template-controller.selectorLabels" . | nindent 4 }} diff --git a/charts/template-controller/templates/serviceaccount.yaml b/charts/template-controller/templates/serviceaccount.yaml new file mode 100644 index 0000000..be5c287 --- /dev/null +++ b/charts/template-controller/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "template-controller.serviceAccountName" . }} + labels: + {{- include "template-controller.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/template-controller/templates/tests/test-connection.yaml b/charts/template-controller/templates/tests/test-connection.yaml new file mode 100644 index 0000000..5c2b8a7 --- /dev/null +++ b/charts/template-controller/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "template-controller.fullname" . }}-test-connection" + labels: + {{- include "template-controller.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "template-controller.fullname" . }}:{{ .Values.service.health.port }}/healthz'] + restartPolicy: Never diff --git a/charts/template-controller/values.yaml b/charts/template-controller/values.yaml new file mode 100644 index 0000000..615dbea --- /dev/null +++ b/charts/template-controller/values.yaml @@ -0,0 +1,64 @@ +# Default values for flux-kluctl-controller. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + repository: ghcr.io/kluctl/template-controller + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +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: + prometheus.io/scrape: "true" + prometheus.io/port: "8080" + +podSecurityContext: + fsGroup: 1337 + +securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1337 + seccompProfile: + type: RuntimeDefault + +service: + type: ClusterIP + prometheus: + port: 8080 + health: + port: 8081 + +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: 1000m + # memory: 1Gi + # requests: + # cpu: 100m +# memory: 64Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {}