├── LICENSE ├── README.md ├── charts ├── README.md ├── debezium-connect │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ └── service.yaml │ └── values.yaml ├── debezium-mysql │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ └── service.yaml │ └── values.yaml ├── minio │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── minio_deployment.yaml │ │ ├── minio_distributed_configmap.yaml │ │ ├── minio_pvc.yaml │ │ ├── minio_secret.yaml │ │ ├── minio_statefulset.yaml │ │ ├── minio_svc.yaml │ │ └── minioconfig_configmap.yaml │ └── values.yaml ├── mongodb │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── pvc.yaml │ │ ├── secrets.yaml │ │ └── svc.yaml │ └── values.yaml └── tika-server │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ └── service.yaml │ └── values.yaml └── incubator ├── controller ├── Makefile ├── README.md ├── ns.py └── requirements.txt ├── crypto ├── Chart.yaml ├── README.md ├── crypto.py ├── requirements.txt └── templates │ └── function.yaml ├── hello-python-with-data ├── README.md ├── hellowithdata.py ├── package.json └── serverless.yml ├── hello-python ├── README.md ├── hello.py ├── package.json └── serverless.yml ├── kafka-connect ├── README.md ├── kafka-connect.py ├── package.json ├── requirements.txt └── serverless.yml ├── kubeless-reminder ├── Makefile ├── README.md ├── reminder.py └── requirements.txt ├── minio-resize ├── Makefile ├── README.md ├── requirements.txt └── resize.py ├── minio-slack ├── README.md ├── minio-slack.py └── requirements.txt ├── ocr ├── README.md ├── ocr.py └── requirements.txt ├── rest-api ├── README.md ├── api │ ├── controllers │ │ └── todoListController.js │ └── models │ │ └── todoListModel.js ├── package.json └── server.js ├── slack ├── Makefile ├── README.md ├── bot.py ├── botevents.py └── requirements.txt ├── twitter ├── README.md ├── package.json ├── requirements.txt ├── serverless.yml └── tweet.py ├── weather ├── .gitignore ├── README.md ├── handler.js └── package.json └── yaml-object └── function.yaml /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright (c) 2016-2017 Bitnami 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## WARNING: Kubeless is no longer actively maintained by VMware. 2 | 3 | VMware has made the difficult decision to stop driving this project and therefore we will no longer actively respond to issues or pull requests. If you would like to take over maintaining this project independently from VMware, please let us know so we can add a link to your forked project here. 4 | 5 | Thank You. 6 | 7 | # Functions for Kubeless 8 | 9 | This repository contains Kubeless Functions. Kubeless is a Kubernetes-native serverless framework that makes use of Kubernetes' ThirdPartyResource to be able to create functions as custom Kubernetes resources 10 | 11 | The purpose of this repository is to provide a place for maintaining and contributing official Kubeless functions, with CI processes in place for assuring an always up-to-date repository. 12 | 13 | ## Repository structure 14 | The Charts in this repository are organized into two folders: 15 | * charts 16 | * incubator 17 | 18 | Stable functions counts with an CI process in place and they are maintained and updated 19 | Incubator functions are those to be shared and improved on until they are ready to be moved into the charts folder. 20 | 21 | ## Structure of a Kubeless Function 22 | Each kubeless functions must have: 23 | - A metadata file 24 | - A README.md file 25 | - A way to declare dependencies 26 | 27 | -------------------------------------------------------------------------------- /charts/README.md: -------------------------------------------------------------------------------- 1 | # Charts repository for kubeless 2 | 3 | This is a chart repository, served via Google Cloud Storage. 4 | 5 | The charts in this repository are used with kubeless functions 6 | -------------------------------------------------------------------------------- /charts/debezium-connect/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/debezium-connect/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: Kafka Connect service by Debezium 2 | engine: gotpl 3 | home: http://debezium.io/docs/connectors/mysql/ 4 | keywords: 5 | - mysql 6 | - debezium 7 | - kafka 8 | - connector 9 | maintainers: 10 | - email: containers@bitnami.com 11 | name: Bitnami 12 | name: debezium-connect 13 | version: 0.1.0 14 | -------------------------------------------------------------------------------- /charts/debezium-connect/README.md: -------------------------------------------------------------------------------- 1 | Debezium Kafka Connect 2 | ===== 3 | 4 | [Debezium Kafka Connect](http://debezium.io/docs/tutorial/) is a server that can monitor a MySQL database and send the events to a kafka-server. 5 | 6 | Introduction 7 | ------------ 8 | 9 | This chart bootstraps a Kafka Connect deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. 10 | 11 | Prerequisites 12 | ------------- 13 | 14 | - Kubernetes 1.4+ with Beta APIs enabled for default standalone mode. 15 | - PV provisioner support in the underlying infrastructure. 16 | 17 | Installing the Chart 18 | -------------------- 19 | 20 | Install this chart using: 21 | 22 | ```bash 23 | $ helm repo add kubeless-functions-charts https://kubeless-functions-charts.storage.googleapis.com 24 | $ helm install kubeless-functions-charts/debezium-connect 25 | ``` 26 | 27 | The command deploys Kafka-Connect on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. 28 | 29 | ### Release name 30 | 31 | An instance of a chart running in a Kubernetes cluster is called a release. Each release is identified by a unique name within the cluster. Helm automatically assigns a unique release name after installing the chart. You can also set your preferred name by: 32 | 33 | ```bash 34 | $ helm install --name my-release kubeless-functions-charts/debezium-connect 35 | ``` 36 | 37 | ### Updating Kafka-Connect configuration via Helm 38 | 39 | [ConfigMap](https://kubernetes.io/docs/user-guide/configmap/) allows injecting containers with configuration data even while a Helm release is deployed. 40 | 41 | To update your Kafka-Connect server configuration while it is deployed in a release, you need to 42 | 43 | 1. Check all the configurable values in the Kafka-Connect chart using `helm inspect values kubeless-functions-charts/debezium-connect`. 44 | 2. Override the `config` settings in a YAML formatted file, and then pass that file like this `helm upgrade -f config.yaml kubeless-functions-charts/debezium-connect`. 45 | 3. Restart the Kafka-Connect server(s) for the changes to take effect. 46 | 47 | You can also check the history of upgrades to a release using `helm history my-release`. Replace `my-release` with the actual release name. 48 | 49 | Uninstalling the Chart 50 | ---------------------- 51 | 52 | Assuming your release is named as `my-release`, delete it using the command: 53 | 54 | ```bash 55 | $ helm delete my-release 56 | ``` 57 | 58 | The command removes all the Kubernetes components associated with the chart and deletes the release. 59 | 60 | Configuration 61 | ------------- 62 | 63 | The following tables lists the configurable parameters of the Kafka-Connect chart and their default values. 64 | 65 | | Parameter | Description | Default | 66 | |----------------------------|-------------------------------------|---------------------------------------------------------| 67 | | `image.repository` | Kafka-Connect image name | `debezium/kafka-connect` | 68 | | `image.tag` | Kafka-Connect image tag. | `0.5` | 69 | | `image.pullPolicy` | Image pull policy | `IfNotPresent` | 70 | | `service.name` | Kubernetes service name | `mysql` | 71 | | `service.type` | Kubernetes service type | `ClusterIP` | 72 | | `service.internalPort` | Kubernetes service internal port | `8083` | 73 | | `service.externalPort` | Kubernetes service externam port | `8083` | 74 | | `config.groupId` | Kafka group Id | `debezium` | 75 | | `config.configStorageTopic`| Topic to store the configs | `mysqlUser` | 76 | | `config.offsetStorageTopic`| Topic to store the offsets | `mysqlpw` | 77 | | `config.bootstrapServers` | Kafka server host | `mysqlpw` | 78 | | `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | 79 | 80 | You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 81 | 82 | ```bash 83 | $ helm install --name my-release \ 84 | --set config.mysqlRootPassword=rootpassword \ 85 | kubeless-functions-charts/debezium-connect 86 | ``` 87 | Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example, 88 | 89 | ```bash 90 | $ helm install --name my-release -f values.yaml kubeless-functions-charts/debezium-connect 91 | ``` 92 | 93 | > **Tip**: You can use the default [values.yaml](values.yaml) 94 | -------------------------------------------------------------------------------- /charts/debezium-connect/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if contains "NodePort" .Values.service.type }} 3 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) 4 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 5 | echo http://$NODE_IP:$NODE_PORT/login 6 | {{- else if contains "LoadBalancer" .Values.service.type }} 7 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 8 | You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' 9 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 10 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 11 | {{- else if contains "ClusterIP" .Values.service.type }} 12 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "fullname" . }}" -o jsonpath="{.items[0].metadata.name}") 13 | echo "Visit http://127.0.0.1:8080 to use your application" 14 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /charts/debezium-connect/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/debezium-connect/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "fullname" . }} 16 | spec: 17 | containers: 18 | - name: {{ template "fullname" . }} 19 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 20 | imagePullPolicy: {{ .Values.image.pullPolicy }} 21 | env: 22 | - name: GROUP_ID 23 | value: {{ .Values.config.groupId | quote}} 24 | - name: CONFIG_STORAGE_TOPIC 25 | value: {{ .Values.config.configStorageTopic }} 26 | - name: OFFSET_STORAGE_TOPIC 27 | value: {{ .Values.config.offsetStorageTopic }} 28 | - name: BOOTSTRAP_SERVERS 29 | value: {{ .Values.config.bootstrapServers }} 30 | {{- range $key, $value := $.Values.env }} 31 | - name: {{ $key }} 32 | value: {{ $value | quote }} 33 | {{- end }} 34 | ports: 35 | - containerPort: {{ .Values.service.internalPort }} 36 | resources: 37 | {{ toYaml .Values.resources | indent 10 }} 38 | -------------------------------------------------------------------------------- /charts/debezium-connect/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | type: {{ .Values.service.type }} 13 | ports: 14 | - port: {{ .Values.service.externalPort }} 15 | targetPort: {{ .Values.service.internalPort }} 16 | protocol: TCP 17 | name: {{ .Values.service.name }} 18 | selector: 19 | app: {{ template "fullname" . }} 20 | -------------------------------------------------------------------------------- /charts/debezium-connect/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for debezium-connect image 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: debezium/connect 7 | tag: 0.5 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: connect 11 | type: ClusterIP 12 | externalPort: 8083 13 | internalPort: 8083 14 | config: 15 | groupId: 1 16 | configStorageTopic: my_connect_configs 17 | offsetStorageTopic: my_connect_offsets 18 | bootstrapServers: kafka.kubeless:9092 19 | #resources: 20 | # limits: 21 | # cpu: 100m 22 | # memory: 512Mi 23 | # requests: 24 | # cpu: 100m 25 | # memory: 512Mi 26 | -------------------------------------------------------------------------------- /charts/debezium-mysql/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/debezium-mysql/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: MySQL server with an example database by Debezium 2 | engine: gotpl 3 | home: https://www.mysql.com/ 4 | keywords: 5 | - mysql 6 | - debezium 7 | maintainers: 8 | - email: containers@bitnami.com 9 | name: Bitnami 10 | name: debezium-mysql 11 | version: 0.1.0 12 | -------------------------------------------------------------------------------- /charts/debezium-mysql/README.md: -------------------------------------------------------------------------------- 1 | Debezium MySQL 2 | ===== 3 | 4 | [Debezium MySQL](http://debezium.io/docs/tutorial/) is a MySQL server with a example database. 5 | 6 | Introduction 7 | ------------ 8 | 9 | This chart bootstraps a MySQL deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. 10 | 11 | Prerequisites 12 | ------------- 13 | 14 | - Kubernetes 1.4+ with Beta APIs enabled for default standalone mode. 15 | - PV provisioner support in the underlying infrastructure. 16 | 17 | Installing the Chart 18 | -------------------- 19 | 20 | Install this chart using: 21 | 22 | ```bash 23 | $ helm repo add kubeless-functions-charts https://kubeless-functions-charts.storage.googleapis.com 24 | $ helm install kubeless-functions-charts/debezium-mysql 25 | ``` 26 | 27 | The command deploys Kafka-Connect on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. 28 | 29 | ### Release name 30 | 31 | An instance of a chart running in a Kubernetes cluster is called a release. Each release is identified by a unique name within the cluster. Helm automatically assigns a unique release name after installing the chart. You can also set your preferred name by: 32 | 33 | ```bash 34 | $ helm install --name my-release kubeless-functions-charts/debezium-mysql 35 | ``` 36 | 37 | ### Updating Kafka-Connect configuration via Helm 38 | 39 | [ConfigMap](https://kubernetes.io/docs/user-guide/configmap/) allows injecting containers with configuration data even while a Helm release is deployed. 40 | 41 | To update your Kafka-Connect server configuration while it is deployed in a release, you need to 42 | 43 | 1. Check all the configurable values in the Kafka-Connect chart using `helm inspect values kubeless-functions-charts/kafka-connect`. 44 | 2. Override the `config` settings in a YAML formatted file, and then pass that file like this `helm upgrade -f config.yaml kubeless-functions-charts/kafka-connect`. 45 | 3. Restart the Kafka-Connect server(s) for the changes to take effect. 46 | 47 | You can also check the history of upgrades to a release using `helm history my-release`. Replace `my-release` with the actual release name. 48 | 49 | Uninstalling the Chart 50 | ---------------------- 51 | 52 | Assuming your release is named as `my-release`, delete it using the command: 53 | 54 | ```bash 55 | $ helm delete my-release 56 | ``` 57 | 58 | The command removes all the Kubernetes components associated with the chart and deletes the release. 59 | 60 | Configuration 61 | ------------- 62 | 63 | The following tables lists the configurable parameters of the Kafka-Connect chart and their default values. 64 | 65 | | Parameter | Description | Default | 66 | |----------------------------|-------------------------------------|---------------------------------------------------------| 67 | | `image.repository` | Kafka-Connect image name | `debezium/example-mysql` | 68 | | `image.tag` | Kafka-Connect image tag. | `0.5` | 69 | | `image.pullPolicy` | Image pull policy | `IfNotPresent` | 70 | | `service.name` | Kubernetes service name | `mysql` | 71 | | `service.type` | Kubernetes service type | `ClusterIP` | 72 | | `service.internalPort` | Kubernetes service internal port | `3306` | 73 | | `service.externalPort` | Kubernetes service externam port | `3306` | 74 | | `config.mysqlRootPassword` | MySQL server root password | `debezium` | 75 | | `config.mysqlUser` | MySQL server user | `mysqlUser` | 76 | | `config.mysqlPassword` | MySQL server password | `mysqlpw` | 77 | | `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | 78 | 79 | You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 80 | 81 | ```bash 82 | $ helm install --name my-release \ 83 | --set config.mysqlRootPassword=rootpassword \ 84 | kubeless-functions-charts/debezium-mysql 85 | ``` 86 | Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example, 87 | 88 | ```bash 89 | $ helm install --name my-release -f values.yaml kubeless-functions-charts/debezium-mysql 90 | ``` 91 | 92 | > **Tip**: You can use the default [values.yaml](values.yaml) 93 | -------------------------------------------------------------------------------- /charts/debezium-mysql/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if contains "NodePort" .Values.service.type }} 3 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) 4 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 5 | echo http://$NODE_IP:$NODE_PORT/login 6 | {{- else if contains "LoadBalancer" .Values.service.type }} 7 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 8 | You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' 9 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 10 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 11 | {{- else if contains "ClusterIP" .Values.service.type }} 12 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "fullname" . }}" -o jsonpath="{.items[0].metadata.name}") 13 | echo "Visit http://127.0.0.1:8080 to use your application" 14 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /charts/debezium-mysql/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/debezium-mysql/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "fullname" . }} 16 | spec: 17 | containers: 18 | - name: {{ template "fullname" . }} 19 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 20 | imagePullPolicy: {{ .Values.image.pullPolicy }} 21 | env: 22 | - name: MYSQL_ROOT_PASSWORD 23 | value: {{ .Values.config.mysqlRootPassword }} 24 | - name: MYSQL_USER 25 | value: {{ .Values.config.mysqlUser }} 26 | - name: MYSQL_PASSWORD 27 | value: {{ .Values.config.mysqlPassword }} 28 | ports: 29 | - containerPort: {{ .Values.service.internalPort }} 30 | resources: 31 | {{ toYaml .Values.resources | indent 10 }} 32 | -------------------------------------------------------------------------------- /charts/debezium-mysql/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | type: {{ .Values.service.type }} 13 | ports: 14 | - port: {{ .Values.service.externalPort }} 15 | targetPort: {{ .Values.service.internalPort }} 16 | protocol: TCP 17 | name: {{ .Values.service.name }} 18 | selector: 19 | app: {{ template "fullname" . }} 20 | -------------------------------------------------------------------------------- /charts/debezium-mysql/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for debezium mysql example. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: debezium/example-mysql 7 | tag: 0.5 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: mysql 11 | type: ClusterIP 12 | externalPort: 3306 13 | internalPort: 3306 14 | 15 | config: 16 | mysqlRootPassword: debezium 17 | mysqlUser: mysqluser 18 | mysqlPassword: mysqlpw 19 | #resources: 20 | # limits: 21 | # cpu: 100m 22 | # memory: 512Mi 23 | # requests: 24 | # cpu: 100m 25 | # memory: 512Mi 26 | -------------------------------------------------------------------------------- /charts/minio/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/minio/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: Distributed object storage server built for cloud applications and devops. 3 | home: https://minio.io 4 | icon: https://www.minio.io/logo/img/logo-dark.svg 5 | keywords: 6 | - storage 7 | - object-storage 8 | - S3 9 | maintainers: 10 | - email: hello@acale.ph 11 | name: Acaleph 12 | - email: hello@minio.io 13 | name: Minio 14 | name: minio 15 | sources: 16 | - https://github.com/minio/minio 17 | version: 0.1.0 18 | -------------------------------------------------------------------------------- /charts/minio/README.md: -------------------------------------------------------------------------------- 1 | Minio 2 | ===== 3 | 4 | [Minio](https://minio.io) is a lightweight, AWS S3 compatible object storage server. It is best suited for storing unstructured data such as photos, videos, log files, backups, VM and container images. Size of an object can range from a few KBs to a maximum of 5TB. Minio server is light enough to be bundled with the application stack, similar to NodeJS, Redis and MySQL. 5 | 6 | Minio supports [distributed mode](https://docs.minio.io/docs/distributed-minio-quickstart-guide). In distributed mode, you can pool multiple drives (even on different machines) into a single object storage server. 7 | 8 | Introduction 9 | ------------ 10 | 11 | This chart bootstraps Minio deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. 12 | 13 | Prerequisites 14 | ------------- 15 | 16 | - Kubernetes 1.4+ with Beta APIs enabled for default standalone mode. 17 | - Kubernetes 1.5+ with Beta APIs enabled to run Minio in [distributed mode](#distributed-minio). 18 | - PV provisioner support in the underlying infrastructure. 19 | 20 | Installing the Chart 21 | -------------------- 22 | 23 | Install this chart using: 24 | 25 | ```bash 26 | $ helm install stable/minio 27 | ``` 28 | 29 | The command deploys Minio on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. 30 | 31 | ### Release name 32 | 33 | An instance of a chart running in a Kubernetes cluster is called a release. Each release is identified by a unique name within the cluster. Helm automatically assigns a unique release name after installing the chart. You can also set your preferred name by: 34 | 35 | ```bash 36 | $ helm install --name my-release stable/minio 37 | ``` 38 | 39 | ### Access and Secret keys 40 | 41 | By default a pre-generated access and secret key will be used. To override the default keys, pass the access and secret keys as arguments to helm install. 42 | 43 | ```bash 44 | $ helm install --set accessKey=myaccesskey,secretKey=mysecretkey \ 45 | stable/minio 46 | ``` 47 | ### Updating Minio configuration via Helm 48 | 49 | [ConfigMap](https://kubernetes.io/docs/user-guide/configmap/) allows injecting containers with configuration data even while a Helm release is deployed. 50 | 51 | To update your Minio server configuration while it is deployed in a release, you need to 52 | 53 | 1. Check all the configurable values in the Minio chart using `helm inspect values stable/minio`. 54 | 2. Override the `minio_server_config` settings in a YAML formatted file, and then pass that file like this `helm upgrade -f config.yaml stable/minio`. 55 | 3. Restart the Minio server(s) for the changes to take effect. 56 | 57 | You can also check the history of upgrades to a release using `helm history my-release`. Replace `my-release` with the actual release name. 58 | 59 | Uninstalling the Chart 60 | ---------------------- 61 | 62 | Assuming your release is named as `my-release`, delete it using the command: 63 | 64 | ```bash 65 | $ helm delete my-release 66 | ``` 67 | 68 | The command removes all the Kubernetes components associated with the chart and deletes the release. 69 | 70 | Configuration 71 | ------------- 72 | 73 | The following tables lists the configurable parameters of the Minio chart and their default values. 74 | 75 | | Parameter | Description | Default | 76 | |----------------------------|-------------------------------------|---------------------------------------------------------| 77 | | `image` | Minio image name | `minio/minio` | 78 | | `imageTag` | Minio image tag. Possible values listed [here](https://hub.docker.com/r/minio/minio/tags/).| `RELEASE.2017-03-16T21-50-32Z`| 79 | | `imagePullPolicy` | Image pull policy | `Always` | 80 | | `mode` | Minio server mode (`standalone`, `shared` or `distributed`)| `standalone` | 81 | | `replicas` | Number of nodes (applicable only for Minio distributed mode). Should be 4 <= x <= 16 | `4` | 82 | | `accessKey` | Default access key (5 to 20 characters) | `AKIAIOSFODNN7EXAMPLE` | 83 | | `secretKey` | Default secret key (8 to 40 characters) | `wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY` | 84 | | `configPath` | Default config file location | `~/.minio` | 85 | | `mountPath` | Default mount location for persistent drive| `/export` | 86 | | `serviceType` | Kubernetes service type | `LoadBalancer` | 87 | | `servicePort` | Kubernetes port where service is exposed| `9000` | 88 | | `persistence.enabled` | Use persistent volume to store data | `true` | 89 | | `persistence.size` | Size of persistent volume claim | `10Gi` | 90 | | `persistence.storageClass` | Type of persistent volume claim | `generic` | 91 | | `persistence.accessMode` | ReadWriteOnce or ReadOnly | `ReadWriteOnce` | 92 | | `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | 93 | 94 | Some of the parameters above map to the env variables defined in the [Minio DockerHub image](https://hub.docker.com/r/minio/minio/). 95 | 96 | You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 97 | 98 | ```bash 99 | $ helm install --name my-release \ 100 | --set persistence.size=100Gi \ 101 | stable/minio 102 | ``` 103 | 104 | The above command deploys Minio server with a 100Gi backing persistent volume. 105 | 106 | Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example, 107 | 108 | ```bash 109 | $ helm install --name my-release -f values.yaml stable/minio 110 | ``` 111 | 112 | > **Tip**: You can use the default [values.yaml](values.yaml) 113 | 114 | Distributed Minio 115 | ----------- 116 | 117 | This chart provisions a Minio server in standalone mode, by default. To provision Minio server in [distributed mode](https://docs.minio.io/docs/distributed-minio-quickstart-guide), set the `mode` field to `distributed`, 118 | 119 | ```bash 120 | $ helm install --set mode=distributed stable/minio 121 | ``` 122 | 123 | This provisions Minio server in distributed mode with 4 nodes. To change the number of nodes in your distributed Minio server, set the `replicas` field, 124 | 125 | ```bash 126 | $ helm install --set mode=distributed,replicas=8 stable/minio 127 | ``` 128 | 129 | This provisions Minio server in distributed mode with 8 nodes. Note that the `replicas` value should be an integer between 4 and 16 (inclusive). 130 | 131 | ### StatefulSet [limitations](http://kubernetes.io/docs/concepts/abstractions/controllers/statefulsets/#limitations) applicable to distributed Minio 132 | 133 | 1. StatefulSets need persistent storage, so the `persistence.enabled` flag is ignored when `mode` is set to `distributed`. 134 | 2. When uninstalling a distributed Minio release, you'll need to manually delete volumes associated with the StatefulSet. 135 | 136 | Shared Minio 137 | ----------- 138 | 139 | ### Prerequisites 140 | 141 | Minio shared mode deployment creates multiple Minio server instances backed by single PV in `ReadWriteMany` mode. Currently few [Kubernetes volume plugins](https://kubernetes.io/docs/user-guide/persistent-volumes/#access-modes) support `ReadWriteMany` mode. To deploy Minio shared mode you'll need to have a Persistent Volume running with one of the supported volume plugins. [This document](https://kubernetes.io/docs/user-guide/volumes/#nfs) 142 | outlines steps to create a NFS PV in Kubernetes cluster. 143 | 144 | ### Provision Shared Minio instances 145 | 146 | To provision Minio servers in [shared mode](https://github.com/minio/minio/blob/master/docs/shared-backend/README.md), set the `mode` field to `shared`, 147 | 148 | ```bash 149 | $ helm install --set mode=shared stable/minio 150 | ``` 151 | 152 | This provisions 4 Minio server nodes backed by single storage. To change the number of nodes in your shared Minio deployment, set the `replicas` field, 153 | 154 | ```bash 155 | $ helm install --set mode=shared,replicas=8 stable/minio 156 | ``` 157 | 158 | This provisions Minio server in shared mode with 8 nodes. 159 | 160 | Persistence 161 | ----------- 162 | 163 | This chart provisions a PersistentVolumeClaim and mounts corresponding persistent volume to default location `/export`. You'll need physical storage available in the Kubernetes cluster for this to work. If you'd rather use `emptyDir`, disable PersistentVolumeClaim by: 164 | 165 | ```bash 166 | $ helm install --set persistence.enabled=false stable/minio 167 | ``` 168 | 169 | > *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* 170 | -------------------------------------------------------------------------------- /charts/minio/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.serviceType "ClusterIP" }} 2 | Minio can be accessed via port {{ .Values.servicePort }} on the following DNS name from within your cluster: 3 | {{ template "fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local 4 | 5 | To access Minio from localhost, run the below commands: 6 | 7 | 1. export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "fullname" . }}" -o jsonpath="{.items[0].metadata.name}") 8 | 9 | 2. kubectl port-forward $POD_NAME 9000 --namespace {{ .Release.Namespace }} 10 | 11 | Read more about port forwarding here: http://kubernetes.io/docs/user-guide/kubectl/kubectl_port-forward/ 12 | 13 | You can now access Minio server on http://localhost:9000. Follow the below steps to connect to Minio server with mc client: 14 | 15 | 1. Download the Minio mc client - https://docs.minio.io/docs/minio-client-quickstart-guide 16 | 17 | 2. mc config host add {{ template "fullname" . }}-local http://localhost:9000 {{ .Values.accessKey }} {{ .Values.secretKey }} S3v4 18 | 19 | 3. mc ls {{ template "fullname" . }}-local 20 | 21 | Alternately, you can use your browser or the Minio SDK to access the server - https://docs.minio.io/categories/17 22 | {{- end }} 23 | {{- if eq .Values.serviceType "LoadBalancer" }} 24 | Minio can be accessed via port {{ .Values.servicePort }} on an external IP address. Get the service external IP address by: 25 | kubectl get svc --namespace {{ .Release.Namespace }} -l app={{ template "fullname" . }} 26 | 27 | Note that the public IP may take a couple of minutes to be available. 28 | 29 | You can now access Minio server on http://:9000. Follow the below steps to connect to Minio server with mc client: 30 | 31 | 1. Download the Minio mc client - https://docs.minio.io/docs/minio-client-quickstart-guide 32 | 33 | 2. mc config host add {{ template "fullname" . }}-local http://:{{ .Values.servicePort }} {{ .Values.accessKey }} {{ .Values.secretKey }} S3v4 34 | 35 | 3. mc ls {{ template "fullname" . }}-local 36 | 37 | Alternately, you can use your browser or the Minio SDK to access the server - https://docs.minio.io/categories/17 38 | {{- end }} 39 | -------------------------------------------------------------------------------- /charts/minio/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/minio/templates/minio_deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.mode "standalone" "shared" }} 2 | apiVersion: extensions/v1beta1 3 | kind: Deployment 4 | metadata: 5 | name: {{ template "fullname" . }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | {{- if eq .Values.mode "shared" }} 13 | replicas: {{ .Values.replicas }} 14 | {{- end }} 15 | selector: 16 | matchLabels: 17 | app: {{ template "fullname" . }} 18 | template: 19 | metadata: 20 | name: {{ template "fullname" . }} 21 | labels: 22 | app: {{ template "fullname" . }} 23 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 24 | release: "{{ .Release.Name }}" 25 | heritage: "{{ .Release.Service }}" 26 | spec: 27 | volumes: 28 | - name: export 29 | {{- if .Values.persistence.enabled }} 30 | persistentVolumeClaim: 31 | claimName: {{ template "fullname" . }} 32 | {{- else }} 33 | emptyDir: {} 34 | {{- end }} 35 | - name: minio-server-config 36 | configMap: 37 | name: {{ template "fullname" . }}-config-cm 38 | - name: minio-user 39 | secret: 40 | secretName: {{ template "fullname" . }}-user 41 | containers: 42 | - name: minio 43 | image: {{ .Values.image }}:{{ .Values.imageTag }} 44 | imagePullPolicy: {{ .Values.imagePullPolicy }} 45 | command: ["minio"] 46 | {{- if .Values.configPath }} 47 | args: ["-C", "{{ .Values.configPath }}", "server", "{{ .Values.mountPath }}"] 48 | {{- else }} 49 | args: ["server", "{{ .Values.mountPath }}"] 50 | {{- end }} 51 | volumeMounts: 52 | - name: export 53 | mountPath: {{ .Values.mountPath }} 54 | - name: minio-server-config 55 | mountPath: {{ default "/root/.minio/" .Values.configPath | quote }} 56 | ports: 57 | - name: service 58 | containerPort: 9000 59 | env: 60 | - name: MINIO_ACCESS_KEY 61 | valueFrom: 62 | secretKeyRef: 63 | name: {{ template "fullname" . }}-user 64 | key: accesskey 65 | - name: MINIO_SECRET_KEY 66 | valueFrom: 67 | secretKeyRef: 68 | name: {{ template "fullname" . }}-user 69 | key: secretkey 70 | livenessProbe: 71 | tcpSocket: 72 | port: 9000 73 | timeoutSeconds: 1 74 | resources: 75 | {{ toYaml .Values.resources | indent 12 }} 76 | {{- end }} 77 | -------------------------------------------------------------------------------- /charts/minio/templates/minio_distributed_configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.mode "distributed" }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ template "fullname" . }}-cm 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | {{ $nodeCount := .Values.replicas | int }} 12 | data: 13 | start.sh: | 14 | #!/bin/sh 15 | {{- if .Values.configPath }} 16 | minio -C {{ .Values.configPath }} server \ 17 | {{- else }} 18 | minio server \ 19 | {{- end }} 20 | {{- range $i := until $nodeCount }} 21 | http://{{ template "fullname" $ }}-{{$i}}.{{ template "fullname" $ }}.{{ $.Release.Namespace }}.svc.cluster.local{{ $.Values.mountPath }} \ 22 | {{- end }} 23 | {{- end }} 24 | -------------------------------------------------------------------------------- /charts/minio/templates/minio_pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.mode "standalone" "shared" }} 2 | {{- if .Values.persistence.enabled }} 3 | kind: PersistentVolumeClaim 4 | apiVersion: v1 5 | metadata: 6 | name: {{ template "fullname" . }} 7 | annotations: 8 | {{- if .Values.persistence.storageClass }} 9 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} 10 | {{- else }} 11 | volume.alpha.kubernetes.io/storage-class: default 12 | {{- end }} 13 | spec: 14 | accessModes: 15 | {{- if eq .Values.mode "shared" }} 16 | - ReadWriteMany 17 | {{- else }} 18 | - {{ .Values.persistence.accessMode | quote }} 19 | {{- end }} 20 | resources: 21 | requests: 22 | storage: {{ .Values.persistence.size | quote }} 23 | {{- end }} 24 | {{- end }} 25 | -------------------------------------------------------------------------------- /charts/minio/templates/minio_secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ template "fullname" . }}-user 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | type: Opaque 11 | data: 12 | accesskey: {{ .Values.accessKey | b64enc }} 13 | secretkey: {{ .Values.secretKey | b64enc }} 14 | -------------------------------------------------------------------------------- /charts/minio/templates/minio_statefulset.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.mode "distributed" }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "fullname" . }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | clusterIP: None 13 | ports: 14 | - name: service 15 | port: 9000 16 | targetPort: {{ .Values.servicePort }} 17 | protocol: TCP 18 | selector: 19 | app: {{ template "fullname" . }} 20 | --- 21 | apiVersion: apps/v1beta1 22 | kind: StatefulSet 23 | metadata: 24 | name: {{ template "fullname" . }} 25 | labels: 26 | app: {{ template "fullname" . }} 27 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 28 | release: "{{ .Release.Name }}" 29 | heritage: "{{ .Release.Service }}" 30 | spec: 31 | serviceName: {{ template "fullname" . }} 32 | replicas: {{ .Values.replicas }} 33 | selector: 34 | matchLabels: 35 | app: {{ template "fullname" . }} 36 | template: 37 | metadata: 38 | name: {{ template "fullname" . }} 39 | labels: 40 | app: {{ template "fullname" . }} 41 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 42 | release: "{{ .Release.Name }}" 43 | heritage: "{{ .Release.Service }}" 44 | spec: 45 | volumes: 46 | - name: minio-user 47 | secret: 48 | secretName: {{ template "fullname" . }}-user 49 | - name: minio-configmap 50 | configMap: 51 | name: {{ template "fullname" . }}-cm 52 | - name: minio-server-config 53 | configMap: 54 | name: {{ template "fullname" . }}-config-cm 55 | containers: 56 | - name: minio 57 | image: {{ .Values.image }}:{{ .Values.imageTag }} 58 | imagePullPolicy: {{ .Values.imagePullPolicy }} 59 | command: 60 | - /bin/sh 61 | - /go/bin/start.sh 62 | volumeMounts: 63 | - name: export 64 | mountPath: {{ .Values.mountPath }} 65 | - name: minio-server-config 66 | mountPath: {{ default "/root/.minio/" .Values.configPath | quote }} 67 | - name: minio-configmap 68 | mountPath: /go/bin/start.sh 69 | subPath: start.sh 70 | ports: 71 | - name: service 72 | containerPort: 9000 73 | env: 74 | - name: MINIO_ACCESS_KEY 75 | valueFrom: 76 | secretKeyRef: 77 | name: {{ template "fullname" . }}-user 78 | key: accesskey 79 | - name: MINIO_SECRET_KEY 80 | valueFrom: 81 | secretKeyRef: 82 | name: {{ template "fullname" . }}-user 83 | key: secretkey 84 | resources: 85 | {{ toYaml .Values.resources | indent 12 }} 86 | volumeClaimTemplates: 87 | - metadata: 88 | name: export 89 | annotations: 90 | {{- if .Values.persistence.storageClass }} 91 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass }} 92 | {{- else }} 93 | volume.alpha.kubernetes.io/storage-class: default 94 | {{- end }} 95 | spec: 96 | accessModes: [ {{ .Values.persistence.accessMode | quote }} ] 97 | resources: 98 | requests: 99 | storage: {{ .Values.persistence.size }} 100 | {{- end }} 101 | -------------------------------------------------------------------------------- /charts/minio/templates/minio_svc.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: {{ template "fullname" . }}-svc 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | spec: 11 | type: {{ .Values.serviceType }} 12 | {{- if eq .Values.serviceType "LoadBalancer" }} 13 | loadBalancerIP: {{ default "" .Values.minioLoadBalancerIP }} 14 | {{- end }} 15 | selector: 16 | app: {{ template "fullname" . }} 17 | ports: 18 | - name: service 19 | port: 9000 20 | targetPort: {{ .Values.servicePort }} 21 | protocol: TCP 22 | -------------------------------------------------------------------------------- /charts/minio/templates/minioconfig_configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ template "fullname" . }}-config-cm 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | data: 11 | config.json: |- 12 | { 13 | "version": "13", 14 | "credential": { 15 | "accessKey": {{ .Values.accessKey | quote }}, 16 | "secretKey": {{ .Values.secretKey | quote }} 17 | }, 18 | "region": "us-east-1", 19 | "logger": { 20 | "console": { 21 | "enable": true, 22 | "level": "fatal" 23 | }, 24 | "file": { 25 | "enable": false, 26 | "fileName": "", 27 | "level": "" 28 | } 29 | }, 30 | "notify": { 31 | "amqp": { 32 | "1": { 33 | "enable": {{ .Values.minioConfig.aqmp.enable }}, 34 | "url": {{ .Values.minioConfig.aqmp.url | quote }}, 35 | "exchange": {{ .Values.minioConfig.aqmp.exchange | quote }}, 36 | "routingKey": {{ .Values.minioConfig.aqmp.routingKey | quote }}, 37 | "exchangeType": {{ .Values.minioConfig.aqmp.exchangeType | quote }}, 38 | "mandatory": {{ .Values.minioConfig.aqmp.mandatory }}, 39 | "immediate": {{ .Values.minioConfig.aqmp.immediate }}, 40 | "durable": {{ .Values.minioConfig.aqmp.durable }}, 41 | "internal": {{ .Values.minioConfig.aqmp.internal }}, 42 | "noWait": {{ .Values.minioConfig.aqmp.noWait }}, 43 | "autoDeleted": {{ .Values.minioConfig.aqmp.autoDeleted }} 44 | } 45 | }, 46 | "nats": { 47 | "1": { 48 | "enable": {{ .Values.minioConfig.nats.enable }}, 49 | "address": {{ .Values.minioConfig.nats.address | quote }}, 50 | "subject": {{ .Values.minioConfig.nats.subject | quote }}, 51 | "username": {{ .Values.minioConfig.nats.username | quote }}, 52 | "password": {{ .Values.minioConfig.nats.password | quote }}, 53 | "token": {{ .Values.minioConfig.nats.token | quote }}, 54 | "secure": {{ .Values.minioConfig.nats.secure }}, 55 | "pingInterval": {{ .Values.minioConfig.nats.pingInterval | int64 }}, 56 | "streaming": { 57 | "enable": {{ .Values.minioConfig.nats.enableStreaming }}, 58 | "clusterID": {{ .Values.minioConfig.nats.clusterID | quote }}, 59 | "clientID": {{ .Values.minioConfig.nats.clientID | quote }}, 60 | "async": {{ .Values.minioConfig.nats.async }}, 61 | "maxPubAcksInflight": {{ .Values.minioConfig.nats.maxPubAcksInflight | int }} 62 | } 63 | } 64 | }, 65 | "elasticsearch": { 66 | "1": { 67 | "enable": {{ .Values.minioConfig.elasticsearch.enable }}, 68 | "url": {{ .Values.minioConfig.elasticsearch.url | quote }}, 69 | "index": {{ .Values.minioConfig.elasticsearch.index | quote }} 70 | } 71 | }, 72 | "redis": { 73 | "1": { 74 | "enable": {{ .Values.minioConfig.redis.enable }}, 75 | "address": {{ .Values.minioConfig.redis.address | quote }}, 76 | "password": {{ .Values.minioConfig.redis.password | quote }}, 77 | "key": {{ .Values.minioConfig.redis.key | quote }} 78 | } 79 | }, 80 | "postgresql": { 81 | "1": { 82 | "enable": {{ .Values.minioConfig.postgresql.enable }}, 83 | "connectionString": {{ .Values.minioConfig.postgresql.connectionString | quote }}, 84 | "table": {{ .Values.minioConfig.postgresql.table | quote }}, 85 | "host": {{ .Values.minioConfig.postgresql.host | quote }}, 86 | "port": {{ .Values.minioConfig.postgresql.port | quote }}, 87 | "user": {{ .Values.minioConfig.postgresql.user | quote }}, 88 | "password": {{ .Values.minioConfig.postgresql.password | quote }}, 89 | "database": {{ .Values.minioConfig.postgresql.database | quote }} 90 | } 91 | }, 92 | "kafka": { 93 | "1": { 94 | "enable": {{ .Values.minioConfig.kafka.enable }}, 95 | "brokers": {{ .Values.minioConfig.kafka.brokers }}, 96 | "topic": {{ .Values.minioConfig.kafka.topic | quote }} 97 | } 98 | }, 99 | "webhook": { 100 | "1": { 101 | "enable": {{ .Values.minioConfig.webhook.enable }}, 102 | "endpoint": {{ .Values.minioConfig.webhook.endpoint | quote }} 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /charts/minio/values.yaml: -------------------------------------------------------------------------------- 1 | ## Set default image, imageTag, and imagePullPolicy. mode is used to indicate the 2 | ## minio server mode, i.e. standalone or distributed. 3 | ## Distributed Minio ref: https://docs.minio.io/docs/distributed-minio-quickstart-guide 4 | ## 5 | image: "minio/minio" 6 | imageTag: "RELEASE.2017-08-05T00-00-53Z" 7 | imagePullPolicy: "Always" 8 | mode: "standalone" 9 | 10 | ## Set default accesskey, secretkey, Minio config file path, volume mount path and 11 | ## number of nodes (only used for Minio distributed mode) 12 | ## Distributed Minio ref: https://docs.minio.io/docs/distributed-minio-quickstart-guide 13 | ## 14 | accessKey: "foobar" 15 | secretKey: "foobarfoo" 16 | configPath: "" 17 | mountPath: "/export" 18 | replicas: 4 19 | 20 | ## loadBalancerIP for the Minio Service (optional, cloud specific) 21 | ## ref: http://kubernetes.io/docs/user-guide/services/#type-loadbalancer 22 | ## 23 | # minioLoadBalancerIP: 24 | 25 | ## Enable persistence using Persistent Volume Claims 26 | ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ 27 | ## 28 | persistence: 29 | enabled: true 30 | 31 | ## If defined, volume.beta.kubernetes.io/storage-class: 32 | ## Default: volume.alpha.kubernetes.io/storage-class: default 33 | ## 34 | # storageClass: 35 | accessMode: ReadWriteOnce 36 | size: 10Gi 37 | 38 | ## Expose the Minio service to be accessed from outside the cluster (LoadBalancer service). 39 | ## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. 40 | ## ref: http://kubernetes.io/docs/user-guide/services/ 41 | ## 42 | serviceType: LoadBalancer 43 | servicePort: 9000 44 | 45 | ## Configure resource requests and limits 46 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ 47 | ## 48 | resources: 49 | requests: 50 | memory: 256Mi 51 | cpu: 250m 52 | 53 | ## Below settings can be used to setup event notifications as explained here. 54 | ## https://docs.minio.io/docs/minio-bucket-notification-guide 55 | ## 56 | minioConfig: 57 | aqmp: 58 | enable: false 59 | url: "" 60 | exchange: "" 61 | routingKey: "" 62 | exchangeType: "" 63 | mandatory: false 64 | immediate: false 65 | durable: false 66 | internal: false 67 | noWait: false 68 | autoDeleted: false 69 | nats: 70 | enable: false 71 | address: "" 72 | subject: "" 73 | username: "" 74 | password: "" 75 | token: "" 76 | secure: false 77 | pingInterval: 0 78 | enableStreaming: false 79 | clusterID: "" 80 | clientID: "" 81 | async: false 82 | maxPubAcksInflight: 0 83 | elasticsearch: 84 | enable: false 85 | url: "" 86 | index: "" 87 | redis: 88 | enable: false 89 | address: "" 90 | password: "" 91 | key: "" 92 | postgresql: 93 | enable: false 94 | connectionString: "" 95 | table: "" 96 | host: "" 97 | port: "" 98 | user: "" 99 | password: "" 100 | database: "" 101 | kafka: 102 | enable: true 103 | brokers: "[\"kafka.kubeless:9092\"]" 104 | topic: "s3" 105 | webhook: 106 | enable: false 107 | endpoint: "" 108 | -------------------------------------------------------------------------------- /charts/mongodb/.helmignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /charts/mongodb/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: NoSQL document-oriented database that stores JSON-like documents with 2 | dynamic schemas, simplifying the integration of data in content-driven applications. 3 | engine: gotpl 4 | home: https://mongodb.org 5 | icon: https://bitnami.com/assets/stacks/mongodb/img/mongodb-stack-220x234.png 6 | keywords: 7 | - mongodb 8 | - database 9 | - nosql 10 | maintainers: 11 | - email: containers@bitnami.com 12 | name: Bitnami 13 | name: mongodb 14 | sources: 15 | - https://github.com/bitnami/bitnami-docker-mongodb 16 | version: 0.4.9 17 | -------------------------------------------------------------------------------- /charts/mongodb/README.md: -------------------------------------------------------------------------------- 1 | # MongoDB 2 | 3 | [MongoDB](https://www.mongodb.com/) is a cross-platform document-oriented database. Classified as a NoSQL database, MongoDB eschews the traditional table-based relational database structure in favor of JSON-like documents with dynamic schemas, making the integration of data in certain types of applications easier and faster. 4 | 5 | ## TL;DR; 6 | 7 | ```bash 8 | $ helm install stable/mongodb 9 | ``` 10 | 11 | ## Introduction 12 | 13 | This chart bootstraps a [MongoDB](https://github.com/bitnami/bitnami-docker-mongodb) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. 14 | 15 | ## Prerequisites 16 | 17 | - Kubernetes 1.4+ with Beta APIs enabled 18 | - PV provisioner support in the underlying infrastructure 19 | 20 | ## Installing the Chart 21 | 22 | To install the chart with the release name `my-release`: 23 | 24 | ```bash 25 | $ helm install --name my-release stable/mongodb 26 | ``` 27 | 28 | The command deploys MongoDB on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. 29 | 30 | > **Tip**: List all releases using `helm list` 31 | 32 | ## Uninstalling the Chart 33 | 34 | To uninstall/delete the `my-release` deployment: 35 | 36 | ```bash 37 | $ helm delete my-release 38 | ``` 39 | 40 | The command removes all the Kubernetes components associated with the chart and deletes the release. 41 | 42 | ## Configuration 43 | 44 | The following tables lists the configurable parameters of the MongoDB chart and their default values. 45 | 46 | | Parameter | Description | Default | 47 | |----------------------------|-------------------------------------|----------------------------------------------------------| 48 | | `image` | MongoDB image | `bitnami/mongodb:{VERSION}` | 49 | | `imagePullPolicy` | Image pull policy | `Always` if `imageTag` is `latest`, else `IfNotPresent`. | 50 | | `mongodbRootPassword` | MongoDB admin password | `nil` | 51 | | `mongodbUsername` | MongoDB custom user | `nil` | 52 | | `mongodbPassword` | MongoDB custom user password | `nil` | 53 | | `mongodbDatabase` | Database to create | `nil` | 54 | | `persistence.enabled` | Use a PVC to persist data | `true` | 55 | | `persistence.storageClass` | Storage class of backing PVC | `nil` (uses alpha storage class annotation) | 56 | | `persistence.accessMode` | Use volume as ReadOnly or ReadWrite | `ReadWriteOnce` | 57 | | `persistence.size` | Size of data volume | `8Gi` | 58 | 59 | The above parameters map to the env variables defined in [bitnami/mongodb](http://github.com/bitnami/bitnami-docker-mongodb). For more information please refer to the [bitnami/mongodb](http://github.com/bitnami/bitnami-docker-mongodb) image documentation. 60 | 61 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 62 | 63 | ```bash 64 | $ helm install --name my-release \ 65 | --set mongodbRootPassword=secretpassword,mongodbUsername=my-user,mongodbPassword=my-password,mongodbDatabase=my-database \ 66 | stable/mongodb 67 | ``` 68 | 69 | The above command sets the MongoDB `root` account password to `secretpassword`. Additionally it creates a standard database user named `my-user`, with the password `my-password`, who has access to a database named `my-database`. 70 | 71 | Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, 72 | 73 | ```bash 74 | $ helm install --name my-release -f values.yaml stable/mongodb 75 | ``` 76 | 77 | > **Tip**: You can use the default [values.yaml](values.yaml) 78 | 79 | ## Persistence 80 | 81 | The [Bitnami MongoDB](https://github.com/bitnami/bitnami-docker-mongodb) image stores the MongoDB data and configurations at the `/bitnami/mongodb` path of the container. 82 | 83 | The chart mounts a [Persistent Volume](kubernetes.io/docs/user-guide/persistent-volumes/) volume at this location. The volume is created using dynamic volume provisioning. 84 | -------------------------------------------------------------------------------- /charts/mongodb/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | MongoDB can be accessed via port 27017 on the following DNS name from within your cluster: 2 | {{ template "fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local 3 | 4 | To connect to your database run the following command: 5 | 6 | kubectl run {{ template "fullname" . }}-client --rm --tty -i --image bitnami/mongodb --command -- mongo --host {{ template "fullname" . }} {{- if .Values.mongodbRootPassword }} -p {{ .Values.mongodbRootPassword }}{{- end -}} 7 | 8 | -------------------------------------------------------------------------------- /charts/mongodb/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/mongodb/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | spec: 11 | template: 12 | metadata: 13 | labels: 14 | app: {{ template "fullname" . }} 15 | spec: 16 | containers: 17 | - name: {{ template "fullname" . }} 18 | image: "{{ .Values.image }}" 19 | imagePullPolicy: {{ default "" .Values.imagePullPolicy | quote }} 20 | env: 21 | - name: MONGODB_ROOT_PASSWORD 22 | valueFrom: 23 | secretKeyRef: 24 | name: {{ template "fullname" . }} 25 | key: mongodb-root-password 26 | - name: MONGODB_USERNAME 27 | value: {{ default "" .Values.mongodbUsername | quote }} 28 | - name: MONGODB_PASSWORD 29 | valueFrom: 30 | secretKeyRef: 31 | name: {{ template "fullname" . }} 32 | key: mongodb-password 33 | - name: MONGODB_DATABASE 34 | value: {{ default "" .Values.mongodbDatabase | quote }} 35 | ports: 36 | - name: mongodb 37 | containerPort: 27017 38 | livenessProbe: 39 | exec: 40 | command: 41 | - mongo 42 | - --eval 43 | - "db.adminCommand('ping')" 44 | initialDelaySeconds: 30 45 | timeoutSeconds: 5 46 | readinessProbe: 47 | exec: 48 | command: 49 | - mongo 50 | - --eval 51 | - "db.adminCommand('ping')" 52 | initialDelaySeconds: 5 53 | timeoutSeconds: 1 54 | volumeMounts: 55 | - name: data 56 | mountPath: /bitnami/mongodb 57 | resources: 58 | {{ toYaml .Values.resources | indent 10 }} 59 | volumes: 60 | - name: data 61 | {{- if .Values.persistence.enabled }} 62 | persistentVolumeClaim: 63 | claimName: {{ template "fullname" . }} 64 | {{- else }} 65 | emptyDir: {} 66 | {{- end -}} 67 | -------------------------------------------------------------------------------- /charts/mongodb/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.persistence.enabled }} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ template "fullname" . }} 6 | annotations: 7 | {{- if .Values.persistence.storageClass }} 8 | volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} 9 | {{- else }} 10 | volume.alpha.kubernetes.io/storage-class: default 11 | {{- end }} 12 | spec: 13 | accessModes: 14 | - {{ .Values.persistence.accessMode | quote }} 15 | resources: 16 | requests: 17 | storage: {{ .Values.persistence.size | quote }} 18 | {{- end }} 19 | -------------------------------------------------------------------------------- /charts/mongodb/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | type: Opaque 11 | data: 12 | mongodb-root-password: {{ default "" .Values.mongodbRootPassword | b64enc | quote }} 13 | mongodb-password: {{ default "" .Values.mongodbPassword | b64enc | quote }} 14 | -------------------------------------------------------------------------------- /charts/mongodb/templates/svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | spec: 11 | ports: 12 | - name: mongodb 13 | port: 27017 14 | targetPort: mongodb 15 | selector: 16 | app: {{ template "fullname" . }} 17 | -------------------------------------------------------------------------------- /charts/mongodb/values.yaml: -------------------------------------------------------------------------------- 1 | ## Bitnami MongoDB image version 2 | ## ref: https://hub.docker.com/r/bitnami/mongodb/tags/ 3 | ## 4 | image: bitnami/mongodb:3.4.3-r0 5 | 6 | ## Specify a imagePullPolicy 7 | ## 'Always' if imageTag is 'latest', else set to 'IfNotPresent' 8 | ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images 9 | ## 10 | # imagePullPolicy: 11 | 12 | ## MongoDB admin password 13 | ## ref: https://github.com/bitnami/bitnami-docker-mongodb/blob/master/README.md#setting-the-root-password-on-first-run 14 | ## 15 | # mongodbRootPassword: 16 | 17 | ## MongoDB custom user and database 18 | ## ref: https://github.com/bitnami/bitnami-docker-mongodb/blob/master/README.md#creating-a-user-and-database-on-first-run 19 | ## 20 | # mongodbUsername: 21 | # mongodbPassword: 22 | # mongodbDatabase: 23 | 24 | ## Enable persistence using Persistent Volume Claims 25 | ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ 26 | ## 27 | persistence: 28 | enabled: true 29 | ## If defined, volume.beta.kubernetes.io/storage-class: 30 | ## Default: volume.alpha.kubernetes.io/storage-class: default 31 | ## 32 | # storageClass: 33 | accessMode: ReadWriteOnce 34 | size: 8Gi 35 | 36 | ## Configure resource requests and limits 37 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ 38 | ## 39 | resources: 40 | requests: 41 | memory: 256Mi 42 | cpu: 100m 43 | -------------------------------------------------------------------------------- /charts/tika-server/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/tika-server/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: A Apache Tika Server Helm chart for Kubernetes 2 | engine: gotpl 3 | home: https://tika.apache.org/ 4 | icon: http://tika.apache.org/tika.png 5 | keywords: 6 | - tika 7 | - translation 8 | maintainers: 9 | - email: containers@bitnami.com 10 | name: Bitnami 11 | name: tika-server 12 | version: 0.1.0 13 | -------------------------------------------------------------------------------- /charts/tika-server/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if contains "NodePort" .Values.service.type }} 3 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) 4 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 5 | echo http://$NODE_IP:$NODE_PORT/login 6 | {{- else if contains "LoadBalancer" .Values.service.type }} 7 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 8 | You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' 9 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 10 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 11 | {{- else if contains "ClusterIP" .Values.service.type }} 12 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "fullname" . }}" -o jsonpath="{.items[0].metadata.name}") 13 | echo "Visit http://127.0.0.1:8080 to use your application" 14 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /charts/tika-server/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/tika-server/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | app: {{ template "fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "fullname" . }} 16 | spec: 17 | containers: 18 | - name: {{ template "fullname" . }} 19 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 20 | imagePullPolicy: {{ .Values.image.pullPolicy }} 21 | env: 22 | - name: TIKA_VERSION 23 | value: {{ .Values.tika.version | quote }} 24 | - name: TRANSLATOR_GOOGLE_CLIENT_SECRET 25 | value: {{ .Values.tika.translator.google.clientsecret | quote }} 26 | ports: 27 | - containerPort: {{ .Values.service.internalPort }} 28 | livenessProbe: 29 | httpGet: 30 | path: / 31 | port: {{ .Values.service.internalPort }} 32 | initialDelaySeconds: 40 33 | periodSeconds: 5 34 | timeoutSeconds: 5 35 | failureThreshold: 10 36 | readinessProbe: 37 | httpGet: 38 | path: / 39 | port: {{ .Values.service.internalPort }} 40 | initialDelaySeconds: 10 41 | periodSeconds: 5 42 | timeoutSeconds: 1 43 | resources: 44 | {{ toYaml .Values.resources | indent 10 }} 45 | -------------------------------------------------------------------------------- /charts/tika-server/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | type: {{ .Values.service.type }} 13 | ports: 14 | - port: {{ .Values.service.externalPort }} 15 | targetPort: {{ .Values.service.internalPort }} 16 | protocol: TCP 17 | name: {{ .Values.service.name }} 18 | selector: 19 | app: {{ template "fullname" . }} 20 | -------------------------------------------------------------------------------- /charts/tika-server/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for tika-server. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: bitnami/tika-server 7 | tag: 1.14 8 | pullPolicy: IfNotPresent 9 | tika: 10 | version: 1.14 11 | translator: 12 | google: 13 | clientsecret: PUT_YOUR_KEY_HERE 14 | service: 15 | name: tika 16 | type: ClusterIP 17 | externalPort: 80 18 | internalPort: 9998 19 | resources: 20 | limits: 21 | cpu: 100m 22 | memory: 512Mi 23 | requests: 24 | cpu: 100m 25 | memory: 512Mi 26 | 27 | -------------------------------------------------------------------------------- /incubator/controller/Makefile: -------------------------------------------------------------------------------- 1 | controller: 2 | kubeless function deploy controller --trigger-topic k8s --runtime python2.7 --handler ns.handler --from-file ns.py --dependencies requirements.txt 3 | sync: 4 | kubectl run event --image=skippbox/k8s-events:0.10.13 5 | -------------------------------------------------------------------------------- /incubator/controller/README.md: -------------------------------------------------------------------------------- 1 | # [WIP] Prototype function that implements a toy k8s controller 2 | 3 | It detects when a namespace is created and deploys a Nginx deployment in it 4 | 5 | It needs the k8s event to kafka event sync: 6 | https://github.com/kubeless/kubeless/tree/master/docker/event-sources/kubernetes 7 | -------------------------------------------------------------------------------- /incubator/controller/ns.py: -------------------------------------------------------------------------------- 1 | import json 2 | import yaml 3 | 4 | from kubernetes import client, config 5 | 6 | config.load_incluster_config() 7 | 8 | d1=client.ExtensionsV1beta1Api() 9 | 10 | nginx= """ 11 | apiVersion: extensions/v1beta1 12 | kind: Deployment 13 | metadata: 14 | name: nginx-deployment 15 | spec: 16 | replicas: 3 17 | template: 18 | metadata: 19 | labels: 20 | app: nginx 21 | spec: 22 | containers: 23 | - name: nginx 24 | image: nginx:1.7.9 25 | ports: 26 | - containerPort: 80 27 | """ 28 | 29 | deployment = yaml.load(nginx) 30 | 31 | def handler(event, context): 32 | try: 33 | if event['data']['type'] == "ADDED" and event['data']['object']['kind'] == "Namespace": 34 | print "Event: %s %s %s" % (event['data']['type'], event['data']['object']['kind'], 35 | event['data']['object']['metadata']['name']) 36 | res = d1.create_namespaced_deployment( 37 | body=deployment, namespace=event['data']['object']['metadata']['name']) 38 | return str(res) 39 | except Exception as inst: 40 | print type(inst) 41 | print inst 42 | print event.keys() 43 | print type(event) 44 | print str(event) 45 | -------------------------------------------------------------------------------- /incubator/controller/requirements.txt: -------------------------------------------------------------------------------- 1 | kubernetes==2.0.0 2 | -------------------------------------------------------------------------------- /incubator/crypto/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: Get a Crypto currency price 3 | home: https://bitnami.com 4 | keywords: 5 | - cryptocurrency 6 | - crypto 7 | - bitcoin 8 | name: crypto 9 | sources: 10 | - https://github.com/kubeless/functions 11 | version: 0.0.1 12 | -------------------------------------------------------------------------------- /incubator/crypto/README.md: -------------------------------------------------------------------------------- 1 | # Function to get price of Cryptocurrencies 2 | 3 | ``` 4 | kubeless function deploy crypto --from-file crypto.py --handler crypto.handler --runtime python2.7 --dependencies requirements.txt 5 | ``` 6 | 7 | Then call the function, specifying with crypto currency you want to get the price of: 8 | 9 | ``` 10 | kubeless function call crypto --data '{"crypto": "bitcoin"}' 11 | Connecting to function... 12 | Forwarding from 127.0.0.1:30000 -> 8080 13 | Forwarding from [::1]:30000 -> 8080 14 | Handling connection for 30000 15 | 10074.8 16 | ``` 17 | 18 | 19 | -------------------------------------------------------------------------------- /incubator/crypto/crypto.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urlparse 3 | 4 | def handler(event, context): 5 | ticker = event['data']['crypto'] 6 | path = urlparse.urljoin('https://api.coinmarketcap.com/v1/ticker/', ticker) 7 | return requests.get(path).json()[0]['price_usd'] 8 | -------------------------------------------------------------------------------- /incubator/crypto/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | -------------------------------------------------------------------------------- /incubator/crypto/templates/function.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kubeless.io/v1beta1 2 | kind: Function 3 | metadata: 4 | name: crypto 5 | namespace: default 6 | spec: 7 | checksum: sha256:{{ .Files.Get "crypto.py" | sha256sum }} 8 | deps: | 9 | requests 10 | function: | 11 | {{ .Files.Get "crypto.py" | indent 4 }} 12 | handler: crypto.handler 13 | runtime: python2.7 14 | type: HTTP 15 | -------------------------------------------------------------------------------- /incubator/hello-python-with-data/README.md: -------------------------------------------------------------------------------- 1 | # Simple Python function for Kubeless 2 | 3 | Make sure `minikube` and `kubeless` are installed. See the respective installation guides: 4 | * [Minikube](https://github.com/kubernetes/minikube#installation) 5 | * [Kubeless](http://kubeless.io/docs/quick-start/) 6 | 7 | You can deploy the function with kubeless or with the serverless plugin: 8 | 9 | ## Deploy the function with kubeless 10 | 11 | ### 1. Deploy 12 | In order to deploy the function run the following command: 13 | 14 | ```bash 15 | $ kubeless function deploy hello --from-file hellowithdata.py --handler hellowithdata.handler --runtime python2.7 16 | ``` 17 | 18 | You can list the function with `kubeless function ls` and you should see the following: 19 | 20 | ``` 21 | $ kubeless function ls 22 | NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS 23 | hello default hellowithdata.handler python2.7 1/1 READY 24 | ``` 25 | 26 | ### 2. Invoke 27 | You can now call your function: 28 | 29 | ```bash 30 | kubeless function call hello --data '{"name": "Tomas"}' 31 | ``` 32 | 33 | ## Deploy the function with the serverless plugin 34 | 35 | Make sure `serverless` is installed. You can see the installation instructions [here](https://github.com/serverless/serverless#quick-start). 36 | 37 | ### 1. Install Service Dependencies 38 | Run `npm install` in this directory to download the modules from `package.json`. 39 | 40 | ### 2. Deploy 41 | Run `serverless deploy` in order to deploy the function defined in `serverless.yml` 42 | 43 | ```bash 44 | $ serverless deploy 45 | Serverless: Packaging service... 46 | Serverless: Function hellowithdata succesfully deployed 47 | ``` 48 | 49 | ### 3. Invoke deployed function 50 | Run `serverless invoke --function hello --log 51 | 52 | In your terminal window you should see the response from Kubernetes. 53 | 54 | ```$ serverless invoke -f hellowithdata --log --data '{"name":"Bob"}' 55 | Serverless: Calling function: hellowithdata... 56 | -------------------------------------------------------------------- 57 | { name: 'Bob' } 58 | ``` 59 | 60 | **For more information on the Serverless Kubeless plugin, please see the project repository: [https://github.com/serverless/serverless-kubeless](https://github.com/serverless/serverless-kubeless).** 61 | -------------------------------------------------------------------------------- /incubator/hello-python-with-data/hellowithdata.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def handler(event, context): 4 | print(event) 5 | return event['data'] 6 | -------------------------------------------------------------------------------- /incubator/hello-python-with-data/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kubeless-python-simple", 3 | "version": "0.0.1", 4 | "description": "This example demonstrates how to setup a simple Python function with Kubeless", 5 | "dependencies": { 6 | "serverless-kubeless": "^0.4.0" 7 | }, 8 | "main": "handler.py", 9 | "autor": "Bitnami", 10 | "license": "ASL" 11 | } 12 | -------------------------------------------------------------------------------- /incubator/hello-python-with-data/serverless.yml: -------------------------------------------------------------------------------- 1 | service: hello-python-with-data 2 | 3 | provider: 4 | name: kubeless 5 | runtime: python2.7 6 | 7 | plugins: 8 | - serverless-kubeless 9 | 10 | functions: 11 | hellowithdata: 12 | handler: hellowithdata.handler 13 | -------------------------------------------------------------------------------- /incubator/hello-python/README.md: -------------------------------------------------------------------------------- 1 | # Simple Python function for Kubeless 2 | 3 | Make sure `minikube` and `kubeless` are installed. See the respective installation guides: 4 | * [Minikube](https://github.com/kubernetes/minikube#installation) 5 | * [Kubeless](http://kubeless.io/docs/quick-start/) 6 | 7 | You can deploy the function with kubeless or with the serverless plugin: 8 | 9 | ## Deploy the function with kubeless 10 | 11 | ### 1. Deploy 12 | In order to deploy the function run the following command: 13 | 14 | ```bash 15 | $ kubeless function deploy hello --from-file hello.py --handler hello.handler --runtime python2.7 16 | ``` 17 | 18 | You can list the function with `kubeless function ls` and you should see the following: 19 | 20 | ``` 21 | $ kubeless function ls 22 | NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS 23 | hello default hello.handler python2.7 1/1 READY 24 | ``` 25 | 26 | ### 2. Invoke 27 | You can now call your function: 28 | 29 | ```bash 30 | $ kubeless function call hello 31 | Hello World! 32 | ``` 33 | 34 | ## Deploy the function with the serverless plugin 35 | 36 | Make sure `serverless` is installed. You can see the installation instructions [here](https://github.com/serverless/serverless#quick-start). 37 | 38 | ### 1. Install Service Dependencies 39 | Run `npm install` in this directory to download the modules from `package.json`. 40 | 41 | ### 2. Deploy 42 | Run `serverless deploy` in order to deploy the function defined in `serverless.yml` 43 | 44 | ```bash 45 | $ serverless deploy 46 | Serverless: Packaging service... 47 | Serverless: Function hello succesfully deployed 48 | ``` 49 | 50 | ### 3. Invoke deployed function 51 | Run `serverless invoke --function hello --log 52 | 53 | In your terminal window you should see the response from Kubernetes. 54 | 55 | ```bash 56 | $ serverless invoke --function hello --log 57 | Serverless: Calling function: hello... 58 | -------------------------------------------------------------------- 59 | Hello World! 60 | ``` 61 | 62 | **For more information on the Serverless Kubeless plugin, please see the project repository: [https://github.com/serverless/serverless-kubeless](https://github.com/serverless/serverless-kubeless).** 63 | -------------------------------------------------------------------------------- /incubator/hello-python/hello.py: -------------------------------------------------------------------------------- 1 | import json 2 | def handler(event, context): 3 | return "Hello World!" 4 | -------------------------------------------------------------------------------- /incubator/hello-python/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kubeless-python-simple", 3 | "version": "0.0.1", 4 | "description": "This example demonstrates how to setup a simple Python function with Kubeless", 5 | "dependencies": { 6 | "serverless-kubeless": "^0.4.0" 7 | }, 8 | "main": "handler.py", 9 | "autor": "Bitnami", 10 | "license": "ASL" 11 | } 12 | -------------------------------------------------------------------------------- /incubator/hello-python/serverless.yml: -------------------------------------------------------------------------------- 1 | service: hello-python 2 | 3 | provider: 4 | name: kubeless 5 | runtime: python2.7 6 | 7 | plugins: 8 | - serverless-kubeless 9 | 10 | functions: 11 | hello: 12 | handler: hello.handler 13 | -------------------------------------------------------------------------------- /incubator/kafka-connect/README.md: -------------------------------------------------------------------------------- 1 | # Send messages to slack on changes to a mysql table 2 | 3 | Make sure `minikube` and `kubeless` are installed. See the respective installation guides: 4 | * [Minikube](https://github.com/kubernetes/minikube#installation) 5 | * [Kubeless](http://kubeless.io/docs/quick-start/) 6 | 7 | 8 | ## Prepare the environment 9 | 10 | This example uses the Debezium Kafka-Connect image to monitor a MySQL database and send events to a Kafka topic. A kubeless function will consume those events and perform actions. 11 | 12 | ### Add kubeless-functions-charts repository 13 | 14 | ```bash 15 | $ helm repo add kubeless-functions-charts https://kubeless-functions-charts.storage.googleapis.com 16 | ``` 17 | 18 | 19 | ### Deploy Debezium MySQL via Helm 20 | 21 | ```bash 22 | $ helm install --name debezium-mysql kubeless-functions-charts/debezium-mysql --set service.type=NodePort 23 | ``` 24 | 25 | ### Deploy Debezium Kafka-Connect via Helm 26 | 27 | ```bash 28 | $ helm install --name debezium-connect kubeless-functions-charts/debezium-connect --set service.type=NodePort 29 | ``` 30 | 31 | ### Get kafka-connect host and port 32 | 33 | ```bash 34 | $ export KAFKA_CONNECT_HOST=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") 35 | $ export KAFKA_CONNECT_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services debezium-connect-debezium-connect) 36 | ``` 37 | 38 | ### Start connector monitoring 39 | 40 | ```bash 41 | $ curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" $KAFKA_CONNECT_HOST:$KAFKA_CONNECT_PORT/connectors/ -d '{ "name": "inventory-connector", "config": { "connector.class": "io.debezium.connector.mysql.MySqlConnector", "tasks.max": "1", "database.hostname": "debezium-mysql-debezium-mysql", "database.port": "3306", "database.user": "debezium", "database.password": "dbz", "database.server.id": "184054", "database.server.name": "dbserver1", "database.whitelist": "inventory", "database.history.kafka.bootstrap.servers": "kafka.kubeless:9092", "database.history.kafka.topic": "dbhistory.inventory" } }' 42 | ``` 43 | 44 | ## Deploy the function with kubeless 45 | 46 | ### 1. Deploy 47 | 48 | In order to deploy the function run the following command: 49 | 50 | ```bash 51 | $ kubeless function deploy kafka-connect --from-file kafka-connect.py --handler kafka-connect.handler --runtime python2.7 --trigger-topic dbserver1.inventory.customers --dependencies requirements.txt 52 | ``` 53 | 54 | You can list the function with `kubeless function ls` and you should see the following: 55 | 56 | ``` 57 | $ kubeless function ls 58 | NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS 59 | kafka-connect default kafka-connect.handler python2.7 kubernetes==2.0.0 1/1 READY 60 | ``` 61 | 62 | ## Deploy the function with the Serverless plugin 63 | 64 | Alternatively you can deploy the function with the Serverless plugin for Kubeless. 65 | Make sure `serverless` is installed. You can see the installation instructions [here](https://github.com/serverless/serverless#quick-start). 66 | 67 | ### 1. Install Service Dependencies 68 | Run `npm install` in this directory to download the modules from `package.json`. 69 | 70 | ### 2. Deploy 71 | Run `serverless deploy` in order to deploy the function defined in `serverless.yml` 72 | 73 | ```bash 74 | $ serverless deploy 75 | Serverless: Packaging service... 76 | Serverless: Excluding development dependencies... 77 | Serverless: Deploying function kafka-connect... 78 | Serverless: Function kafka-connect succesfully deployed 79 | ``` 80 | 81 | **For more information on the Serverless Kubeless plugin, please see the project repository: [https://github.com/serverless/serverless-kubeless](https://github.com/serverless/serverless-kubeless).** 82 | 83 | ## Invoke the function 84 | 85 | To trigger the function you should log into the mysql container, open a client session and make some INSERT, UPDATE or DELETE operations in the `customers` table. 86 | 87 | 88 | ```bash 89 | $ kubectl get pods 90 | $ kubectl exec -it -- bash 91 | $ mysql -uroot -pdebezium 92 | mysql> use inventory; 93 | mysql> UPDATE customers SET first_name='Anne Marie' WHERE id=1004; 94 | mysql> INSERT INTO customers VALUES (default, "Sarah", "Thompson", "kitt@acme.com"); 95 | mysql> DELETE FROM customers WHERE id=1004; 96 | ``` 97 | -------------------------------------------------------------------------------- /incubator/kafka-connect/kafka-connect.py: -------------------------------------------------------------------------------- 1 | import json 2 | import base64 3 | from kubernetes import client, config 4 | 5 | config.load_incluster_config() 6 | v1=client.CoreV1Api() 7 | 8 | #Get slack secret 9 | for secrets in v1.list_secret_for_all_namespaces().items: 10 | if secrets.metadata.name == 'slack': 11 | token = base64.b64decode(secrets.data['token']) 12 | 13 | print "==> Function ready to listen events..." 14 | 15 | def handler(event, context): 16 | util_data = False 17 | try: 18 | if 'op' in event['data']['payload']: 19 | util_data = True; 20 | except: 21 | util_data = False 22 | 23 | if util_data == True: 24 | # CREATE operation 25 | if event['data']['payload']['op'] == "c": 26 | first_name = event['data']['payload']['after']['first_name']; 27 | last_name = event['data']['payload']['after']['last_name']; 28 | email = event['data']['payload']['after']['email']; 29 | msg = "Create operation: Added user %s %s with email %s" % (first_name, last_name, email) 30 | print msg; 31 | # DELETE operation 32 | elif event['data']['payload']['op'] == "d": 33 | first_name = event['data']['payload']['before']['first_name']; 34 | last_name = event['data']['payload']['before']['last_name']; 35 | email = event['data']['payload']['before']['email']; 36 | msg = "Delete operation: Deleted user %s %s with email %s" % (first_name, last_name, email) 37 | print msg; 38 | # UPDATE operation 39 | elif event['data']['payload']['op'] == "u": 40 | row_id = event['data']['payload']['before']['id']; 41 | first_name_before = event['data']['payload']['before']['first_name']; 42 | last_name_before = event['data']['payload']['before']['last_name']; 43 | email_before = event['data']['payload']['before']['email']; 44 | first_name_after = event['data']['payload']['after']['first_name']; 45 | last_name_after = event['data']['payload']['after']['last_name']; 46 | email_after = event['data']['payload']['after']['email']; 47 | msg = "Update operation in row with id %s: \n Old value: Name: %s %s and Email: %s \n New value: Name: %s %s and Email %s" % (row_id, first_name_before, last_name_before, email_before, first_name_after, last_name_after, email_after) 48 | print msg; 49 | else: 50 | msg = "Unrecognized operation" 51 | print msg; 52 | 53 | else: 54 | print "Payload is empty. Useless event..." 55 | 56 | return "Function executed" 57 | -------------------------------------------------------------------------------- /incubator/kafka-connect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kafka-connect", 3 | "version": "1.0.0", 4 | "description": "Function using kafka-connect to ingest events from database changes", 5 | "dependencies": { 6 | "serverless-kubeless": "^0.4.0" 7 | }, 8 | "devDependencies": {}, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "author": "", 13 | "license": "Apache-2.0" 14 | } -------------------------------------------------------------------------------- /incubator/kafka-connect/requirements.txt: -------------------------------------------------------------------------------- 1 | kubernetes==2.0.0 2 | -------------------------------------------------------------------------------- /incubator/kafka-connect/serverless.yml: -------------------------------------------------------------------------------- 1 | service: kafka-connect 2 | 3 | provider: 4 | name: kubeless 5 | runtime: python2.7 6 | 7 | plugins: 8 | - serverless-kubeless 9 | 10 | functions: 11 | kafka-connect: 12 | handler: kafka-connect.handler 13 | events: 14 | - trigger: 'dbserver1.inventory.customers' -------------------------------------------------------------------------------- /incubator/kubeless-reminder/Makefile: -------------------------------------------------------------------------------- 1 | reminder: 2 | kubeless function deploy scheduled-hello --schedule "30 10 * * THU" --runtime python2.7 --handler reminder.remind --from-file reminder.py --dependencies requirements.txt 3 | clean: 4 | kubeless function delete scheduled-hello 5 | kubectl delete secret slack 6 | -------------------------------------------------------------------------------- /incubator/kubeless-reminder/README.md: -------------------------------------------------------------------------------- 1 | # Kubeless weekly technical call reminder 2 | 3 | Trigger the function and it send a reminder for the Kubeless weekly technical call on every 10:30am Thursday. 4 | 5 | You need a SLACK_API_TOKEN 6 | 7 | ## Store token 8 | 9 | Store your SLACK API TOKEN in a Kubernetes secret 10 | 11 | ``` 12 | kubectl create secret generic slack --from-literal=token= 13 | ``` 14 | 15 | ## Launch the function 16 | 17 | Edit `reminder.py` to specify the proper channel, message. 18 | 19 | Deploy the function: 20 | 21 | ``` 22 | make reminder 23 | ``` 24 | 25 | Undeploy the function: 26 | 27 | ``` 28 | make clean 29 | ``` 30 | -------------------------------------------------------------------------------- /incubator/kubeless-reminder/reminder.py: -------------------------------------------------------------------------------- 1 | import json 2 | import base64 3 | 4 | from slackclient import SlackClient 5 | from kubernetes import client, config 6 | 7 | config.load_incluster_config() 8 | 9 | v1=client.CoreV1Api() 10 | 11 | for secrets in v1.list_secret_for_all_namespaces().items: 12 | if secrets.metadata.name == 'slack': 13 | token = base64.b64decode(secrets.data['token']) 14 | 15 | sc = SlackClient(token) 16 | 17 | def remind(event, context): 18 | return sc.api_call( 19 | "chat.postMessage", 20 | channel="#kubeless", 21 | text=""" please jump into the weekly call for discussing things going on Kubeless. 22 | 23 | Join from PC, Mac, Linux, iOS or Android: https://zoom.us/j/536180327 24 | 25 | Or iPhone one-tap : 26 | US: +16699006833,,536180327# or +16465588656,,536180327# 27 | Or Telephone: 28 | Dial(for higher quality, dial a number based on your current location): 29 | US: +1 669 900 6833 or +1 646 558 8656 30 | Meeting ID: 536 180 327 31 | International numbers available: https://zoom.us/zoomconference?m=H8zcNnFc19vCkVdoEHBkxK61gwDvyawC 32 | 33 | Meeting notes: https://docs.google.com/document/d/1-OsikjjQVHVFoXBHUbkRogrzzZijQ9MumFpLfWCCjwk/edit?usp=sharing 34 | """, 35 | as_user=True 36 | ) 37 | -------------------------------------------------------------------------------- /incubator/kubeless-reminder/requirements.txt: -------------------------------------------------------------------------------- 1 | slackclient 2 | kubernetes==2.0.0 3 | -------------------------------------------------------------------------------- /incubator/minio-resize/Makefile: -------------------------------------------------------------------------------- 1 | resize: 2 | kubeless function deploy thumb --trigger-topic s3 --runtime python2.7 --handler resize.thumbnail --from-file resize.py --dependencies requirements.txt 3 | -------------------------------------------------------------------------------- /incubator/minio-resize/README.md: -------------------------------------------------------------------------------- 1 | # A Python function to automatically create thumbnails 2 | 3 | This example assumes that you have Minio running in your Kubernetes cluster. See this [example](../minio-slack/README.md#deploy-minio-via-helm) 4 | 5 | ## Goal 6 | 7 | We want images that get uploaded to a Minio bucket (aka S3 bucket) to automatically trigger a thumbnail creation. 8 | Each thumbnail should then be stored into another bucket 9 | 10 | ## Create buckets 11 | 12 | In this example we will use two different buckets, if you have already configured your minio application as `localminio` run: 13 | 14 | ```bash 15 | mc mb localminio/foobar 16 | mc mb localminio/thumb 17 | mc events add localminio/foobar arn:minio:sqs:us-east-1:1:kafka --events put 18 | ``` 19 | 20 | ## Create the function 21 | 22 | ``` 23 | kubeless function deploy thumb1 --trigger-topic s3 --runtime python2.7 --handler resize.thumbnail --from-file resize.py --dependencies requirements.txt 24 | ``` 25 | 26 | This function is written in Python, the modules required to make it work are `kubernetes`, `minio` and `Pillow` 27 | 28 | Once it is running, drop images in the `foobar` bucket and watch the thumbnail appear automatically in the `thumb` bucket. 29 | 30 | ## Details of the function 31 | 32 | Looking into the `resize.py` file you will see how the thubmail is created: 33 | 34 | ``` 35 | size=(120,120) 36 | img = Image.open(tf.name) 37 | img.thumbnail(size) 38 | img.save(tf_thumb.name, "JPEG") 39 | ``` 40 | -------------------------------------------------------------------------------- /incubator/minio-resize/requirements.txt: -------------------------------------------------------------------------------- 1 | kubernetes==2.0.0 2 | minio 3 | Pillow 4 | -------------------------------------------------------------------------------- /incubator/minio-resize/resize.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import tempfile 3 | import os.path 4 | 5 | #pip install kubernetes 6 | from kubernetes import client, config 7 | 8 | # pip install minio 9 | from minio import Minio 10 | from minio.error import ResponseError 11 | 12 | # Use Pillow for thumbnail 13 | from PIL import Image 14 | 15 | config.load_incluster_config() 16 | 17 | v1=client.CoreV1Api() 18 | 19 | for secrets in v1.list_secret_for_all_namespaces().items: 20 | if secrets.metadata.name == 'minio-minio-user': 21 | access_key = base64.b64decode(secrets.data['accesskey']) 22 | secret_key = base64.b64decode(secrets.data['secretkey']) 23 | 24 | # Replace the DNS below with the minio service name (helm release name -svc) 25 | client = Minio('minio-minio-svc:9000', 26 | access_key=access_key, 27 | secret_key=secret_key, 28 | secure=False) 29 | 30 | def thumbnail(event, context): 31 | bucket = os.path.dirname(event['data']['Key']) 32 | _, file_extension = os.path.splitext(event['data']['Key']) 33 | filename = os.path.basename(event['data']['Key']) 34 | 35 | print file_extension.upper() 36 | 37 | if file_extension.upper() != ".JPEG": 38 | return "Not a picture" 39 | 40 | if event['data']['EventType'] == "s3:ObjectCreated:Put" and bucket == 'foobar': 41 | 42 | tf = tempfile.NamedTemporaryFile(delete=False) 43 | tf_thumb = tempfile.NamedTemporaryFile(delete=False) 44 | 45 | try: 46 | client.fget_object(bucket, filename, tf.name) 47 | except ResponseError as err: 48 | print err 49 | 50 | size=(120,120) 51 | img = Image.open(tf.name) 52 | img.thumbnail(size) 53 | img.save(tf_thumb.name, "JPEG") 54 | 55 | # puts the thumbnail in a thumbnail bucket 56 | thumb_name = filename + '.thumb' 57 | try: 58 | client.fput_object('thumb',thumb_name,tf_thumb.name) 59 | except ResponseError as err: 60 | print err 61 | 62 | else: 63 | print "Minio file deletion event" 64 | 65 | return "Thumbnail creation triggered" 66 | -------------------------------------------------------------------------------- /incubator/minio-slack/README.md: -------------------------------------------------------------------------------- 1 | # Send messages on objects upload to a bucket 2 | 3 | Make sure `minikube` and `kubeless` are installed. See the respective installation guides: 4 | * [Minikube](https://github.com/kubernetes/minikube#installation) 5 | * [Kubeless](http://kubeless.io/docs/quick-start/) 6 | 7 | 8 | ## Prepare the environment 9 | 10 | This example uses the Minio S3 clone to show case a kubeless pubsub function. Minio is configured to send notifications to Kafka, a function consumes those events and performs actions. 11 | 12 | ### Create Minio and Slack kubernetes secrets 13 | 14 | In order to access to the minio object storage and to send messages to a slack channel you need 15 | 16 | The access_key and secret_key for minio are configured in the helm chart template. You can edit the file values.yml and specify the keys you want to use. This secret will be deployed to kubernetes while deploying Minio so no further action is required. 17 | 18 | For the slack secret you need to obtain your slack token from [this page](https://api.slack.com/custom-integrations/legacy-tokens) and then deploy a secret to kubernetes with this command: 19 | 20 | ```bash 21 | kubectl create secret generic slack --from-literal=token=YOUR_SLACK_TOKEN 22 | ``` 23 | 24 | ### Deploy Minio via Helm 25 | 26 | ```bash 27 | helm repo add kubeless-functions-charts https://kubeless-functions-charts.storage.googleapis.com 28 | helm install minio kubeless-functions-charts/minio --set serviceType=NodePort 29 | ``` 30 | 31 | ### Configure Minio 32 | 33 | 34 | You will need the Minio [client](https://github.com/minio/mc) `mc`: 35 | 36 | ```bash 37 | brew install minio-mc 38 | ``` 39 | 40 | The following are Minio specific, it assumes your are using minikube on `192.168.99.100` and the minio service is running on port `32751` 41 | 42 | ```bash 43 | export MINIO_HOST=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") 44 | export MINIO_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services minio-minio-svc) 45 | mc config host add localminio http://$MINIO_HOST:$MINIO_PORT foobar foobarfoo 46 | ``` 47 | 48 | Create a foobar bucket: 49 | 50 | ```bash 51 | $ mc mb localminio/foobar 52 | ``` 53 | 54 | Turn on events for a `foobar` bucket: 55 | 56 | ```bash 57 | mc events add localminio/foobar arn:minio:sqs:us-east-1:1:kafka --events put 58 | ``` 59 | 60 | Check bucket 61 | 62 | ```bash 63 | mc ls localminio/foobar 64 | ``` 65 | 66 | 67 | ## Deploy the function with kubeless 68 | 69 | ### 1. Deploy 70 | 71 | In order to deploy the function run the following command: 72 | 73 | ```bash 74 | $ kubeless function deploy minio-slack --from-file minio-slack.py --handler minio-slack.handler --runtime python2.7 --dependencies requirements.txt 75 | ``` 76 | 77 | You can list the function with `kubeless function ls` and you should see the following: 78 | 79 | ``` 80 | $ kubeless function ls 81 | minio-slack default minio-slack.handler python2.7 slackclient 1/1 READY 82 | kubernetes==2.0.0 83 | minio 84 | ``` 85 | 86 | ### 2. Invoke 87 | 88 | To trigger the function you only need to upload a file to the `foobar` bucket using the Minio web interface of the minio client. 89 | 90 | Login to the Minio UI and upload some file to the `foobar` bucket. 91 | 92 | ```bash 93 | minikube service minio-minio-svc 94 | ``` 95 | -------------------------------------------------------------------------------- /incubator/minio-slack/minio-slack.py: -------------------------------------------------------------------------------- 1 | import json 2 | import base64 3 | import tempfile 4 | 5 | #pip install slackclient 6 | from slackclient import SlackClient 7 | 8 | #pip install kubernetes 9 | from kubernetes import client, config 10 | 11 | # pip install minio 12 | from minio import Minio 13 | from minio.error import ResponseError 14 | 15 | config.load_incluster_config() 16 | 17 | v1=client.CoreV1Api() 18 | 19 | #Get minio and slack secrets 20 | for secrets in v1.list_secret_for_all_namespaces().items: 21 | if secrets.metadata.name == 'minio-minio-user': 22 | access_key = base64.b64decode(secrets.data['accesskey']) 23 | secret_key = base64.b64decode(secrets.data['secretkey']) 24 | if secrets.metadata.name == 'slack': 25 | token = base64.b64decode(secrets.data['token']) 26 | 27 | 28 | # Replace the DNS below with the minio service name (helm release name -svc) 29 | client = Minio('minio-minio-svc:9000', 30 | access_key=access_key, 31 | secret_key=secret_key, 32 | secure=False) 33 | 34 | sc = SlackClient(token) 35 | 36 | 37 | def thumbnail(event, context): 38 | if event['data']['EventType'] == "s3:ObjectCreated:Put": 39 | bucket = event['data']['Key'].split('/')[0] 40 | filename = event['data']['Key'].split('/')[1] 41 | 42 | msg = "An object called %s was uploaded to bucket %s" % (filename,bucket) 43 | 44 | sc.api_call( 45 | "chat.postMessage", 46 | channel="#bot", 47 | text=msg 48 | ) 49 | 50 | return "Notification sent to SLACK" 51 | -------------------------------------------------------------------------------- /incubator/minio-slack/requirements.txt: -------------------------------------------------------------------------------- 1 | slackclient 2 | kubernetes==2.0.0 3 | minio 4 | -------------------------------------------------------------------------------- /incubator/ocr/README.md: -------------------------------------------------------------------------------- 1 | # Parse PDF files to obtain plain text stored in a MongoDbB collection 2 | 3 | Make sure `minikube` and `kubeless` are installed. See the respective installation guides: 4 | * [Minikube](https://github.com/kubernetes/minikube#installation) 5 | * [Kubeless](http://kubeless.io/docs/quick-start/) 6 | 7 | 8 | ## Prepare the environment 9 | 10 | This example uses the Minio S3 clone to show case a kubeless pubsub function. Minio is configured to send notifications to Kafka, then a function consume those events to parse PDF files using Apache Tika and store the plain text in a MongoDB collection. 11 | 12 | ### Deploy Minio, Apache Tika and MongoDB via Helm 13 | 14 | ```bash 15 | helm repo add kubeless-functions-charts https://kubeless-functions-charts.storage.googleapis.com 16 | helm install --name minio kubeless-functions-charts/minio --set serviceType=NodePort 17 | helm install --name tika kubeless-functions-charts/tika-server --set serviceType=NodePort 18 | helm install --name mongodb kubeless-functions-charts/mongodb --set serviceType=NodePort 19 | ``` 20 | 21 | ### Configure Minio 22 | 23 | 24 | You will need the Minio [client](https://github.com/minio/mc) `mc`: 25 | 26 | ```bash 27 | brew install minio-mc 28 | ``` 29 | 30 | The following are Minio specific, it assumes your are using minikube on `192.168.99.100` and the minio service is running on port `32751`. You can check your IP with `$ minikue ip` command and the port with `$ kubectl get svc` 31 | 32 | ```bash 33 | mc config host add localminio http://192.168.99.100:32751 foobar foobarfoo 34 | ``` 35 | 36 | Create an `input` and a `done` bucket: 37 | 38 | ```bash 39 | $ mc mb localminio/input 40 | $ mc mb localminio/done 41 | ``` 42 | 43 | Turn on events for a `input` bucket for .pdf files: 44 | 45 | ```bash 46 | mc events add localminio/input arn:minio:sqs:us-east-1:1:kafka --events put,delete --suffix .pdf 47 | ``` 48 | 49 | ## Deploy the function with kubeless 50 | 51 | ### 1. Deploy 52 | 53 | In order to deploy the function run the following command: 54 | 55 | ```bash 56 | $ kubeless function deploy ocr --from-file ocr.py --handler ocr.handler --runtime python2.7 --trigger-topic s3 --dependencies requirements.txt 57 | ``` 58 | 59 | You can list the function with `kubeless function ls` and you should see the following: 60 | 61 | ``` 62 | $ kubeless function ls 63 | NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS 64 | ocr default ocr.handler python2.7 minio 1/1 READY 65 | tika 66 | pymongo 67 | kubernetes==2.0.0 68 | ``` 69 | 70 | ### 2. Trigger the function 71 | 72 | To trigger the function you only need to upload a PDF file to the `input` bucket using the Minio web interface of the minio client. 73 | 74 | Login to the Minio UI and upload some file to the `input` bucket. 75 | 76 | ```bash 77 | minikube service minio-minio-svc 78 | ``` 79 | 80 | ### 3. Check results 81 | 82 | You should check that the text has been stored in MongoDB. For that first get your mongodb pod: 83 | 84 | ``` $ kubectl get pods -o=custom-columns=NAME:.metadata.name -l app=mongodb-mongodb 85 | NAME 86 | mongodb-mongodb-123307584-5hf33 87 | ``` 88 | 89 | And now execute the following: 90 | 91 | ```bash 92 | $ kubectl exec -it mongodb-mongodb-123307584-5hf33 -- mongo --eval "printjson(db.processed.findOne())" localhost/ocr 93 | ``` 94 | -------------------------------------------------------------------------------- /incubator/ocr/ocr.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import tempfile 3 | import json 4 | import tika 5 | import pymongo 6 | tika.TikaClientOnly = True 7 | from tika import parser 8 | from pymongo import MongoClient 9 | from kubernetes import client, config 10 | from minio import Minio 11 | from minio.error import ResponseError 12 | 13 | config.load_incluster_config() 14 | 15 | v1=client.CoreV1Api() 16 | 17 | for secrets in v1.list_secret_for_all_namespaces().items: 18 | if secrets.metadata.name == 'minio-minio-user': 19 | access_key = base64.b64decode(secrets.data['accesskey']) 20 | secret_key = base64.b64decode(secrets.data['secretkey']) 21 | 22 | mongo = MongoClient('mongodb-mongodb', 27017) 23 | 24 | client = Minio('minio-minio-svc:9000', 25 | access_key=access_key, 26 | secret_key=secret_key, 27 | secure=False) 28 | 29 | print('Loading function...') 30 | 31 | def handler(event, context): 32 | if event['data']['EventType'] == "s3:ObjectCreated:Put" : 33 | tf = tempfile.NamedTemporaryFile(delete=False) 34 | bucket = event['data']['Key'].split('/')[0] 35 | filename = event['data']['Key'].split('/')[1] 36 | 37 | # Fetching source file from Minio 38 | try: 39 | print('Fetching file') 40 | client.fget_object(bucket, filename, tf.name) 41 | except ResponseError as err: 42 | print('Error fetching file') 43 | print err 44 | 45 | # OCR text extraction performed by Tika 46 | print 'Sending file to Tika' 47 | parsed = parser.from_file(tf.name, 'http://tika-tika-server:80/tika') 48 | ocrdata = json.dumps(parsed, ensure_ascii=True) 49 | 50 | # MongoDB document insertion 51 | db = mongo['ocr'] 52 | result = db.processed.insert_one(parsed) 53 | print 'Document Saved!' 54 | print('Document proccessed: {0}'.format(result.inserted_id)) 55 | 56 | # move OCRd file to done bucket 57 | try: 58 | # Copy from input bucket to done bucket 59 | fullpath = 'input/' + filename 60 | client.copy_object('done', filename, fullpath) 61 | # Remove from input bucket 62 | client.remove_object('input', filename) 63 | except ResponseError as err: 64 | print err 65 | else: 66 | print "Minio file deletion event" 67 | 68 | return "OCR Finished" 69 | -------------------------------------------------------------------------------- /incubator/ocr/requirements.txt: -------------------------------------------------------------------------------- 1 | minio 2 | tika 3 | pymongo 4 | kubernetes==2.0.0 5 | -------------------------------------------------------------------------------- /incubator/rest-api/README.md: -------------------------------------------------------------------------------- 1 | # Task List. Simple API app 2 | 3 | This is an example for deploying a simple serverless API. 4 | 5 | It uses MongoDB as database so first we need to deploy it: 6 | 7 | ```console 8 | kubectl create -f https://raw.githubusercontent.com/bitnami/bitnami-docker-mongodb/3.4.10-r0/kubernetes.yml 9 | ``` 10 | 11 | Now we need to create a zip file containing all the API code. Generate it executing: 12 | 13 | ```console 14 | zip -r api.zip api server.js 15 | ``` 16 | 17 | Wait for the database to be deployed (check the status with `kubectl get pods`). Once it is ready deploy the API functions: 18 | 19 | ```console 20 | kubeless function deploy api-list \ 21 | --from-file api.zip \ 22 | --handler server.list \ 23 | --runtime nodejs6 \ 24 | --dependencies package.json 25 | kubeless function deploy api-add \ 26 | --from-file api.zip \ 27 | --handler server.add \ 28 | --runtime nodejs6 \ 29 | --dependencies package.json 30 | kubeless function deploy api-update \ 31 | --from-file api.zip \ 32 | --handler server.update \ 33 | --runtime nodejs6 \ 34 | --dependencies package.json 35 | kubeless function deploy api-delete \ 36 | --from-file api.zip \ 37 | --handler server.delete \ 38 | --runtime nodejs6 \ 39 | --dependencies package.json 40 | ``` 41 | 42 | Once the functions are finally deployed you can invoke them: 43 | 44 | ```console 45 | $ kubeless function call api-add --data '{"name": "Create an API"}' 46 | {"__v":0,"name":"Create an API","_id":"5a0c78018cef7f00017f39ca","status":["pending"],"Created_date":"2017-11-15T17:23:13.718Z"} 47 | $ kubeless function call api-list 48 | [{"_id":"5a0c78ae8cef7f00017f39cb","name":"Create an API","__v":0,"status":["pending"],"Created_date":"2017-11-15T17:26:06.453Z"}] 49 | $ kubeless function call api-update --data '{"name": "Create an API", "status": ["completed"]}' 50 | {"_id":"5a0c71429bf23b0001cea0d2","name":"Create an API","__v":0,"status":["completed"],"Created_date":"2017-11-15T16:54:26.865Z"} 51 | $ kubeless function call api-delete --data '{"name": "Create an API"}' 52 | {"message":"Task successfully deleted"} 53 | ``` -------------------------------------------------------------------------------- /incubator/rest-api/api/controllers/todoListController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | var mongoose = require('mongoose'), 5 | Task = mongoose.model('Tasks'); 6 | 7 | exports.list_all_tasks = function () { 8 | return new Promise((resolve, reject) => { 9 | Task.find({}, function (err, task) { 10 | if (err) { 11 | reject(err); 12 | } 13 | resolve(task); 14 | }); 15 | }) 16 | }; 17 | 18 | exports.create_a_task = function (event) { 19 | var new_task = new Task(event.data); 20 | return new Promise((resolve, reject) => { 21 | new_task.save(function (err, task) { 22 | if (err) { 23 | reject(err); 24 | } 25 | resolve(task); 26 | }); 27 | }); 28 | }; 29 | 30 | exports.update_a_task = function (event) { 31 | return new Promise((resolve, reject) => { 32 | Task.findOneAndUpdate({ name: event.data.name }, event.data, { new: true }, function (err, task) { 33 | if (err) { 34 | reject(err); 35 | } 36 | resolve(task); 37 | }); 38 | }); 39 | }; 40 | 41 | exports.delete_a_task = function (event) { 42 | return new Promise((resolve, reject) => { 43 | Task.remove({ 44 | name: event.data.name 45 | }, function (err, task) { 46 | if (err) { 47 | reject(err); 48 | } 49 | resolve({ message: 'Task successfully deleted' }); 50 | }); 51 | }); 52 | }; 53 | -------------------------------------------------------------------------------- /incubator/rest-api/api/models/todoListModel.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var mongoose = require('mongoose'); 3 | var Schema = mongoose.Schema; 4 | 5 | 6 | var TaskSchema = new Schema({ 7 | name: { 8 | type: String, 9 | required: 'Kindly enter the name of the task' 10 | }, 11 | Created_date: { 12 | type: Date, 13 | default: Date.now 14 | }, 15 | status: { 16 | type: [{ 17 | type: String, 18 | enum: ['pending', 'ongoing', 'completed'] 19 | }], 20 | default: ['pending'] 21 | } 22 | }); 23 | 24 | module.exports = mongoose.model('Tasks', TaskSchema); 25 | -------------------------------------------------------------------------------- /incubator/rest-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-api", 3 | "version": "1.0.0", 4 | "description": "Simple serverless api", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "body-parser": "^1.18.2", 13 | "mongoose": "^5.7.7" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /incubator/rest-api/server.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'), 2 | Task = require('./api/models/todoListModel'), //created model loading here 3 | bodyParser = require('body-parser'); 4 | 5 | // mongoose instance connection url connection 6 | mongoose.Promise = global.Promise; 7 | mongoose.connect('mongodb://mongodb.default/Tododb'); 8 | 9 | var controller = require('./api/controllers/todoListController'); //importing route 10 | 11 | module.exports = { 12 | add: function (event, data) { return controller.create_a_task(event, data) }, 13 | delete: function (event, data) { return controller.delete_a_task(event, data) }, 14 | list: function (event, data) { return controller.list_all_tasks(event, data) }, 15 | update: function (event, data) { return controller.update_a_task(event, data) }, 16 | } 17 | -------------------------------------------------------------------------------- /incubator/slack/Makefile: -------------------------------------------------------------------------------- 1 | slack: 2 | kubeless function deploy slack --runtime python2.7 --handler bot.handler --from-file bot.py --dependencies requirements.txt 3 | events: 4 | kubeless function deploy k8s-events --trigger-topic k8s --from-file botevents.py --handler botevents.handler --runtime python2.7 --dependencies requirements.txt 5 | -------------------------------------------------------------------------------- /incubator/slack/README.md: -------------------------------------------------------------------------------- 1 | # SLACK example 2 | 3 | Trigger the function and it send a message to your SLACK channel. 4 | 5 | You need a SLACK_API_TOKEN 6 | 7 | ## Store token 8 | 9 | Store your SLACK API TOKEN in a Kubernetes secret 10 | 11 | ``` 12 | kubectl create secret generic slack --from-literal=token= 13 | ``` 14 | 15 | ## Launch the function 16 | 17 | Edit `bot.py` to specify the proper channel. 18 | 19 | ``` 20 | make slack 21 | ``` 22 | 23 | ## Send a slack message 24 | 25 | With a local proxy running: 26 | 27 | ``` 28 | kubeless function call slack --data '{"msg":"This is a message to SLACK"}' 29 | ``` 30 | 31 | ## Listen to Kubernetes events in SLACK 32 | 33 | Launch the Kafka event sync: 34 | 35 | ``` 36 | kubeless topic create k8s 37 | kubectl run events --image=skippbox/k8s-events:0.10.12 38 | ``` 39 | 40 | Deploy the function to get triggered on k8s events and send message to SLACK 41 | 42 | ``` 43 | make events 44 | ``` 45 | -------------------------------------------------------------------------------- /incubator/slack/bot.py: -------------------------------------------------------------------------------- 1 | import json 2 | import base64 3 | 4 | from slackclient import SlackClient 5 | from kubernetes import client, config 6 | 7 | config.load_incluster_config() 8 | 9 | v1=client.CoreV1Api() 10 | 11 | for secrets in v1.list_namespaced_secret("default").items: 12 | if secrets.metadata.name == 'slack': 13 | token = base64.b64decode(secrets.data['token']) 14 | 15 | sc = SlackClient(token) 16 | 17 | def handler(event, context): 18 | return sc.api_call("chat.postMessage", channel="#bot", text=event['data']['msg']) 19 | -------------------------------------------------------------------------------- /incubator/slack/botevents.py: -------------------------------------------------------------------------------- 1 | import json 2 | import base64 3 | import tempfile 4 | 5 | #pip install slackclient 6 | from slackclient import SlackClient 7 | 8 | #pip install kubernetes 9 | from kubernetes import client, config 10 | 11 | config.load_incluster_config() 12 | 13 | v1=client.CoreV1Api() 14 | 15 | #Get minio and slack secrets 16 | for secrets in v1.list_secret_for_all_namespaces().items: 17 | if secrets.metadata.name == 'slack': 18 | token = base64.b64decode(secrets.data['token']) 19 | 20 | sc = SlackClient(token) 21 | 22 | def handler(event, context): 23 | msg = "k8s event: %s" % event['data'] 24 | 25 | r = sc.api_call( 26 | "chat.postMessage", 27 | channel="#bot", 28 | text=msg 29 | ) 30 | if r.get('ok'): 31 | return "Notification successfully sent to Slack" 32 | else: 33 | return "Error while sending notification to Slack: " + r.get('error') 34 | -------------------------------------------------------------------------------- /incubator/slack/requirements.txt: -------------------------------------------------------------------------------- 1 | slackclient 2 | kubernetes==2.0.0 3 | -------------------------------------------------------------------------------- /incubator/twitter/README.md: -------------------------------------------------------------------------------- 1 | # Twitter function for Kubeless 2 | 3 | Make sure `minikube` and `kubeless` are installed. See the respective installation guides: 4 | * [Minikube](https://github.com/kubernetes/minikube#installation) 5 | * [Kubeless](http://kubeless.io/docs/quick-start/) 6 | 7 | Before deploy the function, you need to create a kubernetes secret storing your consumer_key, consumer_secret and token_key and token_secret. You can obtain them from the following URL by creating a new app. 8 | 9 | https://apps.twitter.com/ 10 | 11 | Once you have your keys, you can deploy to kubernetes with the following command. Remember to update the placeholders with the correct values. 12 | 13 | ```bash 14 | kubectl create secret generic twitter --from-literal=consumer_key=YOUR_CONSUME_KEY --from-literal=consumer_secret=YOUR_CONSUME_SECRET --from-literal=token_key=YOUR_TOKEN_KEY --from-literal=token_secret=YOUR_TOKEN_SECRET 15 | ``` 16 | 17 | Now you can deploy the function with kubeless or with the serverless plugin: 18 | 19 | ## Deploy the function with kubeless 20 | 21 | ### 1. Deploy 22 | 23 | In order to deploy the function run the following command: 24 | 25 | ```bash 26 | $ kubeless function deploy tweet --from-file tweet.py --handler tweet.handler --runtime python2.7 --dependencies requirements.txt 27 | ``` 28 | 29 | You can list the function with `kubeless function ls` and you should see the following: 30 | 31 | ``` 32 | $ kubeless function ls 33 | NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS 34 | tweet default tweet.handler python2.7 python-twitter 1/1 READY 35 | kubernetes==2.0.0 36 | ``` 37 | 38 | ### 2. Invoke 39 | You can now call your function: 40 | 41 | ```bash 42 | kubeless function call tweet --data '{"tweet": "Testing twitter function from kubeless!"}' 43 | ``` 44 | 45 | ## Deploy the function with the Serverless plugin 46 | 47 | Make sure `serverless` is installed. You can see the installation instructions [here](https://github.com/serverless/serverless#quick-start). 48 | 49 | ### 1. Install Service Dependencies 50 | Run `npm install` in this directory to download the modules from `package.json`. 51 | 52 | ### 2. Deploy 53 | Run `serverless deploy` in order to deploy the function defined in `serverless.yml` 54 | 55 | ```bash 56 | $ serverless deploy 57 | Serverless: Packaging service... 58 | Serverless: Function tweet succesfully deployed 59 | ``` 60 | 61 | ### 3. Invoke the function 62 | 63 | Run the following command: 64 | 65 | ```bash 66 | $ serverless invoke -f tweet --log --data '{"tweet":"testing tweet from serverless kubeless plugin"}' 67 | Serverless: Calling function: tweet... 68 | -------------------------------------------------------------------- 69 | ``` 70 | 71 | **For more information on the Serverless Kubeless plugin, please see the project repository: [https://github.com/serverless/serverless-kubeless](https://github.com/serverless/serverless-kubeless).** 72 | -------------------------------------------------------------------------------- /incubator/twitter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kubeless-python-simple", 3 | "version": "0.0.1", 4 | "description": "This example demonstrates how to setup a simple Python function with Kubeless", 5 | "dependencies": { 6 | "serverless-kubeless": "^0.4.0" 7 | }, 8 | "main": "handler.py", 9 | "autor": "Bitnami", 10 | "license": "ASL" 11 | } 12 | -------------------------------------------------------------------------------- /incubator/twitter/requirements.txt: -------------------------------------------------------------------------------- 1 | python-twitter 2 | kubernetes==2.0.0 3 | -------------------------------------------------------------------------------- /incubator/twitter/serverless.yml: -------------------------------------------------------------------------------- 1 | service: tweet 2 | 3 | provider: 4 | name: kubeless 5 | runtime: python2.7 6 | 7 | plugins: 8 | - serverless-kubeless 9 | 10 | functions: 11 | tweet: 12 | handler: tweet.handler 13 | -------------------------------------------------------------------------------- /incubator/twitter/tweet.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import twitter 3 | 4 | from kubernetes import client, config 5 | 6 | config.load_incluster_config() 7 | 8 | v1=client.CoreV1Api() 9 | 10 | for secrets in v1.list_secret_for_all_namespaces().items: 11 | if secrets.metadata.name == 'twitter': 12 | consumer_key = base64.b64decode(secrets.data['consumer_key']) 13 | consumer_secret = base64.b64decode(secrets.data['consumer_secret']) 14 | token_key = base64.b64decode(secrets.data['token_key']) 15 | token_secret = base64.b64decode(secrets.data['token_secret']) 16 | 17 | api = twitter.Api(consumer_key=consumer_key, 18 | consumer_secret=consumer_secret, 19 | access_token_key=token_key, 20 | access_token_secret=token_secret) 21 | 22 | def handler(event, context): 23 | status = api.PostUpdate(event['data']['tweet']) 24 | -------------------------------------------------------------------------------- /incubator/weather/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json -------------------------------------------------------------------------------- /incubator/weather/README.md: -------------------------------------------------------------------------------- 1 | # Weather report 2 | 3 | This is a simple function that uses query.yahooapis.com to retrieve the weather for a specific location. 4 | 5 | ## Launch the function 6 | 7 | ``` 8 | kubeless function deploy weather --runtime nodejs8 \ 9 | --from-file handler.js \ 10 | --dependencies package.json \ 11 | --handler handler.weather 12 | ``` 13 | 14 | ## Execute the function 15 | 16 | ``` 17 | $ kubeless function call weather --data '{"location": "nome, ak"}' 18 | It is -5 celsius degrees in nome, ak and Snow 19 | ``` 20 | 21 | ## Delete the function 22 | 23 | ``` 24 | kubeless function delete weather 25 | ``` 26 | -------------------------------------------------------------------------------- /incubator/weather/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const rq = require('request-promise-native'); 4 | 5 | module.exports = { 6 | weather: async function (event, context) { 7 | const location = event.data.location; 8 | 9 | if (!location) { 10 | throw new Error('You must provide a location.'); 11 | } 12 | const response = await rq(`https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text="${location}") and u="c"&format=json`); 13 | const condition = JSON.parse(response).query.results.channel.item.condition; 14 | const text = condition.text; 15 | const temperature = condition.temp; 16 | return `It is ${temperature} celsius degrees in ${location} and ${text}`; 17 | } 18 | } -------------------------------------------------------------------------------- /incubator/weather/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weather", 3 | "version": "1.0.0", 4 | "description": "Simple weather reporter", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "request": "^2.83.0", 13 | "request-promise-native": "^1.0.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /incubator/yaml-object/function.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kubeless.io/v1beta1 2 | kind: Function 3 | metadata: 4 | name: hello-yaml 5 | spec: 6 | checksum: sha256:d251999dcbfdeccec385606fd0aec385b214cfc74ede8b6c9e47af71728f6e9a 7 | deps: 8 | function: | 9 | def foo(event, context): 10 | return "hello world" 11 | function-content-type: text 12 | handler: helloget.foo 13 | runtime: python2.7 14 | timeout: "180" 15 | --------------------------------------------------------------------------------