diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..a82a1dd --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,4 @@ +# Lines starting with '#' are comments. +# Each line is a file pattern followed by one or more owners. +# See https://blog.github.com/2017-07-06-introducing-code-owners/ for details +* @pchico83 @rberrelleza @rlamana \ No newline at end of file diff --git a/README.md b/README.md index 26a8bad..8f9bd75 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,15 @@ **Maintainers:** [Okteto](https://github.com/okteto) -This repository contains examples of how to develop applications directly in the cloud using [Okteto](https://cloud.okteto.com). +This repository contains examples of how to develop applications directly in your Kubernetes cluster using [okteto](https://okteto.com), different platforms and deployment technologies. ## Examples -1. [Golang app](math/README.md) -1. [Python app accesing Redis](vote/README.md) -1. [React/Webpack app + Node.js API + MongoDB](movies/README.md) -1. [Accelerate Serverless Development with Cloud Run and Okteto](cloud-run/README.md) -1. [Python app deployed with raw Kubernetes manifests](python-kubectl/README.md) -1. [Python app integrated with VS Code Remote Development](vscode-ssh/README.md) - +1. [Python](python/README.md) +1. [Golang](golang/README.md) +1. [Node.js](node/README.md) +1. [Ruby](ruby/README.md) +1. [Java](java/README.md) +1. [Helm](helm/README.md) +1. [Cloud Run](cloud-run/README.md) +1. [VS Code Remote Development](vscode/README.md) diff --git a/cloud-run/.gitignore b/cloud-run/.gitignore deleted file mode 100644 index 894a44c..0000000 --- a/cloud-run/.gitignore +++ /dev/null @@ -1,104 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ diff --git a/cloud-run/Dockerfile b/cloud-run/Dockerfile deleted file mode 100644 index e27a2c4..0000000 --- a/cloud-run/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -# Using official python runtime base image -FROM python:3-alpine - -# Set the application directory -WORKDIR /src - -RUN pip install --upgrade pip - -# Install our requirements.txt -ADD requirements.txt requirements.txt -RUN pip install -r requirements.txt - -# Copy our code from the current folder to /app inside the container -ADD . /src - -# Make port 8080 available for links and/or publish -EXPOSE 8080 - -# Define our command to be run when launching the container -CMD ["python", "app.py"] diff --git a/cloud-run/LICENSE b/cloud-run/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/cloud-run/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/cloud-run/README.md b/cloud-run/README.md deleted file mode 100644 index 103520a..0000000 --- a/cloud-run/README.md +++ /dev/null @@ -1,124 +0,0 @@ -# Accelerate Serverless Development with Cloud Run and Okteto - -Based on this [blog post](https://medium.com/okteto/accelerate-serverless-development-with-cloud-run-and-okteto-33343e4fcbd8). - -Cloud Run is a solution for deploying your code as containers with no infrastructure management. It is a step forward for serverless platforms, eliminating most of the architectural restrictions that Lambda functions have. - -There is an official Cloud Run contract for supported containers that we can summarize in the following points: - -- Compile your container for 64-bit Linux; -- Your container listens on port 8080 for HTTP requests; -- Your HTTP must be ready within four minutes after receiving a request; -- The available memory per request is 2GB; -- Computation is stateless and scoped to a single request. - -If your application meets these requirements it will work in Cloud Run. Note that there is no restriction on the programming language used by your application. - -Cloud Run runs on top of Kubernetes, but you don’t need to know anything about Kubernetes to deploy your applications in Cloud Run. Let’s see how easy it is with a sample application, the Voting App. - -## Deploy the Voting App to Cloud Run - -> I assume you are already familiar with GCP (Google Cloud Platform) and Cloud Run. If you are not, check this excellent [blog post](https://medium.com/@aconchillo/google-cloud-run-or-how-to-run-your-static-website-in-5-minutes-and-much-more-dbe8f2804395) to get a sense of it. For the purpose of this sample, we will just need a Project ID on which to deploy Cloud Run applications. - -Get a local version of the Voting App, by executing the following commands from your terminal: - -```console -$ git clone git@github.com:okteto/cloud-samples.git -$ cd cloud-samples/cloud-run -``` - -You now have a functioning git repository that contains a simple python 3 application and a Dockerfile to generate the associate Docker Image. The Voting App consists of a flask app that allows you to vote for your favorite animals. Build the Docker image by executing: - -```console -$ gcloud builds submit --tag gcr.io/[project-id]/vote -``` - -After about 30 seconds you will have your Docker image built and uploaded to the Google Container Registry. Deploy your image to Cloud Run by executing the command below: - -```console -$ gcloud beta run deploy --image gcr.io/[project-id]/vote -Service name: (vote): -Deploying container to Cloud Run service [vote] in project [project-id] region [us-central1] -Allow unauthenticated invocations to new service [vote]? (y/N)? y -✓ Deploying new service... Done. -✓ Creating Revision... -✓ Routing traffic... -Done. -Service [vote] revision [vote-00001] has been deployed and is serving traffic at https://vote-cg2bjntyuq-uc.a.run.app -``` - -After another 30 seconds or so you will be able to browse to the generated URL and see the Voting App online! Really cool, isn’t it? - -## Develop the Voting App with Okteto - -Now it is time to do some work on the Voting App. Building and deploying the Voting App to Cloud Run takes about 1 minute for every change we want to test. If you don’t want to kill your productivity, you will need to take a different approach. - -Let me introduce you to Okteto. Okteto provides instant cloud-based environments to code and collaborate. Instead of having to build and deploy a container every time you want to see your changes in action, Okteto lets you develop your applications directly in the cloud. - -The first thing we need to do is install the Okteto CLI by running the command below: - -MacOS/Linux - -```console -curl https://get.okteto.com -sSfL | sh -``` - -Windows - -```console -wget https://downloads.okteto.com/cli/okteto-Windows-x86_64 -OutFile c:\windows\system32\okteto.exe -``` - -Once the CLI is installed, run the okteto login command to create your Okteto account and get an API token for your workstation. - -```console -$ okteto login -``` - -Now start your Okteto Development Environment by executing the okteto up command: - -```console -$ okteto up -✓ Okteto Environment activated -✓ Files synchronized -✓ Your Okteto Environment is ready -Name: vote -Endpoint: https://vote-pchico83.okteto.net -* Serving Flask app "app" (lazy loading) -* Environment: production - WARNING: Do not use the development server in a production environment. - Use a production WSGI server instead. -* Debug mode: on -* Running on http://0.0.0.0:8080/ (Press CTRL+C to quit) -* Restarting with stat -* Debugger is active! -* Debugger PIN: 117-959-944 -``` - -After a couple of seconds, you will be able to browse to the generated URL and see the Voting App online! - -> Note that Okteto creates HTTPs endpoints and takes care of the infrastructure for your Okteto Development Environment, but this environment isn’t highly available. It is just meant for development purposes. - -Now you are ready to see the power of Okteto in action. Open your local IDE, go to `app.py` and modify the `getOptions` function with the code below: - -``` -def getOptions(): - optionA = 'Otters' - optionB = 'Dogs' - return optionA, optionB -``` - -Go to the browser again and reload the page. Your changes were applied instantly. No commit, build or push required 😎! - -Edit the source code as many times as you need. With Okteto you can iterate in your code instantly, instead of wasting minutes building and deploying images. This is possible because Okteto instantly synchronizes your local filesystem to your cloud development environment. - -Once you are happy with your changes, deploy them to production with Cloud Run: - -```console -$ gcloud builds submit --tag gcr.io/[project-id]/vote -$ gcloud beta run deploy --image gcr.io/[project-id]/vote -``` - -## Conclusion - -We have shown how easy is to deploy applications in Cloud Run, and how to [use Okteto](https://okteto.com) to do efficient development in the cloud. And what it is even more awesome, is that you have been able to efficiently develop, build and deploy a Docker-based application without typing a single docker command, thanks to the combined powers of Cloud Run and [Okteto](https://okteto.com)! diff --git a/cloud-run/static/stylesheets/style.css b/cloud-run/static/stylesheets/style.css deleted file mode 100644 index 53de543..0000000 --- a/cloud-run/static/stylesheets/style.css +++ /dev/null @@ -1,129 +0,0 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:400,700,600); - -*{ - box-sizing:border-box; -} -html,body{ - margin: 0; - padding: 0; - background-color: #F7F8F9; - height: 100vh; - font-family: 'Open Sans'; -} - -button{ - border-radius: 0; - width: 100%; - height: 50%; -} - -button[type="submit"] { - -webkit-appearance:none; -webkit-border-radius:0; -} - -button i{ - float: right; - padding-right: 30px; - margin-top: 3px; -} - -button.a{ - background-color: #1aaaf8; -} - -button.b{ - background-color: #00cbca; -} - -#tip{ - text-align: left; - color: #c0c9ce; - font-size: 14px; -} - -#hostname{ - position: absolute; - bottom: 100px; - right: 0; - left: 0; - color: #8f9ea8; - font-size: 24px; -} - -#content-container{ - z-index: 2; - position: relative; - margin: 0 auto; - display: table; - padding: 10px; - max-width: 940px; - height: 100%; -} -#content-container-center{ - display: table-cell; - text-align: center; -} - -#content-container-center h3{ - color: #254356; -} - -#choice{ - transition: all 300ms linear; - line-height: 1.3em; - display: inline; - vertical-align: middle; - font-size: 3em; -} -#choice a{ - text-decoration:none; -} -#choice a:hover, #choice a:focus{ - outline:0; - text-decoration:underline; -} - -#choice button{ - display: block; - height: 80px; - width: 330px; - border: none; - color: white; - text-transform: uppercase; - font-size:18px; - font-weight: 700; - margin-top: 10px; - margin-bottom: 10px; - text-align: left; - padding-left: 50px; -} - -#choice button.a:hover{ - background-color: #1488c6; -} - -#choice button.b:hover{ - background-color: #00a2a1; -} - -#choice button.a:focus{ - background-color: #1488c6; -} - -#choice button.b:focus{ - background-color: #00a2a1; -} - -#background-stats{ - z-index:1; - height:100%; - width:100%; - position:absolute; -} -#background-stats div{ - transition: width 400ms ease-in-out; - display:inline-block; - margin-bottom:-4px; - width:50%; - height:100%; -} diff --git a/go.mod b/go.mod deleted file mode 100644 index 59939bf..0000000 --- a/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/okteto/cloud-samples - -require github.com/astaxie/beego v1.11.1 diff --git a/math/.stignore b/golang/.stignore similarity index 100% rename from math/.stignore rename to golang/.stignore diff --git a/math/Dockerfile b/golang/Dockerfile similarity index 100% rename from math/Dockerfile rename to golang/Dockerfile diff --git a/golang/README.md b/golang/README.md new file mode 100644 index 0000000..03664e2 --- /dev/null +++ b/golang/README.md @@ -0,0 +1,97 @@ +# Math App + +This example shows how to leverage [Okteto](https://okteto.com) to develop a python app directly in the cloud. +This example is deployed using raw Kubernetes manifests. + +## Step 1: Install the Okteto CLI + +Install the Okteto CLI by running the following command in your local terminal: + +MacOS/Linux: + +```console +$ curl https://get.okteto.com -sSfL | sh +``` + +Windows: + +```console +$ wget https://downloads.okteto.com/cli/okteto-Windows-x86_64 -OutFile c:\windows\system32\okteto.exe +``` + +This example works in any Kubernetes cluster (Okteto reads your local Kubernetes credentials), but we recommend to use https://cloud.okteto.com to follow this guide. + +## Step 2: Deploy the sample app + +Get a local version of the sample application by executing the following commands in your local terminal: + +```console +git clone https://github.com/okteto/samples +cd samples/golang +``` + +You now have a functioning git repository that contains a simple golang application. Now start your Okteto Environment by running the following command: + +In the `manifest/` directory you also have raw Kubernetes manifests that we will use in this guide to deploy the application in the cluster. Okteto works however independently of your common deployment practices or tools. + +> If you don´t have `kubectl` installed, follow this [guide](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + +Run the Math app by executing: + +```console +kubectl apply -f manifests +``` + +> Wait for one or two minutes until the application is running. You can access the Math app at https://localhost:8080/mult/3/4. + + +## Step 3: Create your Okteto Environment + +Now start your Okteto Environment by running the following command: + +```console +okteto up +``` + +The `okteto up` command will automatically start an Okteto Environment. It will also start a file synchronization service to keep your changes up to date between your local filesystem and your Okteto Environment. + +```console +$ okteto up + ✓ Okteto Environment activated + ✓ Files synchronized + ✓ Your Okteto Environment is ready + Name: math + +bash-4.4# +``` + +Once the Okteto Environment is ready, start your application by executing the following command in your Okteto Terminal: + +```console +okteto> go run main.go +``` + +## Step 4: Develop directly in the cloud + +Now things get more exciting. Edit the file `math/main.go` and switch the word `mult` by `times` at line 43. Save your changes. Cancel the execution of `go run main.go` from your Okteto Terminal by pressing `ctrl + c`. Run your tests to check that everything is fine with your changes: + +```console +okteto> go test ./... +``` + +And finally rerun your application: + +```console +okteto> go run main.go +``` + +Go back to the browser, and go to the new endpoint https://localhost:8080/times/3/4. Notice how your changes are instantly applied. No commit, build or push required 😎! + + +## Step 5: Cleanup + +Cancel the `okteto up` command by pressing `ctrl + c` + `exit` and run the following commands to remove the resources created by this guide: + +```console +kubectl delete -f manifests +``` diff --git a/math/conf/app.conf b/golang/conf/app.conf similarity index 100% rename from math/conf/app.conf rename to golang/conf/app.conf diff --git a/math/go.mod b/golang/go.mod similarity index 100% rename from math/go.mod rename to golang/go.mod diff --git a/go.sum b/golang/go.sum similarity index 100% rename from go.sum rename to golang/go.sum diff --git a/math/main.go b/golang/main.go similarity index 100% rename from math/main.go rename to golang/main.go diff --git a/math/main_test.go b/golang/main_test.go similarity index 100% rename from math/main_test.go rename to golang/main_test.go diff --git a/golang/manifests/deployment.yaml b/golang/manifests/deployment.yaml new file mode 100644 index 0000000..c4fd6fa --- /dev/null +++ b/golang/manifests/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: math + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + replicas: 1 + selector: + matchLabels: + app: math + template: + metadata: + labels: + app: math + spec: + containers: + - image: okteto/math:latest + name: math \ No newline at end of file diff --git a/golang/manifests/service.yaml b/golang/manifests/service.yaml new file mode 100644 index 0000000..299a0f4 --- /dev/null +++ b/golang/manifests/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: math + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + type: ClusterIP + ports: + - name: "math" + port: 8080 + selector: + app: math diff --git a/golang/okteto.yml b/golang/okteto.yml new file mode 100644 index 0000000..3f753b7 --- /dev/null +++ b/golang/okteto.yml @@ -0,0 +1,5 @@ +name: math +command: ["bash"] +workdir: /go/src/app +forward: + - 8080:8080 \ No newline at end of file diff --git a/math/vendor/github.com/astaxie/beego/.gitignore b/golang/vendor/github.com/astaxie/beego/.gitignore similarity index 100% rename from math/vendor/github.com/astaxie/beego/.gitignore rename to golang/vendor/github.com/astaxie/beego/.gitignore diff --git a/math/vendor/github.com/astaxie/beego/.gosimpleignore b/golang/vendor/github.com/astaxie/beego/.gosimpleignore similarity index 100% rename from math/vendor/github.com/astaxie/beego/.gosimpleignore rename to golang/vendor/github.com/astaxie/beego/.gosimpleignore diff --git a/math/vendor/github.com/astaxie/beego/.travis.yml b/golang/vendor/github.com/astaxie/beego/.travis.yml similarity index 100% rename from math/vendor/github.com/astaxie/beego/.travis.yml rename to golang/vendor/github.com/astaxie/beego/.travis.yml diff --git a/math/vendor/github.com/astaxie/beego/CONTRIBUTING.md b/golang/vendor/github.com/astaxie/beego/CONTRIBUTING.md similarity index 100% rename from math/vendor/github.com/astaxie/beego/CONTRIBUTING.md rename to golang/vendor/github.com/astaxie/beego/CONTRIBUTING.md diff --git a/math/vendor/github.com/astaxie/beego/LICENSE b/golang/vendor/github.com/astaxie/beego/LICENSE similarity index 100% rename from math/vendor/github.com/astaxie/beego/LICENSE rename to golang/vendor/github.com/astaxie/beego/LICENSE diff --git a/math/vendor/github.com/astaxie/beego/README.md b/golang/vendor/github.com/astaxie/beego/README.md similarity index 100% rename from math/vendor/github.com/astaxie/beego/README.md rename to golang/vendor/github.com/astaxie/beego/README.md diff --git a/math/vendor/github.com/astaxie/beego/admin.go b/golang/vendor/github.com/astaxie/beego/admin.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/admin.go rename to golang/vendor/github.com/astaxie/beego/admin.go diff --git a/math/vendor/github.com/astaxie/beego/adminui.go b/golang/vendor/github.com/astaxie/beego/adminui.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/adminui.go rename to golang/vendor/github.com/astaxie/beego/adminui.go diff --git a/math/vendor/github.com/astaxie/beego/app.go b/golang/vendor/github.com/astaxie/beego/app.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/app.go rename to golang/vendor/github.com/astaxie/beego/app.go diff --git a/math/vendor/github.com/astaxie/beego/beego.go b/golang/vendor/github.com/astaxie/beego/beego.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/beego.go rename to golang/vendor/github.com/astaxie/beego/beego.go diff --git a/math/vendor/github.com/astaxie/beego/config.go b/golang/vendor/github.com/astaxie/beego/config.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/config.go rename to golang/vendor/github.com/astaxie/beego/config.go diff --git a/math/vendor/github.com/astaxie/beego/config/config.go b/golang/vendor/github.com/astaxie/beego/config/config.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/config/config.go rename to golang/vendor/github.com/astaxie/beego/config/config.go diff --git a/math/vendor/github.com/astaxie/beego/config/fake.go b/golang/vendor/github.com/astaxie/beego/config/fake.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/config/fake.go rename to golang/vendor/github.com/astaxie/beego/config/fake.go diff --git a/math/vendor/github.com/astaxie/beego/config/ini.go b/golang/vendor/github.com/astaxie/beego/config/ini.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/config/ini.go rename to golang/vendor/github.com/astaxie/beego/config/ini.go diff --git a/math/vendor/github.com/astaxie/beego/config/json.go b/golang/vendor/github.com/astaxie/beego/config/json.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/config/json.go rename to golang/vendor/github.com/astaxie/beego/config/json.go diff --git a/math/vendor/github.com/astaxie/beego/context/acceptencoder.go b/golang/vendor/github.com/astaxie/beego/context/acceptencoder.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/acceptencoder.go rename to golang/vendor/github.com/astaxie/beego/context/acceptencoder.go diff --git a/math/vendor/github.com/astaxie/beego/context/context.go b/golang/vendor/github.com/astaxie/beego/context/context.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/context.go rename to golang/vendor/github.com/astaxie/beego/context/context.go diff --git a/math/vendor/github.com/astaxie/beego/context/input.go b/golang/vendor/github.com/astaxie/beego/context/input.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/input.go rename to golang/vendor/github.com/astaxie/beego/context/input.go diff --git a/math/vendor/github.com/astaxie/beego/context/output.go b/golang/vendor/github.com/astaxie/beego/context/output.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/output.go rename to golang/vendor/github.com/astaxie/beego/context/output.go diff --git a/math/vendor/github.com/astaxie/beego/context/param/conv.go b/golang/vendor/github.com/astaxie/beego/context/param/conv.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/param/conv.go rename to golang/vendor/github.com/astaxie/beego/context/param/conv.go diff --git a/math/vendor/github.com/astaxie/beego/context/param/methodparams.go b/golang/vendor/github.com/astaxie/beego/context/param/methodparams.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/param/methodparams.go rename to golang/vendor/github.com/astaxie/beego/context/param/methodparams.go diff --git a/math/vendor/github.com/astaxie/beego/context/param/options.go b/golang/vendor/github.com/astaxie/beego/context/param/options.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/param/options.go rename to golang/vendor/github.com/astaxie/beego/context/param/options.go diff --git a/math/vendor/github.com/astaxie/beego/context/param/parsers.go b/golang/vendor/github.com/astaxie/beego/context/param/parsers.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/param/parsers.go rename to golang/vendor/github.com/astaxie/beego/context/param/parsers.go diff --git a/math/vendor/github.com/astaxie/beego/context/renderer.go b/golang/vendor/github.com/astaxie/beego/context/renderer.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/renderer.go rename to golang/vendor/github.com/astaxie/beego/context/renderer.go diff --git a/math/vendor/github.com/astaxie/beego/context/response.go b/golang/vendor/github.com/astaxie/beego/context/response.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/context/response.go rename to golang/vendor/github.com/astaxie/beego/context/response.go diff --git a/math/vendor/github.com/astaxie/beego/controller.go b/golang/vendor/github.com/astaxie/beego/controller.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/controller.go rename to golang/vendor/github.com/astaxie/beego/controller.go diff --git a/math/vendor/github.com/astaxie/beego/doc.go b/golang/vendor/github.com/astaxie/beego/doc.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/doc.go rename to golang/vendor/github.com/astaxie/beego/doc.go diff --git a/math/vendor/github.com/astaxie/beego/error.go b/golang/vendor/github.com/astaxie/beego/error.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/error.go rename to golang/vendor/github.com/astaxie/beego/error.go diff --git a/math/vendor/github.com/astaxie/beego/filter.go b/golang/vendor/github.com/astaxie/beego/filter.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/filter.go rename to golang/vendor/github.com/astaxie/beego/filter.go diff --git a/math/vendor/github.com/astaxie/beego/flash.go b/golang/vendor/github.com/astaxie/beego/flash.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/flash.go rename to golang/vendor/github.com/astaxie/beego/flash.go diff --git a/math/vendor/github.com/astaxie/beego/fs.go b/golang/vendor/github.com/astaxie/beego/fs.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/fs.go rename to golang/vendor/github.com/astaxie/beego/fs.go diff --git a/math/vendor/github.com/astaxie/beego/go.mod b/golang/vendor/github.com/astaxie/beego/go.mod similarity index 100% rename from math/vendor/github.com/astaxie/beego/go.mod rename to golang/vendor/github.com/astaxie/beego/go.mod diff --git a/math/vendor/github.com/astaxie/beego/go.sum b/golang/vendor/github.com/astaxie/beego/go.sum similarity index 100% rename from math/vendor/github.com/astaxie/beego/go.sum rename to golang/vendor/github.com/astaxie/beego/go.sum diff --git a/math/vendor/github.com/astaxie/beego/grace/conn.go b/golang/vendor/github.com/astaxie/beego/grace/conn.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/grace/conn.go rename to golang/vendor/github.com/astaxie/beego/grace/conn.go diff --git a/math/vendor/github.com/astaxie/beego/grace/grace.go b/golang/vendor/github.com/astaxie/beego/grace/grace.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/grace/grace.go rename to golang/vendor/github.com/astaxie/beego/grace/grace.go diff --git a/math/vendor/github.com/astaxie/beego/grace/listener.go b/golang/vendor/github.com/astaxie/beego/grace/listener.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/grace/listener.go rename to golang/vendor/github.com/astaxie/beego/grace/listener.go diff --git a/math/vendor/github.com/astaxie/beego/grace/server.go b/golang/vendor/github.com/astaxie/beego/grace/server.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/grace/server.go rename to golang/vendor/github.com/astaxie/beego/grace/server.go diff --git a/math/vendor/github.com/astaxie/beego/hooks.go b/golang/vendor/github.com/astaxie/beego/hooks.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/hooks.go rename to golang/vendor/github.com/astaxie/beego/hooks.go diff --git a/math/vendor/github.com/astaxie/beego/log.go b/golang/vendor/github.com/astaxie/beego/log.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/log.go rename to golang/vendor/github.com/astaxie/beego/log.go diff --git a/math/vendor/github.com/astaxie/beego/logs/README.md b/golang/vendor/github.com/astaxie/beego/logs/README.md similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/README.md rename to golang/vendor/github.com/astaxie/beego/logs/README.md diff --git a/math/vendor/github.com/astaxie/beego/logs/accesslog.go b/golang/vendor/github.com/astaxie/beego/logs/accesslog.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/accesslog.go rename to golang/vendor/github.com/astaxie/beego/logs/accesslog.go diff --git a/math/vendor/github.com/astaxie/beego/logs/color.go b/golang/vendor/github.com/astaxie/beego/logs/color.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/color.go rename to golang/vendor/github.com/astaxie/beego/logs/color.go diff --git a/math/vendor/github.com/astaxie/beego/logs/color_windows.go b/golang/vendor/github.com/astaxie/beego/logs/color_windows.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/color_windows.go rename to golang/vendor/github.com/astaxie/beego/logs/color_windows.go diff --git a/math/vendor/github.com/astaxie/beego/logs/conn.go b/golang/vendor/github.com/astaxie/beego/logs/conn.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/conn.go rename to golang/vendor/github.com/astaxie/beego/logs/conn.go diff --git a/math/vendor/github.com/astaxie/beego/logs/console.go b/golang/vendor/github.com/astaxie/beego/logs/console.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/console.go rename to golang/vendor/github.com/astaxie/beego/logs/console.go diff --git a/math/vendor/github.com/astaxie/beego/logs/file.go b/golang/vendor/github.com/astaxie/beego/logs/file.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/file.go rename to golang/vendor/github.com/astaxie/beego/logs/file.go diff --git a/math/vendor/github.com/astaxie/beego/logs/jianliao.go b/golang/vendor/github.com/astaxie/beego/logs/jianliao.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/jianliao.go rename to golang/vendor/github.com/astaxie/beego/logs/jianliao.go diff --git a/math/vendor/github.com/astaxie/beego/logs/log.go b/golang/vendor/github.com/astaxie/beego/logs/log.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/log.go rename to golang/vendor/github.com/astaxie/beego/logs/log.go diff --git a/math/vendor/github.com/astaxie/beego/logs/logger.go b/golang/vendor/github.com/astaxie/beego/logs/logger.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/logger.go rename to golang/vendor/github.com/astaxie/beego/logs/logger.go diff --git a/math/vendor/github.com/astaxie/beego/logs/multifile.go b/golang/vendor/github.com/astaxie/beego/logs/multifile.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/multifile.go rename to golang/vendor/github.com/astaxie/beego/logs/multifile.go diff --git a/math/vendor/github.com/astaxie/beego/logs/slack.go b/golang/vendor/github.com/astaxie/beego/logs/slack.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/slack.go rename to golang/vendor/github.com/astaxie/beego/logs/slack.go diff --git a/math/vendor/github.com/astaxie/beego/logs/smtp.go b/golang/vendor/github.com/astaxie/beego/logs/smtp.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/logs/smtp.go rename to golang/vendor/github.com/astaxie/beego/logs/smtp.go diff --git a/math/vendor/github.com/astaxie/beego/mime.go b/golang/vendor/github.com/astaxie/beego/mime.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/mime.go rename to golang/vendor/github.com/astaxie/beego/mime.go diff --git a/math/vendor/github.com/astaxie/beego/namespace.go b/golang/vendor/github.com/astaxie/beego/namespace.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/namespace.go rename to golang/vendor/github.com/astaxie/beego/namespace.go diff --git a/math/vendor/github.com/astaxie/beego/parser.go b/golang/vendor/github.com/astaxie/beego/parser.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/parser.go rename to golang/vendor/github.com/astaxie/beego/parser.go diff --git a/math/vendor/github.com/astaxie/beego/policy.go b/golang/vendor/github.com/astaxie/beego/policy.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/policy.go rename to golang/vendor/github.com/astaxie/beego/policy.go diff --git a/math/vendor/github.com/astaxie/beego/router.go b/golang/vendor/github.com/astaxie/beego/router.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/router.go rename to golang/vendor/github.com/astaxie/beego/router.go diff --git a/math/vendor/github.com/astaxie/beego/session/README.md b/golang/vendor/github.com/astaxie/beego/session/README.md similarity index 100% rename from math/vendor/github.com/astaxie/beego/session/README.md rename to golang/vendor/github.com/astaxie/beego/session/README.md diff --git a/math/vendor/github.com/astaxie/beego/session/sess_cookie.go b/golang/vendor/github.com/astaxie/beego/session/sess_cookie.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/session/sess_cookie.go rename to golang/vendor/github.com/astaxie/beego/session/sess_cookie.go diff --git a/math/vendor/github.com/astaxie/beego/session/sess_file.go b/golang/vendor/github.com/astaxie/beego/session/sess_file.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/session/sess_file.go rename to golang/vendor/github.com/astaxie/beego/session/sess_file.go diff --git a/math/vendor/github.com/astaxie/beego/session/sess_mem.go b/golang/vendor/github.com/astaxie/beego/session/sess_mem.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/session/sess_mem.go rename to golang/vendor/github.com/astaxie/beego/session/sess_mem.go diff --git a/math/vendor/github.com/astaxie/beego/session/sess_utils.go b/golang/vendor/github.com/astaxie/beego/session/sess_utils.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/session/sess_utils.go rename to golang/vendor/github.com/astaxie/beego/session/sess_utils.go diff --git a/math/vendor/github.com/astaxie/beego/session/session.go b/golang/vendor/github.com/astaxie/beego/session/session.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/session/session.go rename to golang/vendor/github.com/astaxie/beego/session/session.go diff --git a/math/vendor/github.com/astaxie/beego/staticfile.go b/golang/vendor/github.com/astaxie/beego/staticfile.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/staticfile.go rename to golang/vendor/github.com/astaxie/beego/staticfile.go diff --git a/math/vendor/github.com/astaxie/beego/template.go b/golang/vendor/github.com/astaxie/beego/template.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/template.go rename to golang/vendor/github.com/astaxie/beego/template.go diff --git a/math/vendor/github.com/astaxie/beego/templatefunc.go b/golang/vendor/github.com/astaxie/beego/templatefunc.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/templatefunc.go rename to golang/vendor/github.com/astaxie/beego/templatefunc.go diff --git a/math/vendor/github.com/astaxie/beego/toolbox/healthcheck.go b/golang/vendor/github.com/astaxie/beego/toolbox/healthcheck.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/toolbox/healthcheck.go rename to golang/vendor/github.com/astaxie/beego/toolbox/healthcheck.go diff --git a/math/vendor/github.com/astaxie/beego/toolbox/profile.go b/golang/vendor/github.com/astaxie/beego/toolbox/profile.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/toolbox/profile.go rename to golang/vendor/github.com/astaxie/beego/toolbox/profile.go diff --git a/math/vendor/github.com/astaxie/beego/toolbox/statistics.go b/golang/vendor/github.com/astaxie/beego/toolbox/statistics.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/toolbox/statistics.go rename to golang/vendor/github.com/astaxie/beego/toolbox/statistics.go diff --git a/math/vendor/github.com/astaxie/beego/toolbox/task.go b/golang/vendor/github.com/astaxie/beego/toolbox/task.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/toolbox/task.go rename to golang/vendor/github.com/astaxie/beego/toolbox/task.go diff --git a/math/vendor/github.com/astaxie/beego/tree.go b/golang/vendor/github.com/astaxie/beego/tree.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/tree.go rename to golang/vendor/github.com/astaxie/beego/tree.go diff --git a/math/vendor/github.com/astaxie/beego/utils/caller.go b/golang/vendor/github.com/astaxie/beego/utils/caller.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/caller.go rename to golang/vendor/github.com/astaxie/beego/utils/caller.go diff --git a/math/vendor/github.com/astaxie/beego/utils/debug.go b/golang/vendor/github.com/astaxie/beego/utils/debug.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/debug.go rename to golang/vendor/github.com/astaxie/beego/utils/debug.go diff --git a/math/vendor/github.com/astaxie/beego/utils/file.go b/golang/vendor/github.com/astaxie/beego/utils/file.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/file.go rename to golang/vendor/github.com/astaxie/beego/utils/file.go diff --git a/math/vendor/github.com/astaxie/beego/utils/mail.go b/golang/vendor/github.com/astaxie/beego/utils/mail.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/mail.go rename to golang/vendor/github.com/astaxie/beego/utils/mail.go diff --git a/math/vendor/github.com/astaxie/beego/utils/rand.go b/golang/vendor/github.com/astaxie/beego/utils/rand.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/rand.go rename to golang/vendor/github.com/astaxie/beego/utils/rand.go diff --git a/math/vendor/github.com/astaxie/beego/utils/safemap.go b/golang/vendor/github.com/astaxie/beego/utils/safemap.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/safemap.go rename to golang/vendor/github.com/astaxie/beego/utils/safemap.go diff --git a/math/vendor/github.com/astaxie/beego/utils/slice.go b/golang/vendor/github.com/astaxie/beego/utils/slice.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/slice.go rename to golang/vendor/github.com/astaxie/beego/utils/slice.go diff --git a/math/vendor/github.com/astaxie/beego/utils/utils.go b/golang/vendor/github.com/astaxie/beego/utils/utils.go similarity index 100% rename from math/vendor/github.com/astaxie/beego/utils/utils.go rename to golang/vendor/github.com/astaxie/beego/utils/utils.go diff --git a/math/vendor/golang.org/x/crypto/AUTHORS b/golang/vendor/golang.org/x/crypto/AUTHORS similarity index 100% rename from math/vendor/golang.org/x/crypto/AUTHORS rename to golang/vendor/golang.org/x/crypto/AUTHORS diff --git a/math/vendor/golang.org/x/crypto/CONTRIBUTORS b/golang/vendor/golang.org/x/crypto/CONTRIBUTORS similarity index 100% rename from math/vendor/golang.org/x/crypto/CONTRIBUTORS rename to golang/vendor/golang.org/x/crypto/CONTRIBUTORS diff --git a/math/vendor/golang.org/x/crypto/LICENSE b/golang/vendor/golang.org/x/crypto/LICENSE similarity index 100% rename from math/vendor/golang.org/x/crypto/LICENSE rename to golang/vendor/golang.org/x/crypto/LICENSE diff --git a/math/vendor/golang.org/x/crypto/PATENTS b/golang/vendor/golang.org/x/crypto/PATENTS similarity index 100% rename from math/vendor/golang.org/x/crypto/PATENTS rename to golang/vendor/golang.org/x/crypto/PATENTS diff --git a/math/vendor/golang.org/x/crypto/acme/acme.go b/golang/vendor/golang.org/x/crypto/acme/acme.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/acme.go rename to golang/vendor/golang.org/x/crypto/acme/acme.go diff --git a/math/vendor/golang.org/x/crypto/acme/autocert/autocert.go b/golang/vendor/golang.org/x/crypto/acme/autocert/autocert.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/autocert/autocert.go rename to golang/vendor/golang.org/x/crypto/acme/autocert/autocert.go diff --git a/math/vendor/golang.org/x/crypto/acme/autocert/cache.go b/golang/vendor/golang.org/x/crypto/acme/autocert/cache.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/autocert/cache.go rename to golang/vendor/golang.org/x/crypto/acme/autocert/cache.go diff --git a/math/vendor/golang.org/x/crypto/acme/autocert/listener.go b/golang/vendor/golang.org/x/crypto/acme/autocert/listener.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/autocert/listener.go rename to golang/vendor/golang.org/x/crypto/acme/autocert/listener.go diff --git a/math/vendor/golang.org/x/crypto/acme/autocert/renewal.go b/golang/vendor/golang.org/x/crypto/acme/autocert/renewal.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/autocert/renewal.go rename to golang/vendor/golang.org/x/crypto/acme/autocert/renewal.go diff --git a/math/vendor/golang.org/x/crypto/acme/http.go b/golang/vendor/golang.org/x/crypto/acme/http.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/http.go rename to golang/vendor/golang.org/x/crypto/acme/http.go diff --git a/math/vendor/golang.org/x/crypto/acme/jws.go b/golang/vendor/golang.org/x/crypto/acme/jws.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/jws.go rename to golang/vendor/golang.org/x/crypto/acme/jws.go diff --git a/math/vendor/golang.org/x/crypto/acme/types.go b/golang/vendor/golang.org/x/crypto/acme/types.go similarity index 100% rename from math/vendor/golang.org/x/crypto/acme/types.go rename to golang/vendor/golang.org/x/crypto/acme/types.go diff --git a/math/vendor/gopkg.in/yaml.v2/.travis.yml b/golang/vendor/gopkg.in/yaml.v2/.travis.yml similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/.travis.yml rename to golang/vendor/gopkg.in/yaml.v2/.travis.yml diff --git a/math/vendor/gopkg.in/yaml.v2/LICENSE b/golang/vendor/gopkg.in/yaml.v2/LICENSE similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/LICENSE rename to golang/vendor/gopkg.in/yaml.v2/LICENSE diff --git a/math/vendor/gopkg.in/yaml.v2/LICENSE.libyaml b/golang/vendor/gopkg.in/yaml.v2/LICENSE.libyaml similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/LICENSE.libyaml rename to golang/vendor/gopkg.in/yaml.v2/LICENSE.libyaml diff --git a/math/vendor/gopkg.in/yaml.v2/NOTICE b/golang/vendor/gopkg.in/yaml.v2/NOTICE similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/NOTICE rename to golang/vendor/gopkg.in/yaml.v2/NOTICE diff --git a/math/vendor/gopkg.in/yaml.v2/README.md b/golang/vendor/gopkg.in/yaml.v2/README.md similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/README.md rename to golang/vendor/gopkg.in/yaml.v2/README.md diff --git a/math/vendor/gopkg.in/yaml.v2/apic.go b/golang/vendor/gopkg.in/yaml.v2/apic.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/apic.go rename to golang/vendor/gopkg.in/yaml.v2/apic.go diff --git a/math/vendor/gopkg.in/yaml.v2/decode.go b/golang/vendor/gopkg.in/yaml.v2/decode.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/decode.go rename to golang/vendor/gopkg.in/yaml.v2/decode.go diff --git a/math/vendor/gopkg.in/yaml.v2/emitterc.go b/golang/vendor/gopkg.in/yaml.v2/emitterc.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/emitterc.go rename to golang/vendor/gopkg.in/yaml.v2/emitterc.go diff --git a/math/vendor/gopkg.in/yaml.v2/encode.go b/golang/vendor/gopkg.in/yaml.v2/encode.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/encode.go rename to golang/vendor/gopkg.in/yaml.v2/encode.go diff --git a/math/vendor/gopkg.in/yaml.v2/go.mod b/golang/vendor/gopkg.in/yaml.v2/go.mod similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/go.mod rename to golang/vendor/gopkg.in/yaml.v2/go.mod diff --git a/math/vendor/gopkg.in/yaml.v2/parserc.go b/golang/vendor/gopkg.in/yaml.v2/parserc.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/parserc.go rename to golang/vendor/gopkg.in/yaml.v2/parserc.go diff --git a/math/vendor/gopkg.in/yaml.v2/readerc.go b/golang/vendor/gopkg.in/yaml.v2/readerc.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/readerc.go rename to golang/vendor/gopkg.in/yaml.v2/readerc.go diff --git a/math/vendor/gopkg.in/yaml.v2/resolve.go b/golang/vendor/gopkg.in/yaml.v2/resolve.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/resolve.go rename to golang/vendor/gopkg.in/yaml.v2/resolve.go diff --git a/math/vendor/gopkg.in/yaml.v2/scannerc.go b/golang/vendor/gopkg.in/yaml.v2/scannerc.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/scannerc.go rename to golang/vendor/gopkg.in/yaml.v2/scannerc.go diff --git a/math/vendor/gopkg.in/yaml.v2/sorter.go b/golang/vendor/gopkg.in/yaml.v2/sorter.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/sorter.go rename to golang/vendor/gopkg.in/yaml.v2/sorter.go diff --git a/math/vendor/gopkg.in/yaml.v2/writerc.go b/golang/vendor/gopkg.in/yaml.v2/writerc.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/writerc.go rename to golang/vendor/gopkg.in/yaml.v2/writerc.go diff --git a/math/vendor/gopkg.in/yaml.v2/yaml.go b/golang/vendor/gopkg.in/yaml.v2/yaml.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/yaml.go rename to golang/vendor/gopkg.in/yaml.v2/yaml.go diff --git a/math/vendor/gopkg.in/yaml.v2/yamlh.go b/golang/vendor/gopkg.in/yaml.v2/yamlh.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/yamlh.go rename to golang/vendor/gopkg.in/yaml.v2/yamlh.go diff --git a/math/vendor/gopkg.in/yaml.v2/yamlprivateh.go b/golang/vendor/gopkg.in/yaml.v2/yamlprivateh.go similarity index 100% rename from math/vendor/gopkg.in/yaml.v2/yamlprivateh.go rename to golang/vendor/gopkg.in/yaml.v2/yamlprivateh.go diff --git a/math/vendor/modules.txt b/golang/vendor/modules.txt similarity index 100% rename from math/vendor/modules.txt rename to golang/vendor/modules.txt diff --git a/math/views/invalid-route.html b/golang/views/invalid-route.html similarity index 100% rename from math/views/invalid-route.html rename to golang/views/invalid-route.html diff --git a/math/views/result.html b/golang/views/result.html similarity index 100% rename from math/views/result.html rename to golang/views/result.html diff --git a/helm/.dockerignore b/helm/.dockerignore new file mode 100644 index 0000000..97a398a --- /dev/null +++ b/helm/.dockerignore @@ -0,0 +1 @@ +okteto.yml \ No newline at end of file diff --git a/helm/README.md b/helm/README.md new file mode 100644 index 0000000..96b060b --- /dev/null +++ b/helm/README.md @@ -0,0 +1,52 @@ +# Voting App + +Example helm + python app + +A simple helm chart that deploys a Python app (using Flask) to demo the power of [okteto](https:/okteto.com). + +This example works in any Kubernetes cluster. Cloud Native Development provides more value in remote Kubernetes clusters, but in order to make it simple to follow this guide, we recommend to use Docker for Mac (with Kubernetes support) or [minikube](https://github.com/kubernetes/minikube). + +For this example you also need to have helm installed and configured in your cluster. + + +## Deploy the chart + +Clone the repository and go to the python-helm folder. + +```console +git clone https://github.com/okteto/samples +cd samples/helm +``` + +Deploy the Voting chart using the following command: +```console +helm install --name vote ./chart/vote +``` + +Wait for one or two minutes until the application is running. + +## Develop as a Cloud Native Developer + +In order to activate your Cloud Native Development, execute: + +```console +okteto up +``` + +The `okteto up` command will start a remote development environment that automatically synchronizes and applies your code changes without rebuilding containers (eliminating the **docker build/push/pull/redeploy** cycle). + +Edit the file `vote/app.py` and change the `option_a` in line 8 from "Cats" to "Otters". Save your changes. + +Finally, refresh the Voting App UI, and cool! your code changes are live! + +## Cleanup + +Cancel the `okteto up` command by pressing `ctrl + c` and run the following command to remove the resources created by this guide: + +```console +helm delete --purge vote +``` + + + + diff --git a/vscode-ssh/app.py b/helm/app.py similarity index 72% rename from vscode-ssh/app.py rename to helm/app.py index 6057ac4..fce21d9 100644 --- a/vscode-ssh/app.py +++ b/helm/app.py @@ -3,22 +3,18 @@ import socket import random import json -import collections +option_a = os.getenv('OPTION_A', 'Cats') +option_b = os.getenv('OPTION_B', 'Dogs') hostname = socket.gethostname() -votes = collections.defaultdict(int) +namespace = os.getenv('CND_KUBERNETES_NAMESPACE', 'localhost') +votes = {option_a: 0, option_b: 0} app = Flask(__name__) -def getOptions(): - option_a = 'Cats' - option_b = 'Dogs' - return option_a, option_b - @app.route("/", methods=['POST','GET']) def hello(): vote = None - option_a, option_b = getOptions() if request.method == 'POST': vote = request.form['vote'] vote = option_a if vote == "a" else option_b @@ -30,9 +26,10 @@ def hello(): hostname=hostname, votes_a=votes[option_a], votes_b=votes[option_b], + namespace=namespace )) return resp if __name__ == "__main__": - app.run(host='0.0.0.0', port=8080, debug=True) + app.run(host='0.0.0.0', port=80, debug=True) diff --git a/helm/chart/vote/.helmignore b/helm/chart/vote/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/chart/vote/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/chart/vote/Chart.yaml b/helm/chart/vote/Chart.yaml new file mode 100644 index 0000000..7b0a1f8 --- /dev/null +++ b/helm/chart/vote/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "1.0" +description: A voting app +name: vote +version: 0.1.0 diff --git a/helm/chart/vote/templates/NOTES.txt b/helm/chart/vote/templates/NOTES.txt new file mode 100644 index 0000000..c331aa0 --- /dev/null +++ b/helm/chart/vote/templates/NOTES.txt @@ -0,0 +1,19 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "mychart.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ include "mychart.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "mychart.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "mychart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/helm/chart/vote/templates/_helpers.tpl b/helm/chart/vote/templates/_helpers.tpl new file mode 100644 index 0000000..7ba0e4f --- /dev/null +++ b/helm/chart/vote/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "mychart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "mychart.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "mychart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/helm/chart/vote/templates/deployment.yaml b/helm/chart/vote/templates/deployment.yaml new file mode 100644 index 0000000..f1bc69e --- /dev/null +++ b/helm/chart/vote/templates/deployment.yaml @@ -0,0 +1,53 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "mychart.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "mychart.name" . }} + helm.sh/chart: {{ include "mychart.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "mychart.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "mychart.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: +{{ toYaml .Values.resources | indent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/helm/chart/vote/templates/service.yaml b/helm/chart/vote/templates/service.yaml new file mode 100644 index 0000000..86082a8 --- /dev/null +++ b/helm/chart/vote/templates/service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mychart.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "mychart.name" . }} + helm.sh/chart: {{ include "mychart.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "mychart.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/helm/chart/vote/values.yaml b/helm/chart/vote/values.yaml new file mode 100644 index 0000000..5a5532a --- /dev/null +++ b/helm/chart/vote/values.yaml @@ -0,0 +1,35 @@ +# Default values for mychart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: okteto/vote + tag: "latest" + pullPolicy: IfNotPresent + +nameOverride: "" +fullnameOverride: "" + +service: + type: ClusterIP + port: 8080 + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/cloud-run/okteto.yml b/helm/okteto.yml similarity index 61% rename from cloud-run/okteto.yml rename to helm/okteto.yml index ad67390..a9f360d 100644 --- a/cloud-run/okteto.yml +++ b/helm/okteto.yml @@ -1,4 +1,5 @@ name: vote -image: okteto/dev-cloud-run:latest -workdir: /src command: ["python", "app.py"] +workdir: /src +forward: + - 8080:8080 diff --git a/cloud-run/requirements.txt b/helm/requirements.txt similarity index 100% rename from cloud-run/requirements.txt rename to helm/requirements.txt diff --git a/vote/static/stylesheets/style.css b/helm/static/stylesheets/style.css similarity index 100% rename from vote/static/stylesheets/style.css rename to helm/static/stylesheets/style.css diff --git a/cloud-run/templates/index.html b/helm/templates/index.html similarity index 95% rename from cloud-run/templates/index.html rename to helm/templates/index.html index 5dac042..58f9669 100644 --- a/cloud-run/templates/index.html +++ b/helm/templates/index.html @@ -20,7 +20,7 @@

{{option_a}} vs {{option_b}}!

{{votes_a}} vs {{votes_b}}

- Processed by container ID {{hostname}} +

Processed by {{namespace}}\{{hostname}}

diff --git a/java/.dockerignore b/java/.dockerignore new file mode 100644 index 0000000..f06dfad --- /dev/null +++ b/java/.dockerignore @@ -0,0 +1,2 @@ +.gradle +build \ No newline at end of file diff --git a/java/.gitignore b/java/.gitignore new file mode 100644 index 0000000..151fdd4 --- /dev/null +++ b/java/.gitignore @@ -0,0 +1,2 @@ +build +.gradle \ No newline at end of file diff --git a/java/.stignore b/java/.stignore new file mode 100644 index 0000000..6fbe8a4 --- /dev/null +++ b/java/.stignore @@ -0,0 +1,2 @@ +/.gradle +/build \ No newline at end of file diff --git a/java/Dockerfile b/java/Dockerfile new file mode 100644 index 0000000..a664168 --- /dev/null +++ b/java/Dockerfile @@ -0,0 +1,13 @@ +FROM gradle:5.1-jdk11 as builder + +RUN mkdir -p /home/gradle/src +COPY --chown=gradle:gradle build.gradle /home/gradle +COPY --chown=gradle:gradle src /home/gradle/src +WORKDIR /home/gradle +RUN gradle build + +FROM openjdk:11-jre-slim +EXPOSE 8080 +WORKDIR /app +COPY --from=builder /home/gradle/build/libs/*.jar . +CMD java -jar *.jar \ No newline at end of file diff --git a/java/README.md b/java/README.md new file mode 100644 index 0000000..841f1d6 --- /dev/null +++ b/java/README.md @@ -0,0 +1,107 @@ +# Payroll + +This example shows how to develop a Spring Boot Java application with [okteto](https://okteto.com). It's based on [Spring's gs-rest-service example](https://github.com/spring-guides/gs-rest-service). + +This example works in any Kubernetes cluster. Cloud Native Development provides more value in remote Kubernetes clusters, but in order to make it simple to follow this guide, we recommend to use Docker for Mac (with Kubernetes support) or [minikube](https://github.com/kubernetes/minikube). + +## Deploy the payroll service + +Clone the repository and go to the java-kubectl folder. + +```console +git clone https://github.com/okteto/samples +cd samples/java +``` + +Deploy the Payroll application by using the following command: +```console +kubectl apply -f manifests +``` + +## Cloud native development + +In order to activate your Cloud Native Development, execute: + +```console +okteto up +``` + +The `okteto up` command will start a remote development environment that automatically synchronizes and applies your code changes without rebuilding containers (eliminating the **docker build/push/pull/redeploy** cycle). + +This development environment includes java dev tools (e.g. gradle) and it's configured to automatically compile your code directly on the cluster every time you make a change. It will also start forwarding port 8080 to your local machine. + +On a second terminal screen execute the command below. This will run the `boot` script as defined by the user on [`okteto.yml`](payroll/okteto.yml). The boot script will run `gradle bootRun` directly in the cluster. The command will start your service and reload it automatically after every successful compilation. + +```console +okteto run boot +``` + +Verify that everything is up and running by calling the `/employees` endpoint from your local machine: +```console +curl http://localhost:8080/employees +``` + +The response to a successful request is a list of employees: +```json +[ + {"id":1,"name":"Pablo Chico de Guzman"},{"id":2,"name":"Ramon Lamana"}, + {"id":3,"name":"Ramiro Berrelleza"},{"id":4,"name":"Cindy Lopez"} +] +``` + +You can also get a single employee by passing an employee ID: +```console +curl http://localhost:8080/employees/4 +``` +```json +{ + "id":4, + "name":"Cindy Lopez" +} +``` + + Time to write some code. Let's say that the company just hired employee #5, and you're tasked with adding her to the employee list. First, we'll check and see if someone else already took care of the work by calling the API: + + ```console +curl http://localhost:8080/employees/5 +``` +```json +{ + "timestamp":"2019-01-12T04:36:29.225+0000", + "status":404, + "error":"Not Found", + "message":"employee not found", + "path":"/employees/5" +} +``` + + Alright, the new employee is not yet in the system. Open [payroll/src/main/java/payroll/PayrollController.java](payroll/src/main/java/payroll/PayrollController.java) with your favorite IDE. Add the new employee to the list (look around line 20) and save your changes. + ```java + ... + this.employees.put(4, new Employee(4, "Cindy Lopez")); + this.employees.put(5, new Employee(5, "Alexandra Greyson")); +... + ``` + + Go back to your terminal and call API again: +```console +curl http://localhost:8080/employees/5 +``` +```json +{ + "id":5, + "name":"Alexandra Greyson" +} +``` + +Your changes were automatically applied, no docker, kubectl or even a local jvm required 💪! + +*review [okteto's usage](https://okteto.com/docs/reference/cli) guide to see other commands available to help you speed you up your development.* + +## Cleanup + +Cancel the `okteto up` command by pressing `ctrl + c` and run the following command to remove the resources created by this guide: + +```console +kubectl delete -f manifests +``` \ No newline at end of file diff --git a/java/build.gradle b/java/build.gradle new file mode 100644 index 0000000..7b3e15a --- /dev/null +++ b/java/build.gradle @@ -0,0 +1,46 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE") + } +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + +bootJar { + baseName = 'payroll' + version = '0.1.0' +} + +repositories { + mavenCentral() +} + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +configurations { + dev +} + +dependencies { + compile("org.springframework.boot:spring-boot-starter-web") + // tag::actuator[] + compile("org.springframework.boot:spring-boot-starter-actuator") + // end::actuator[] + // tag::tests[] + dev("org.springframework.boot:spring-boot-devtools") + + testCompile("org.springframework.boot:spring-boot-starter-test") + // end::tests[] +} + +bootRun { + classpath = sourceSets.main.runtimeClasspath + configurations.dev +} \ No newline at end of file diff --git a/java/docker-compose.yml b/java/docker-compose.yml new file mode 100644 index 0000000..0628f2e --- /dev/null +++ b/java/docker-compose.yml @@ -0,0 +1,10 @@ +version: "3.4" +services: + dev: + image: okteto/payroll:0.1-dev + build: + context: . + target: builder + prod: + image: okteto/payroll:0.1 + build: . diff --git a/java/manifests/deployment.yaml b/java/manifests/deployment.yaml new file mode 100644 index 0000000..0663167 --- /dev/null +++ b/java/manifests/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: payroll + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + replicas: 1 + selector: + matchLabels: + app: payroll + template: + metadata: + labels: + app: payroll + spec: + containers: + - image: okteto/payroll:latest + name: payroll \ No newline at end of file diff --git a/java/manifests/service.yaml b/java/manifests/service.yaml new file mode 100644 index 0000000..800d225 --- /dev/null +++ b/java/manifests/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: payroll + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + type: ClusterIP + ports: + - name: "payroll" + port: 8080 + selector: + app: payroll diff --git a/java/okteto.yml b/java/okteto.yml new file mode 100644 index 0000000..44d437a --- /dev/null +++ b/java/okteto.yml @@ -0,0 +1,11 @@ +name: payroll +image: okteto/payroll:0.1-dev +runAsUser: 1000 +command: +- gradle +- build +- -continuous +- --scan +workdir: /home/gradle +forward: + - 8080:8080 diff --git a/java/src/main/java/payroll/Application.java b/java/src/main/java/payroll/Application.java new file mode 100644 index 0000000..5448b29 --- /dev/null +++ b/java/src/main/java/payroll/Application.java @@ -0,0 +1,24 @@ +package payroll; + +import java.util.Arrays; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + public CommandLineRunner commandLineRunner(ApplicationContext ctx) { + return args -> { + }; + } + +} diff --git a/java/src/main/java/payroll/Employee.java b/java/src/main/java/payroll/Employee.java new file mode 100644 index 0000000..9fe0758 --- /dev/null +++ b/java/src/main/java/payroll/Employee.java @@ -0,0 +1,21 @@ +package payroll ; + +public class Employee { + + private final int id; + private final String name; + + public Employee(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + +} \ No newline at end of file diff --git a/java/src/main/java/payroll/PayrollController.java b/java/src/main/java/payroll/PayrollController.java new file mode 100644 index 0000000..2695a4e --- /dev/null +++ b/java/src/main/java/payroll/PayrollController.java @@ -0,0 +1,49 @@ +package payroll; + +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Collection; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.http.HttpStatus; + +@RestController +public class PayrollController { + + private Map employees; + + public PayrollController() { + this.employees = new HashMap(); + this.employees.put(1, new Employee(1, "Pablo Chico de Guzman")); + this.employees.put(2, new Employee(2, "Ramon Lamana")); + this.employees.put(3, new Employee(3, "Ramiro Berrelleza")); + this.employees.put(4, new Employee(4, "Cindy Lopez")); + } + + @RequestMapping("/") + public String index() { + return "Greetings from Spring Boot!"; + } + + @RequestMapping("/employees") + public Collection getAll() { + return this.employees.values(); + } + + @RequestMapping("/employees/{employeeID}") + public Employee get(@PathVariable(value="employeeID") final int id) throws EmployeeNotFoundException { + if (this.employees.containsKey(id)) { + return this.employees.get(id); + } else{ + throw new EmployeeNotFoundException(); + } + } + + @ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "employee not found") + public class EmployeeNotFoundException extends RuntimeException { +} +} diff --git a/java/src/test/java/payroll/PayrollControllerTest.java b/java/src/test/java/payroll/PayrollControllerTest.java new file mode 100644 index 0000000..2a7869b --- /dev/null +++ b/java/src/test/java/payroll/PayrollControllerTest.java @@ -0,0 +1,38 @@ +package payroll; + +import static org.hamcrest.Matchers.equalTo; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class PayrollControllerTest { + + @Autowired + private MockMvc mvc; + + @Test + public void getHello() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(equalTo("Greetings from Spring Boot!"))); + } + + @Test + public void getAll() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/employees").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + } +} diff --git a/math/README.md b/math/README.md deleted file mode 100644 index 4e83e65..0000000 --- a/math/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# Math App - -This example shows how to leverage [Okteto](https://cloud.okteto.com) to develop a golang app directly in the cloud. - -## Step 1: Install the Okteto CLI - -Install the Okteto CLI by running the following command in your local terminal: - -MacOS/Linux - -```console -curl https://get.okteto.com -sSfL | sh -``` - -Windows - -```console -wget https://downloads.okteto.com/cli/okteto-Windows-x86_64 -OutFile c:\windows\system32\okteto.exe -``` - -## Step 2: Login from the Okteto CLI - -```console -$ okteto login -``` - -This will give you an Okteto Space, where you can create Okteto Environments to code and collaborate. - -## Step 3: Create your Okteto Environment - -Get a local version of the sample application by executing the following commands in your local terminal: - -```console -$ git clone https://github.com/okteto/cloud-samples -$ cd cloud-samples/math -``` - -You now have a functioning git repository that contains a simple golang application. Now start your Okteto Environment by running the following command: - -```console -$ okteto up -``` - -The `okteto up` command will automatically start an Okteto Environment. It will also start a file synchronization service to keep your changes up to date between your local filesystem and your Okteto Environment. - - - -Once the Okteto Environment is ready, start your application by executing the following command in your Okteto Terminal: - -```console -okteto> go run main.go -``` - -Your application is now ready to be tested. You can check it by browsing the application's endpoint, adding the path `/mult/3/4`. In our case, it would be the endpoint `https://damp-darkness.rberrelleza.cloud.okteto.net/mult/3/4`. - -> Note that Okteto creates a public HTTPS endpoint forwarding to the port 8080 of your application. - -Congratulations, you just deployed your first Okteto Application 🚀! - -## Step 4: Develop directly in the cloud - -Now things get more exciting. Edit the file `math/main.go` and switch the word `mult` by `times` at line 43. Save your changes. Cancel the execution of `go run main.go` from your Okteto Terminal by pressing `ctrl + c`. Run your tests to check that everything is fine with your changes: - -```console -okteto> go test ./... -``` - -And finally rerun your application: - -```console -okteto> go run main.go -``` - -In just seconds, your code changes are live! Check it by accessing the path `/times/3/4` of your application endpoint. No commit or push required 😎! - -## Step 5: Deploy your application - -Now that you are happy with your changes, it's time to run your updated application with the `okteto run` command. Instead of launching an Okteto Environment and synchronizing your files, the `okteto run` command automatically deploys a container into your Okteto Space. - -Let's build a Docker image with your latest changes. Press `ctrl + c` and `ctrl + d` in your Okteto Terminal to go back to your local terminal, and execute the following command to build your docker image and push it to [Docker Hub](https://docs.docker.com/docker-hub/repos/): - -```console -$ docker build -t \math -$ docker push \math -``` - -> If you don't have access to Docker Hub, you can use `okteto/math:0.1.0` instead of your own docker image to complete this step. - -Once your image is ready, run the following command to deploy your container: - -```console -$ okteto run \math -``` - -After a couple of seconds, your application will be ready. Go back to the browser and reload the page to see your new docker container up and running. - -> `okteto run` only supports images from public docker repositories. [Contact us](mailto:sales@okteto.com?Subject=Support%20for%20private%20images) if you're interested in support for private images diff --git a/math/go.sum b/math/go.sum deleted file mode 100644 index 1a03013..0000000 --- a/math/go.sum +++ /dev/null @@ -1,36 +0,0 @@ -github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/astaxie/beego v1.11.1 h1:6DESefxW5oMcRLFRKi53/6exzup/IR6N4EzzS1n6CnQ= -github.com/astaxie/beego v1.11.1/go.mod h1:i69hVzgauOPSw5qeyF4GVZhn7Od0yG5bbCGzmhbWxgQ= -github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= -github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= -github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff/go.mod h1:PhH1ZhyCzHKt4uAasyx+ljRCgoezetRNf59CUtwUkqY= -github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= -github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= -github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= -github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= -github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= -github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= -github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= -github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= -github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= -github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= -github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= -github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= -github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= -github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= -golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 h1:et7+NAX3lLIk5qUCTA9QelBjGE/NkhzYw/mhnr0s7nI= -golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/math/images/okteto-up.png b/math/images/okteto-up.png deleted file mode 100644 index 76e2aec..0000000 Binary files a/math/images/okteto-up.png and /dev/null differ diff --git a/math/okteto.yml b/math/okteto.yml deleted file mode 100644 index 2afc35d..0000000 --- a/math/okteto.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: curly-river -image: okteto/golang:1 -command: -- bash -workdir: /go/src/app diff --git a/movies/images/movies-frontend.jpg b/movies/images/movies-frontend.jpg deleted file mode 100644 index ef2f537..0000000 Binary files a/movies/images/movies-frontend.jpg and /dev/null differ diff --git a/movies/images/okteflix.gif b/movies/images/okteflix.gif deleted file mode 100644 index 871bc61..0000000 Binary files a/movies/images/okteflix.gif and /dev/null differ diff --git a/movies/images/okteto-ui-full.png b/movies/images/okteto-ui-full.png deleted file mode 100644 index 0418d2d..0000000 Binary files a/movies/images/okteto-ui-full.png and /dev/null differ diff --git a/movies/images/okteto-ui.png b/movies/images/okteto-ui.png deleted file mode 100644 index 2c3dd81..0000000 Binary files a/movies/images/okteto-ui.png and /dev/null differ diff --git a/movies/images/okteto-up.png b/movies/images/okteto-up.png deleted file mode 100644 index 6bd7687..0000000 Binary files a/movies/images/okteto-up.png and /dev/null differ diff --git a/movies/README.md b/node/README.md similarity index 91% rename from movies/README.md rename to node/README.md index ad4d1c6..2479035 100644 --- a/movies/README.md +++ b/node/README.md @@ -25,20 +25,12 @@ wget https://downloads.okteto.com/cli/okteto-Windows-x86_64 -OutFile c:\windows\ ``` -## Step 2: Login from the Okteto CLI - -```console -$ okteto login -``` - -This command will give you an Okteto Space, where you can create Okteto Environments to code and collaborate. - -## Step 3: Create your Okteto Environments +## Step 2: Create your Okteto Environments Clone the samples repository: ```console -$ git clone https://github.com/okteto/cloud-samples +$ git clone https://github.com/okteto/samples ``` Now that you have the application code in your local machine, let's create an Okteto Environments to run the application directly in the cluster. @@ -48,7 +40,7 @@ Now that you have the application code in your local machine, let's create an Ok Move to the movies front-end code directory: ```console -$ cd cloud-samples/movies/frontend +$ cd samples/movies/frontend ``` From the frontend's root directory, launch the following command: @@ -90,7 +82,7 @@ $ okteto database mongo Now we need the API service for the frontend to connect to. Open a new terminal, go to the API's source directory, and run the Okteto CLI again to create a second environment: ```console -$ cd cloud-samples/movies/api +$ cd samples/movies/api $ okteto run okteto/movies:api ``` @@ -102,7 +94,7 @@ Congratulations, you just deployed your first multi-service application using Ok

-## Step 4: Develop directly in the cloud +## Step 3: Develop directly in the cloud Now things get even more exciting. You can now develop *directly in the cluster*. The API service and database will be available at all times. No need to mock services nor use any kind of redirection. @@ -112,7 +104,7 @@ Go back to the browser, and cool! Your changes are automatically live with no ne

-## Step 5: Deploy your application +## Step 4: Deploy your application Now that you are happy with your changes, it is time to deploy them. diff --git a/movies/api/.stignore b/node/api/.stignore similarity index 100% rename from movies/api/.stignore rename to node/api/.stignore diff --git a/movies/api/Dockerfile b/node/api/Dockerfile similarity index 100% rename from movies/api/Dockerfile rename to node/api/Dockerfile diff --git a/movies/api/data/movie.json b/node/api/data/movie.json similarity index 100% rename from movies/api/data/movie.json rename to node/api/data/movie.json diff --git a/movies/api/data/mylist.json b/node/api/data/mylist.json similarity index 100% rename from movies/api/data/mylist.json rename to node/api/data/mylist.json diff --git a/movies/api/data/watching.json b/node/api/data/watching.json similarity index 100% rename from movies/api/data/watching.json rename to node/api/data/watching.json diff --git a/movies/api/okteto.yml b/node/api/okteto.yml similarity index 100% rename from movies/api/okteto.yml rename to node/api/okteto.yml diff --git a/movies/api/package.json b/node/api/package.json similarity index 100% rename from movies/api/package.json rename to node/api/package.json diff --git a/movies/api/server.js b/node/api/server.js similarity index 100% rename from movies/api/server.js rename to node/api/server.js diff --git a/movies/api/yarn.lock b/node/api/yarn.lock similarity index 100% rename from movies/api/yarn.lock rename to node/api/yarn.lock diff --git a/movies/frontend/.babelrc b/node/frontend/.babelrc similarity index 100% rename from movies/frontend/.babelrc rename to node/frontend/.babelrc diff --git a/movies/frontend/.gitignore b/node/frontend/.gitignore similarity index 100% rename from movies/frontend/.gitignore rename to node/frontend/.gitignore diff --git a/movies/frontend/.stignore b/node/frontend/.stignore similarity index 100% rename from movies/frontend/.stignore rename to node/frontend/.stignore diff --git a/movies/frontend/Dockerfile b/node/frontend/Dockerfile similarity index 100% rename from movies/frontend/Dockerfile rename to node/frontend/Dockerfile diff --git a/movies/frontend/okteto.yml b/node/frontend/okteto.yml similarity index 100% rename from movies/frontend/okteto.yml rename to node/frontend/okteto.yml diff --git a/movies/frontend/package.json b/node/frontend/package.json similarity index 100% rename from movies/frontend/package.json rename to node/frontend/package.json diff --git a/movies/frontend/src/App.jsx b/node/frontend/src/App.jsx similarity index 100% rename from movies/frontend/src/App.jsx rename to node/frontend/src/App.jsx diff --git a/movies/frontend/src/App.scss b/node/frontend/src/App.scss similarity index 100% rename from movies/frontend/src/App.scss rename to node/frontend/src/App.scss diff --git a/movies/frontend/src/assets/images/movie-bg.jpg b/node/frontend/src/assets/images/movie-bg.jpg similarity index 100% rename from movies/frontend/src/assets/images/movie-bg.jpg rename to node/frontend/src/assets/images/movie-bg.jpg diff --git a/movies/frontend/src/assets/images/movie-logo.png b/node/frontend/src/assets/images/movie-logo.png similarity index 100% rename from movies/frontend/src/assets/images/movie-logo.png rename to node/frontend/src/assets/images/movie-logo.png diff --git a/movies/frontend/src/assets/images/user.jpg b/node/frontend/src/assets/images/user.jpg similarity index 100% rename from movies/frontend/src/assets/images/user.jpg rename to node/frontend/src/assets/images/user.jpg diff --git a/movies/frontend/src/index.html b/node/frontend/src/index.html similarity index 100% rename from movies/frontend/src/index.html rename to node/frontend/src/index.html diff --git a/movies/frontend/src/index.jsx b/node/frontend/src/index.jsx similarity index 100% rename from movies/frontend/src/index.jsx rename to node/frontend/src/index.jsx diff --git a/movies/frontend/src/index.scss b/node/frontend/src/index.scss similarity index 100% rename from movies/frontend/src/index.scss rename to node/frontend/src/index.scss diff --git a/movies/frontend/webpack.config.js b/node/frontend/webpack.config.js similarity index 100% rename from movies/frontend/webpack.config.js rename to node/frontend/webpack.config.js diff --git a/movies/frontend/yarn.lock b/node/frontend/yarn.lock similarity index 100% rename from movies/frontend/yarn.lock rename to node/frontend/yarn.lock diff --git a/python/README.md b/python/README.md index 7c34c30..01c5846 100644 --- a/python/README.md +++ b/python/README.md @@ -1,4 +1,4 @@ -# Voting App deployed with raw Kubernetes manifests +# Voting App This example shows how to leverage [Okteto](https://okteto.com) to develop a python app directly in the cloud. This example is deployed using raw Kubernetes manifests. @@ -26,8 +26,8 @@ This example works in any Kubernetes cluster (Okteto reads your local Kubernetes Get a local version of the sample application by executing the following commands in your local terminal: ```console -git clone https://github.com/okteto/cloud-samples -cd cloud-samples/python +git clone https://github.com/okteto/samples +cd samples/python ``` You now have a functioning git repository that contains a simple python application and a `requirements.txt`, which is used by Python’s dependency manager, `pip`. @@ -42,7 +42,7 @@ Run the voting app by executing: kubectl apply -f manifests ``` -> Wait for one or two minutes until the application is running. If you are using the Okteto cluster, you can access the app at https://vote-[githubid].cloud.okteto.net. If not, it will be available at https://localhost:8080. +Wait for one or two minutes until the application is running. You can access the app at https://localhost:8080. ## Step 3: Create your Okteto Environment diff --git a/python/okteto.yml b/python/okteto.yml index 177ef09..e29db0f 100644 --- a/python/okteto.yml +++ b/python/okteto.yml @@ -1,5 +1,6 @@ name: vote +image: okteto/vote:latest workdir: /src command: ["python", "app.py"] forward: - - 8080 \ No newline at end of file + - 8080:8080 \ No newline at end of file diff --git a/ruby/.dockerignore b/ruby/.dockerignore new file mode 100644 index 0000000..9f7883b --- /dev/null +++ b/ruby/.dockerignore @@ -0,0 +1,27 @@ +# Ignore bundler config. +/.bundle + +# Ignore the default SQLite database. +/db/*.sqlite3 +/db/*.sqlite3-journal + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore uploaded files in development +/storage/* +!/storage/.keep + +/node_modules +/yarn-error.log + +/public/assets +.byebug_history + +# Ignore master key for decrypting credentials and more. +/config/master.key + +manifest diff --git a/ruby/Dockerfile b/ruby/Dockerfile new file mode 100644 index 0000000..348ffa4 --- /dev/null +++ b/ruby/Dockerfile @@ -0,0 +1,12 @@ +FROM ruby:2 +WORKDIR /usr/src/app +RUN apt-get update && \ + apt-get install sqlite3 + +COPY blog . + +RUN bundler install +RUN rails db:migrate +EXPOSE 3000 + +CMD ["sh", "-c", "rails db:migrate && rails server"] \ No newline at end of file diff --git a/ruby/README.md b/ruby/README.md new file mode 100644 index 0000000..2a6dab3 --- /dev/null +++ b/ruby/README.md @@ -0,0 +1,55 @@ +# Ruby on rails web app deployed with raw Kubernetes manifests + +This example shows how to develop a Ruby on Rails web app with [okteto](https://okteto.com). It's based on [Ruby on Rails' getting started guide](https://guides.rubyonrails.org/getting_started.html). + +This example works in any Kubernetes cluster. Cloud Native Development provides more value in remote Kubernetes clusters, but in order to make it simple to follow this guide, we recommend to use Docker for Mac (with Kubernetes support) or [minikube](https://github.com/kubernetes/minikube). + +## Deploy the blog service + +Clone the repository and go to the rails-kubectl folder. + +```console +git clone https://github.com/okteto/samples +cd samples/ruby +``` + +Deploy the blog application by using the following command: +```console +kubectl apply -f manifests +``` + +## Cloud Native Development + +In order to activate your Cloud Native Development, execute: + +```console +okteto up +``` + +The `okteto up` command will start a remote development environment that automatically synchronizes and applies your code changes without rebuilding containers. The environment already includes the ruby dev tools, and will automatically forward port 3000 to your local machine. + +Now execute the command below. The command will start your service and reload it automatically after every successful change. + +```console +rails s -e development +``` + +Once the server is running, browse to the application at http://localhost:3000 and you'll see an error message similar to this one in your browser: +```console +Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development +``` + +This is because we have a migration pending. Press `ctrl + c` and run the following commands from your terminal: + +```console +rails db:migrate +rails s -e development +``` + +Notice that even though you don't have the application running locally (and you don't have rails installed), the command still runs successfully. This is because okteto is running the command directly in your dev environment in the browser! + +Browse again to your application, it should load without any issues. At this point, you have a web application that can create, show, list, update and destroy articles. + +To keep testing the power of cloud native development, continue with the rest of the [getting started guide](https://guides.rubyonrails.org/getting_started.html#adding-a-second-model). Keep creating and editing files in your IDE. + +Happy coding! \ No newline at end of file diff --git a/ruby/app/assets/config/manifest.js b/ruby/app/assets/config/manifest.js new file mode 100644 index 0000000..b16e53d --- /dev/null +++ b/ruby/app/assets/config/manifest.js @@ -0,0 +1,3 @@ +//= link_tree ../images +//= link_directory ../javascripts .js +//= link_directory ../stylesheets .css diff --git a/ruby/app/assets/images/.keep b/ruby/app/assets/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/app/assets/javascripts/application.js b/ruby/app/assets/javascripts/application.js new file mode 100644 index 0000000..82e6f0f --- /dev/null +++ b/ruby/app/assets/javascripts/application.js @@ -0,0 +1,16 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's +// vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. JavaScript code in this file should be added after the last require_* statement. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require rails-ujs +//= require activestorage +//= require turbolinks +//= require_tree . diff --git a/ruby/app/assets/javascripts/articles.coffee b/ruby/app/assets/javascripts/articles.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/ruby/app/assets/javascripts/articles.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/ruby/app/assets/javascripts/cable.js b/ruby/app/assets/javascripts/cable.js new file mode 100644 index 0000000..739aa5f --- /dev/null +++ b/ruby/app/assets/javascripts/cable.js @@ -0,0 +1,13 @@ +// Action Cable provides the framework to deal with WebSockets in Rails. +// You can generate new channels where WebSocket features live using the `rails generate channel` command. +// +//= require action_cable +//= require_self +//= require_tree ./channels + +(function() { + this.App || (this.App = {}); + + App.cable = ActionCable.createConsumer(); + +}).call(this); diff --git a/ruby/app/assets/javascripts/channels/.keep b/ruby/app/assets/javascripts/channels/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/app/assets/javascripts/welcome.coffee b/ruby/app/assets/javascripts/welcome.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/ruby/app/assets/javascripts/welcome.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/ruby/app/assets/stylesheets/application.css b/ruby/app/assets/stylesheets/application.css new file mode 100644 index 0000000..d05ea0f --- /dev/null +++ b/ruby/app/assets/stylesheets/application.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's + * vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/ruby/app/assets/stylesheets/articles.scss b/ruby/app/assets/stylesheets/articles.scss new file mode 100644 index 0000000..e77f17a --- /dev/null +++ b/ruby/app/assets/stylesheets/articles.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Articles controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/ruby/app/assets/stylesheets/welcome.scss b/ruby/app/assets/stylesheets/welcome.scss new file mode 100644 index 0000000..4e19aa4 --- /dev/null +++ b/ruby/app/assets/stylesheets/welcome.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Welcome controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/ruby/app/channels/application_cable/channel.rb b/ruby/app/channels/application_cable/channel.rb new file mode 100644 index 0000000..d672697 --- /dev/null +++ b/ruby/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/ruby/app/channels/application_cable/connection.rb b/ruby/app/channels/application_cable/connection.rb new file mode 100644 index 0000000..0ff5442 --- /dev/null +++ b/ruby/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/ruby/app/controllers/application_controller.rb b/ruby/app/controllers/application_controller.rb new file mode 100644 index 0000000..09705d1 --- /dev/null +++ b/ruby/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::Base +end diff --git a/ruby/app/controllers/articles_controller.rb b/ruby/app/controllers/articles_controller.rb new file mode 100644 index 0000000..725b4c3 --- /dev/null +++ b/ruby/app/controllers/articles_controller.rb @@ -0,0 +1,49 @@ +class ArticlesController < ApplicationController + + def new + @article = Article.new + end + + def edit + @article = Article.find(params[:id]) + end + + def update + @article = Article.find(params[:id]) + + if @article.update(article_params) + redirect_to @article + else + render 'edit' + end + end + + def create + @article = Article.new(article_params) + if @article.save + redirect_to @article + else + render 'new' + end + end + + def destroy + @article = Article.find(params[:id]) + @article.destroy + + redirect_to articles_path + end + + def show + @article = Article.find(params[:id]) + end + + def index + @articles = Article.all + end + + private + def article_params + params.require(:article).permit(:title, :text) + end + end \ No newline at end of file diff --git a/ruby/app/controllers/concerns/.keep b/ruby/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/app/controllers/welcome_controller.rb b/ruby/app/controllers/welcome_controller.rb new file mode 100644 index 0000000..f9b859b --- /dev/null +++ b/ruby/app/controllers/welcome_controller.rb @@ -0,0 +1,4 @@ +class WelcomeController < ApplicationController + def index + end +end diff --git a/ruby/app/helpers/application_helper.rb b/ruby/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/ruby/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/ruby/app/helpers/articles_helper.rb b/ruby/app/helpers/articles_helper.rb new file mode 100644 index 0000000..2968277 --- /dev/null +++ b/ruby/app/helpers/articles_helper.rb @@ -0,0 +1,2 @@ +module ArticlesHelper +end diff --git a/ruby/app/helpers/welcome_helper.rb b/ruby/app/helpers/welcome_helper.rb new file mode 100644 index 0000000..eeead45 --- /dev/null +++ b/ruby/app/helpers/welcome_helper.rb @@ -0,0 +1,2 @@ +module WelcomeHelper +end diff --git a/ruby/app/jobs/application_job.rb b/ruby/app/jobs/application_job.rb new file mode 100644 index 0000000..a009ace --- /dev/null +++ b/ruby/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/ruby/app/mailers/application_mailer.rb b/ruby/app/mailers/application_mailer.rb new file mode 100644 index 0000000..286b223 --- /dev/null +++ b/ruby/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' +end diff --git a/ruby/app/models/application_record.rb b/ruby/app/models/application_record.rb new file mode 100644 index 0000000..10a4cba --- /dev/null +++ b/ruby/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/ruby/app/models/article.rb b/ruby/app/models/article.rb new file mode 100644 index 0000000..847f346 --- /dev/null +++ b/ruby/app/models/article.rb @@ -0,0 +1,3 @@ +class Article < ApplicationRecord + validates :title, presence: true, length: { minimum: 5 } +end diff --git a/ruby/app/models/concerns/.keep b/ruby/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/app/views/articles/_form.html.erb b/ruby/app/views/articles/_form.html.erb new file mode 100644 index 0000000..5e18d4c --- /dev/null +++ b/ruby/app/views/articles/_form.html.erb @@ -0,0 +1,31 @@ +<%= form_with model: @article, local: true do |form| %> + + <% if @article.errors.any? %> +
+

+ <%= pluralize(@article.errors.count, "error") %> prohibited + this article from being saved: +

+
    + <% @article.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+
+ <% end %> + +

+ <%= form.label :title %>
+ <%= form.text_field :title %> +

+ +

+ <%= form.label :text %>
+ <%= form.text_area :text %> +

+ +

+ <%= form.submit %> +

+ + <% end %> \ No newline at end of file diff --git a/ruby/app/views/articles/edit.html.erb b/ruby/app/views/articles/edit.html.erb new file mode 100644 index 0000000..498da19 --- /dev/null +++ b/ruby/app/views/articles/edit.html.erb @@ -0,0 +1,6 @@ + +

Edit article

+ +<%= render 'form' %> + +<%= link_to 'Back', articles_path %> \ No newline at end of file diff --git a/ruby/app/views/articles/index.html.erb b/ruby/app/views/articles/index.html.erb new file mode 100644 index 0000000..5f32729 --- /dev/null +++ b/ruby/app/views/articles/index.html.erb @@ -0,0 +1,22 @@ + +

Listing Articles

+<%= link_to 'New article', new_article_path %> + + + + + + + + <% @articles.each do |article| %> + + + + + + + + <% end %> +
TitleText
<%= article.title %><%= article.text %><%= link_to 'Show', article_path(article) %><%= link_to 'Edit', edit_article_path(article) %><%= link_to 'Destroy', article_path(article), + method: :delete, + data: { confirm: 'Are you sure?' } %>
\ No newline at end of file diff --git a/ruby/app/views/articles/new.html.erb b/ruby/app/views/articles/new.html.erb new file mode 100644 index 0000000..cbac1e9 --- /dev/null +++ b/ruby/app/views/articles/new.html.erb @@ -0,0 +1,6 @@ + +

New article

+ +<%= render 'form' %> + +<%= link_to 'Back', articles_path %> \ No newline at end of file diff --git a/ruby/app/views/articles/show.html.erb b/ruby/app/views/articles/show.html.erb new file mode 100644 index 0000000..e03ccc2 --- /dev/null +++ b/ruby/app/views/articles/show.html.erb @@ -0,0 +1,12 @@ +

+ Title: + <%= @article.title %> +

+ +

+ Text: + <%= @article.text %> +

+ +<%= link_to 'Edit', edit_article_path(@article) %> | +<%= link_to 'Back', articles_path %> \ No newline at end of file diff --git a/ruby/app/views/layouts/application.html.erb b/ruby/app/views/layouts/application.html.erb new file mode 100644 index 0000000..752a30d --- /dev/null +++ b/ruby/app/views/layouts/application.html.erb @@ -0,0 +1,15 @@ + + + + Blog + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> + <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> + + + + <%= yield %> + + diff --git a/ruby/app/views/layouts/mailer.html.erb b/ruby/app/views/layouts/mailer.html.erb new file mode 100644 index 0000000..cbd34d2 --- /dev/null +++ b/ruby/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/ruby/app/views/layouts/mailer.text.erb b/ruby/app/views/layouts/mailer.text.erb new file mode 100644 index 0000000..37f0bdd --- /dev/null +++ b/ruby/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/ruby/app/views/welcome/index.html.erb b/ruby/app/views/welcome/index.html.erb new file mode 100644 index 0000000..552a621 --- /dev/null +++ b/ruby/app/views/welcome/index.html.erb @@ -0,0 +1,3 @@ + +

Hello, Okteto!

+<%= link_to 'My Blog', controller: 'articles' %> diff --git a/ruby/bin/bundle b/ruby/bin/bundle new file mode 100755 index 0000000..f19acf5 --- /dev/null +++ b/ruby/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) +load Gem.bin_path('bundler', 'bundle') diff --git a/ruby/bin/rails b/ruby/bin/rails new file mode 100755 index 0000000..5badb2f --- /dev/null +++ b/ruby/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/ruby/bin/rake b/ruby/bin/rake new file mode 100755 index 0000000..d87d5f5 --- /dev/null +++ b/ruby/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/ruby/bin/setup b/ruby/bin/setup new file mode 100755 index 0000000..94fd4d7 --- /dev/null +++ b/ruby/bin/setup @@ -0,0 +1,36 @@ +#!/usr/bin/env ruby +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:setup' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/ruby/bin/spring b/ruby/bin/spring new file mode 100755 index 0000000..fb2ec2e --- /dev/null +++ b/ruby/bin/spring @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) + spring = lockfile.specs.detect { |spec| spec.name == "spring" } + if spring + Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path + gem 'spring', spring.version + require 'spring/binstub' + end +end diff --git a/ruby/bin/update b/ruby/bin/update new file mode 100755 index 0000000..58bfaed --- /dev/null +++ b/ruby/bin/update @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/ruby/bin/yarn b/ruby/bin/yarn new file mode 100755 index 0000000..460dd56 --- /dev/null +++ b/ruby/bin/yarn @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +APP_ROOT = File.expand_path('..', __dir__) +Dir.chdir(APP_ROOT) do + begin + exec "yarnpkg", *ARGV + rescue Errno::ENOENT + $stderr.puts "Yarn executable was not detected in the system." + $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" + exit 1 + end +end diff --git a/ruby/config/application.rb b/ruby/config/application.rb new file mode 100644 index 0000000..9e1e20d --- /dev/null +++ b/ruby/config/application.rb @@ -0,0 +1,19 @@ +require_relative 'boot' + +require 'rails/all' + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module Blog + class Application < Rails::Application + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 5.2 + + # Settings in config/environments/* take precedence over those specified here. + # Application configuration can go into files in config/initializers + # -- all .rb files in that directory are automatically loaded after loading + # the framework and any gems in your application. + end +end diff --git a/ruby/config/boot.rb b/ruby/config/boot.rb new file mode 100644 index 0000000..b9e460c --- /dev/null +++ b/ruby/config/boot.rb @@ -0,0 +1,4 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. +require 'bootsnap/setup' # Speed up boot time by caching expensive operations. diff --git a/ruby/config/cable.yml b/ruby/config/cable.yml new file mode 100644 index 0000000..f75b4dd --- /dev/null +++ b/ruby/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: blog_production diff --git a/ruby/config/credentials.yml.enc b/ruby/config/credentials.yml.enc new file mode 100644 index 0000000..924f75b --- /dev/null +++ b/ruby/config/credentials.yml.enc @@ -0,0 +1 @@ +kYWBWC64t93cuqfSU1SWFaaox8b0MpJArBTnQ5O9pajHacori5FXgP1D2bZjuiee6qQ8Z+Rfquj7iSSx1JH+3U5IVAr+Y+xXGEPR9UflvS7iuNc8bk8mbNNXw9oMrIAgld1Vd0q7a6qNhhmmGPU8CCFkyOoUqX5Yzz2LDLnaF1oGWGT6dsrrpeqDClSMQCnUCL/i/tF9gVZWUKo6ny5wCw65Yc2ZrI74rP2uzUppwTr82q724TjyLigiGa+X62rIi0q9lyfd17RQ3EVDl7tBWFwsULF2tSt1xh9Ay5iKoCbAWuybSM67RJGxVqjmJn2epqFaaipeB7VPnpsLcXERAgqjxQ49cEpMzQMyvyFb17z1178PIjHgM+9favTZcpzkiSNdHAw+vqgsZkLz6VkFY1zMobscDgA60RMi--93DL+hSJ8ze7stBN--rOEY4YDmYA8iF9FZLSDWCQ== \ No newline at end of file diff --git a/ruby/config/database.yml b/ruby/config/database.yml new file mode 100644 index 0000000..0d02f24 --- /dev/null +++ b/ruby/config/database.yml @@ -0,0 +1,25 @@ +# SQLite version 3.x +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem 'sqlite3' +# +default: &default + adapter: sqlite3 + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: 5000 + +development: + <<: *default + database: db/development.sqlite3 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: db/test.sqlite3 + +production: + <<: *default + database: db/production.sqlite3 diff --git a/ruby/config/environment.rb b/ruby/config/environment.rb new file mode 100644 index 0000000..426333b --- /dev/null +++ b/ruby/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative 'application' + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/ruby/config/environments/development.rb b/ruby/config/environments/development.rb new file mode 100644 index 0000000..1311e3e --- /dev/null +++ b/ruby/config/environments/development.rb @@ -0,0 +1,61 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + # Run rails dev:cache to toggle caching. + if Rails.root.join('tmp', 'caching-dev.txt').exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{2.days.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Store uploaded files on the local file system (see config/storage.yml for options) + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Suppress logger output for asset requests. + config.assets.quiet = true + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true + + # Use an evented file watcher to asynchronously detect changes in source code, + # routes, locales, etc. This feature depends on the listen gem. + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end diff --git a/ruby/config/environments/production.rb b/ruby/config/environments/production.rb new file mode 100644 index 0000000..4d84c97 --- /dev/null +++ b/ruby/config/environments/production.rb @@ -0,0 +1,94 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Store uploaded files on the local file system (see config/storage.yml for options) + config.active_storage.service = :local + + # Mount Action Cable outside main process or domain + # config.action_cable.mount_path = nil + # config.action_cable.url = 'wss://example.com/cable' + # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment) + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "blog_#{Rails.env}" + + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/ruby/config/environments/test.rb b/ruby/config/environments/test.rb new file mode 100644 index 0000000..0a38fd3 --- /dev/null +++ b/ruby/config/environments/test.rb @@ -0,0 +1,46 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{1.hour.to_i}" + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory + config.active_storage.service = :test + + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/ruby/config/initializers/application_controller_renderer.rb b/ruby/config/initializers/application_controller_renderer.rb new file mode 100644 index 0000000..89d2efa --- /dev/null +++ b/ruby/config/initializers/application_controller_renderer.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/ruby/config/initializers/assets.rb b/ruby/config/initializers/assets.rb new file mode 100644 index 0000000..4b828e8 --- /dev/null +++ b/ruby/config/initializers/assets.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = '1.0' + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path +# Add Yarn node_modules folder to the asset load path. +Rails.application.config.assets.paths << Rails.root.join('node_modules') + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w( admin.js admin.css ) diff --git a/ruby/config/initializers/backtrace_silencers.rb b/ruby/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/ruby/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/ruby/config/initializers/content_security_policy.rb b/ruby/config/initializers/content_security_policy.rb new file mode 100644 index 0000000..d3bcaa5 --- /dev/null +++ b/ruby/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https + +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end + +# If you are using UJS then enable automatic nonce generation +# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } + +# Report CSP violations to a specified URI +# For further information see the following documentation: +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# Rails.application.config.content_security_policy_report_only = true diff --git a/ruby/config/initializers/cookies_serializer.rb b/ruby/config/initializers/cookies_serializer.rb new file mode 100644 index 0000000..5a6a32d --- /dev/null +++ b/ruby/config/initializers/cookies_serializer.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. + +# Specify a serializer for the signed and encrypted cookie jars. +# Valid options are :json, :marshal, and :hybrid. +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/ruby/config/initializers/filter_parameter_logging.rb b/ruby/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..4a994e1 --- /dev/null +++ b/ruby/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/ruby/config/initializers/inflections.rb b/ruby/config/initializers/inflections.rb new file mode 100644 index 0000000..ac033bf --- /dev/null +++ b/ruby/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/ruby/config/initializers/mime_types.rb b/ruby/config/initializers/mime_types.rb new file mode 100644 index 0000000..dc18996 --- /dev/null +++ b/ruby/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/ruby/config/initializers/wrap_parameters.rb b/ruby/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..bbfc396 --- /dev/null +++ b/ruby/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/ruby/config/locales/en.yml b/ruby/config/locales/en.yml new file mode 100644 index 0000000..decc5a8 --- /dev/null +++ b/ruby/config/locales/en.yml @@ -0,0 +1,33 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# The following keys must be escaped otherwise they will not be retrieved by +# the default I18n backend: +# +# true, false, on, off, yes, no +# +# Instead, surround them with single quotes. +# +# en: +# 'true': 'foo' +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/ruby/config/puma.rb b/ruby/config/puma.rb new file mode 100644 index 0000000..a5eccf8 --- /dev/null +++ b/ruby/config/puma.rb @@ -0,0 +1,34 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked webserver processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. +# +# preload_app! + +# Allow puma to be restarted by `rails restart` command. +plugin :tmp_restart diff --git a/ruby/config/routes.rb b/ruby/config/routes.rb new file mode 100644 index 0000000..0841dad --- /dev/null +++ b/ruby/config/routes.rb @@ -0,0 +1,7 @@ +Rails.application.routes.draw do + get 'welcome/index' + + resources :articles + + root 'welcome#index' +end diff --git a/ruby/config/spring.rb b/ruby/config/spring.rb new file mode 100644 index 0000000..9fa7863 --- /dev/null +++ b/ruby/config/spring.rb @@ -0,0 +1,6 @@ +%w[ + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +].each { |path| Spring.watch(path) } diff --git a/ruby/config/storage.yml b/ruby/config/storage.yml new file mode 100644 index 0000000..d32f76e --- /dev/null +++ b/ruby/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket + +# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/ruby/db/migrate/20190129035246_create_articles.rb b/ruby/db/migrate/20190129035246_create_articles.rb new file mode 100644 index 0000000..811b24b --- /dev/null +++ b/ruby/db/migrate/20190129035246_create_articles.rb @@ -0,0 +1,10 @@ +class CreateArticles < ActiveRecord::Migration[5.2] + def change + create_table :articles do |t| + t.string :title + t.text :text + + t.timestamps + end + end +end diff --git a/ruby/db/schema.rb b/ruby/db/schema.rb new file mode 100644 index 0000000..33ff23e --- /dev/null +++ b/ruby/db/schema.rb @@ -0,0 +1,22 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 2019_01_29_035246) do + + create_table "articles", force: :cascade do |t| + t.string "title" + t.text "text" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + +end diff --git a/ruby/db/seeds.rb b/ruby/db/seeds.rb new file mode 100644 index 0000000..1beea2a --- /dev/null +++ b/ruby/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). +# +# Examples: +# +# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) +# Character.create(name: 'Luke', movie: movies.first) diff --git a/ruby/lib/assets/.keep b/ruby/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/lib/tasks/.keep b/ruby/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/log/.keep b/ruby/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/manifests/deployment.yaml b/ruby/manifests/deployment.yaml new file mode 100644 index 0000000..6699d2b --- /dev/null +++ b/ruby/manifests/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: blog + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + replicas: 1 + selector: + matchLabels: + app: blog + template: + metadata: + labels: + app: blog + spec: + containers: + - image: okteto/blog:latest + name: blog \ No newline at end of file diff --git a/ruby/manifests/service.yaml b/ruby/manifests/service.yaml new file mode 100644 index 0000000..8ea7e1c --- /dev/null +++ b/ruby/manifests/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: blog + annotations: + dev.okteto.com/auto-ingress: "true" +spec: + type: ClusterIP + ports: + - name: "blog" + port: 8080 + selector: + app: blog diff --git a/ruby/public/404.html b/ruby/public/404.html new file mode 100644 index 0000000..2be3af2 --- /dev/null +++ b/ruby/public/404.html @@ -0,0 +1,67 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/ruby/public/422.html b/ruby/public/422.html new file mode 100644 index 0000000..c08eac0 --- /dev/null +++ b/ruby/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/ruby/public/500.html b/ruby/public/500.html new file mode 100644 index 0000000..78a030a --- /dev/null +++ b/ruby/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/ruby/public/apple-touch-icon-precomposed.png b/ruby/public/apple-touch-icon-precomposed.png new file mode 100644 index 0000000..e69de29 diff --git a/ruby/public/apple-touch-icon.png b/ruby/public/apple-touch-icon.png new file mode 100644 index 0000000..e69de29 diff --git a/ruby/public/favicon.ico b/ruby/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/ruby/public/robots.txt b/ruby/public/robots.txt new file mode 100644 index 0000000..37b576a --- /dev/null +++ b/ruby/public/robots.txt @@ -0,0 +1 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/ruby/storage/.keep b/ruby/storage/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/application_system_test_case.rb b/ruby/test/application_system_test_case.rb new file mode 100644 index 0000000..d19212a --- /dev/null +++ b/ruby/test/application_system_test_case.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :selenium, using: :chrome, screen_size: [1400, 1400] +end diff --git a/ruby/test/controllers/.keep b/ruby/test/controllers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/controllers/articles_controller_test.rb b/ruby/test/controllers/articles_controller_test.rb new file mode 100644 index 0000000..aae3248 --- /dev/null +++ b/ruby/test/controllers/articles_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ArticlesControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/ruby/test/controllers/welcome_controller_test.rb b/ruby/test/controllers/welcome_controller_test.rb new file mode 100644 index 0000000..a95e43a --- /dev/null +++ b/ruby/test/controllers/welcome_controller_test.rb @@ -0,0 +1,9 @@ +require 'test_helper' + +class WelcomeControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + get welcome_index_url + assert_response :success + end + +end diff --git a/ruby/test/fixtures/.keep b/ruby/test/fixtures/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/fixtures/articles.yml b/ruby/test/fixtures/articles.yml new file mode 100644 index 0000000..46b01c3 --- /dev/null +++ b/ruby/test/fixtures/articles.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + text: MyText + +two: + title: MyString + text: MyText diff --git a/ruby/test/fixtures/files/.keep b/ruby/test/fixtures/files/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/helpers/.keep b/ruby/test/helpers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/integration/.keep b/ruby/test/integration/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/mailers/.keep b/ruby/test/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/models/.keep b/ruby/test/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/models/article_test.rb b/ruby/test/models/article_test.rb new file mode 100644 index 0000000..11c8abe --- /dev/null +++ b/ruby/test/models/article_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ArticleTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/ruby/test/system/.keep b/ruby/test/system/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/test/test_helper.rb b/ruby/test/test_helper.rb new file mode 100644 index 0000000..3ab84e3 --- /dev/null +++ b/ruby/test/test_helper.rb @@ -0,0 +1,10 @@ +ENV['RAILS_ENV'] ||= 'test' +require_relative '../config/environment' +require 'rails/test_help' + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... +end diff --git a/ruby/tmp/.keep b/ruby/tmp/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ruby/vendor/.keep b/ruby/vendor/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vote/.gitignore b/vote/.gitignore deleted file mode 100644 index a08fb88..0000000 --- a/vote/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -okteto.yml -.stignore diff --git a/vote/Dockerfile b/vote/Dockerfile deleted file mode 100644 index 4a71d27..0000000 --- a/vote/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -# Using official python runtime base image -FROM python:3-alpine - -# Set the application directory -WORKDIR /usr/src/app - -# Install our requirements.txt -ADD requirements.txt requirements.txt -RUN pip install -r requirements.txt - -# Copy our code from the current folder to /app inside the container -ADD . /usr/src/app - -# Make port 8080 available for links and/or publish -EXPOSE 8080 - -# Define our command to be run when launching the container -CMD ["python", "app.py"] diff --git a/vote/README.md b/vote/README.md deleted file mode 100644 index d6fda35..0000000 --- a/vote/README.md +++ /dev/null @@ -1,115 +0,0 @@ -# Voting App - -This example shows how to leverage [Okteto](https://cloud.okteto.com) to develop a python app directly in the cloud. - -## Step 1: Install the Okteto CLI - -Install the Okteto CLI by running the following command in your local terminal: - -MacOS/Linux - -```console -curl https://get.okteto.com -sSfL | sh -``` - -Windows - -```console -wget https://downloads.okteto.com/cli/okteto-Windows-x86_64 -OutFile c:\windows\system32\okteto.exe -``` - -## Step 2: Login from the Okteto CLI - -```console -$ okteto login -``` - -This command will give you an Okteto Space, where you can create Okteto Environments to code and collaborate. - -## Step 3: Create your Okteto Environment - -Get a local version of the sample application by executing the following commands in your local terminal: - -```console -$ git clone https://github.com/okteto/cloud-samples -$ cd cloud-samples/vote -``` - -You now have a functioning git repository that contains a simple python 3 application and a `requirements.txt`, which is used by Python’s dependency manager, `pip`. - -The sample application uses redis. Run the following command to deploy an Okteto Redis Database into your Okteto Space: - -```console -$ okteto database redis -``` - -Now start your Okteto Environment by running the following command: - -```console -$ okteto up -``` - -The `okteto up` command will automatically start an Okteto Environment. It will also start a file synchronization service to keep your changes up to date between your local filesystem and your Okteto Environment. - - - -Once the Okteto Environment is ready, start your application by executing the following commands in your Okteto Terminal: - -```console -okteto> pip install -r requirements.txt -okteto> python app.py -``` - -Your application is now ready to be tested. You can check it by logging into [Okteto](https://cloud.okteto.com) and clicking in the application's endpoint. - -> Note that Okteto creates a public HTTPS endpoint forwarding to the port 8080 of your application. - - - -Congratulations, you just deployed your first Okteto Application 🚀! - -## Step 4: Develop directly in the cloud - -Now things get more exciting. Open `vote/app.py` in your favorite IDE and modify the `getOptions` function with the following code, and save your file: - -```python -def getOptions(): - optionA = 'Otters' - optionB = 'Dogs' - return optionA, optionB -``` - -Go back to the Okteto Terminal and notice that flask already detected the code changes and reloaded your application. - -```console -... - * Detected change in '/usr/src/app/app.py', reloading - * Restarting with stat - * Debugger is active! - * Debugger PIN: 778-756-428 -``` - -Go back to the browser, and reload the page. Notice how your changes are instantly applied. No commit or push required 😎! - -## Step 5: Deploy your application - -Now that you are happy with your changes, it's time to run your updated application with the `okteto run` command. Instead of launching an Okteto Environment and synchronizing your files, the `okteto run` command automatically deploys a container into your Okteto Space. - -Let's build a Docker image with your latest changes. Press `ctrl + c` and `ctrl + d` in your Okteto Terminal to go back to your local terminal, and execute the following command to build your docker image and push it to [Docker Hub](https://docs.docker.com/docker-hub/repos/): - -```console -$ docker build -t \vote -$ docker push \vote -``` - -> If you don't have access to Docker Hub, you can use `okteto/vote:0.1.0` instead of your own docker image to complete this step. - -Once your image is ready, run the following command to deploy your container: - -```console -$ okteto run \vote -``` - -After a couple of seconds, your application will be ready. Go back to the browser and reload the page to see your new docker container up and running. - -> `okteto run` only supports images from public docker repositories. [Contact us](mailto:sales@okteto.com?Subject=Support%20for%20private%20images) if you're interested in support for private images diff --git a/vote/app.py b/vote/app.py deleted file mode 100644 index 5606068..0000000 --- a/vote/app.py +++ /dev/null @@ -1,52 +0,0 @@ -from flask import Flask, render_template, request, make_response, g -from redis import Redis, RedisError -import socket -import random -import json - -hostname = socket.gethostname() - -redis = Redis(host="redis", db=0) -app = Flask(__name__) - -def getOptions(): - option_a = 'Cats' - option_b = 'Dogs' - return option_a, option_b - -@app.route("/", methods=['POST','GET']) -def hello(): - option_a, option_b = getOptions() - - try: - votesA = int(redis.get(option_a) or 0) - votesB = int(redis.get(option_b) or 0) - except RedisError: - votesA = "cannot connect to Redis, counter disabled" - votesB = "cannot connect to Redis, counter disabled" - - if request.method == 'POST': - try: - vote = request.form['vote'] - if vote == "a": - votesA = redis.incr(option_a) - else: - votesB = redis.incr(option_b) - except Exception as e: - print(e) - votesA = "An error occured" - votesB = "An error occured" - - resp = make_response(render_template( - 'index.html', - option_a=option_a, - option_b=option_b, - hostname=hostname, - votes_a=votesA, - votes_b=votesB, - )) - return resp - - -if __name__ == "__main__": - app.run(host='0.0.0.0', port=8080, debug=True) diff --git a/vote/images/okteto-ui.png b/vote/images/okteto-ui.png deleted file mode 100644 index 76e6d3a..0000000 Binary files a/vote/images/okteto-ui.png and /dev/null differ diff --git a/vote/images/okteto-up.png b/vote/images/okteto-up.png deleted file mode 100644 index 76e2aec..0000000 Binary files a/vote/images/okteto-up.png and /dev/null differ diff --git a/vote/requirements.txt b/vote/requirements.txt deleted file mode 100644 index 82dfa50..0000000 --- a/vote/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Flask -Redis diff --git a/vscode-ssh/manifests/ingress.yaml b/vscode-ssh/manifests/ingress.yaml deleted file mode 100644 index 07d1db3..0000000 --- a/vscode-ssh/manifests/ingress.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: vote - annotations: - kubernetes.io/ingress.class: nginx -spec: - rules: - - host: vote-cindy.cloud.okteto.net - http: - paths: - - path: / - backend: - serviceName: vote - servicePort: 8080 - tls: - - hosts: - - vote-cindy.cloud.okteto.net \ No newline at end of file diff --git a/vscode-ssh/templates/index.html b/vscode-ssh/templates/index.html deleted file mode 100644 index f94714d..0000000 --- a/vscode-ssh/templates/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - {{option_a}} vs {{option_b}}! - - - - - - - - -
-
-

{{option_a}} vs {{option_b}}!

-
- - -
-

{{votes_a}} vs {{votes_b}}

-
-

Processed by {{hostname}}

-
-
-
- - - - diff --git a/vscode-ssh/Dockerfile b/vscode/Dockerfile similarity index 86% rename from vscode-ssh/Dockerfile rename to vscode/Dockerfile index 20f40ce..4e2f9f9 100644 --- a/vscode-ssh/Dockerfile +++ b/vscode/Dockerfile @@ -2,14 +2,14 @@ FROM python:stretch as app # Install the application -WORKDIR /usr/src/app +WORKDIR /src ADD requirements.txt requirements.txt RUN pip install -r requirements.txt -ADD . /usr/src/app +ADD . /src EXPOSE 8080 CMD ["python", "app.py"] -FROM app as ssh +FROM app # Configure SSH server RUN apt-get update && apt-get install -y openssh-server diff --git a/vscode-ssh/README.md b/vscode/README.md similarity index 52% rename from vscode-ssh/README.md rename to vscode/README.md index 2e51fef..cb22239 100644 --- a/vscode-ssh/README.md +++ b/vscode/README.md @@ -18,56 +18,27 @@ Windows wget https://downloads.okteto.com/cli/okteto-Windows-x86_64 -OutFile c:\windows\system32\okteto.exe ``` -## Step 2: Login from the Okteto CLI +This example works in any Kubernetes cluster (Okteto reads your local Kubernetes credentials), but we recommend to use https://cloud.okteto.com to follow this guide. -```console -$ okteto login -``` - -This command will give you an Okteto Space, where you can create Okteto Environments to code and collaborate. -Under the hood, an Okteto Space is mapped to a Kubernetes Namespace. - -## Step 3: Configure kubectl to point to Okteto - -> If you don´t have `kubectl` installed, follow this [guide](https://kubernetes.io/docs/tasks/tools/install-kubectl/). - -Okteto gives you `kubectl` credentials configured to work in our multi-tenant cluster. These credentials have network policies, quotas, pod security policies, admission webhooks, roles, role bindings and limit ranges to control what you can do in your Okteto Space. In order to download the credentials, execute: - -```console -$ okteto kubeconfig - ✓ Kubeconfig stored at $HOME/.okteto/.kubeconfig - i Configure kubectl to work on your Okteto Space by running: - export KUBECONFIG=$HOME/.okteto/.kubeconfig -``` -and now execute: - -```console -$ export KUBECONFIG=$HOME/.okteto/.kubeconfig -``` - -## Step 4: Deploy the Voting App +## Step 2: Deploy the Voting App Clone this repository and move to this example folder. ```console -git clone https://github.com/okteto/cloud-samples -cd cloud-samples/vscode-ssh +git clone https://github.com/okteto/samples +cd samples/vscode ``` -Edit the file `manifests\ingress.yaml` and substitute `cindy` by your Github ID in lines 9 and 18. - -> Okteto only let you create ingress rules for domains ending in `-[githubid].cloud.okteto.net`. - -Save and run the Voting App by executing: +Run the Voting App by executing: ```console kubectl apply -f manifests ``` -Wait for one or two minutes until the application is running. You can access it at https://vote-[githubid].cloud.okteto.net. +Wait for one or two minutes until the application is running. You can access it at https://localhost:8080. -## Step 5: Develop as a Cloud Native Developer +## Step 3: Develop as a Cloud Native Developer Now start your Okteto Environment by running the following command: @@ -79,7 +50,7 @@ The `okteto up` command will automatically start an Okteto Environment. It will Everything is ready now to set up your VS Code Remote SSH extension to point to `localhost:22000` (follow this [link](https://code.visualstudio.com/docs/remote/ssh#_connect-to-a-remote-host) if you are not familiar with this process). In order to indicate the remote server in VS Code, write `-p 22000 root@localhost` as the Remote Host. -From VS Code, open the remote folder `/usr/src/app`, then open a terminal and execute the following command: +From VS Code, open the remote folder `/src`, then open a terminal and execute the following command: ```console $ python app.py @@ -91,7 +62,7 @@ $ python app.py * Debugger PIN: 117-959-944 ``` -This command will start the python service on your remote development environment. You can verify that everything is up and running by going to your service's endpoint at https://vote-[githubid].cloud.okteto.net. +This command will start the python service on your remote development environment. You can verify that everything is up and running by going to your service's endpoint at https://localhost:8080. Now let's make a code change. Open `app.py` in VS Code and modify the `getOptions` function with the code below: @@ -106,8 +77,10 @@ Go to the browser again and reload the page. Your changes were applied instantly > We recommend to keep Git extensions locally. This way they use your local keys and you don´t need to install them remotely. -## Conclusions +## Step 5: Cleanup -We explained the advantages of developing directly in Kubernetes while keeping the same developer experience than working on a local machine. Working on the Cloud is always better. You don't work on your spreadsheets and listen to media files locally, do you? Stop dealing with local environments and become a Cloud Native Developer today 😎! +Cancel the `okteto up` command by pressing `ctrl + c` and run the following commands to remove the resources created by this guide: -> Interested in improving your Kubernetes and Docker development workflows? [Contact us](mailto:sales@okteto.com?Subject=Improve%20my%20development%20workflow) to see how to install our platform in your own infrastructure. +```console +kubectl delete -f manifests +``` diff --git a/cloud-run/app.py b/vscode/app.py similarity index 100% rename from cloud-run/app.py rename to vscode/app.py diff --git a/vscode-ssh/manifests/deployment.yaml b/vscode/manifests/deployment.yaml similarity index 74% rename from vscode-ssh/manifests/deployment.yaml rename to vscode/manifests/deployment.yaml index 2603cd5..99d816e 100644 --- a/vscode-ssh/manifests/deployment.yaml +++ b/vscode/manifests/deployment.yaml @@ -2,6 +2,8 @@ apiVersion: apps/v1 kind: Deployment metadata: name: vote + annotations: + dev.okteto.com/auto-ingress: "true" spec: replicas: 1 selector: @@ -13,7 +15,7 @@ spec: app: vote spec: containers: - - image: okteto/vote:1.3 + - image: okteto/vote:latest name: vote volumeMounts: - name: ssh diff --git a/vscode-ssh/manifests/service.yaml b/vscode/manifests/service.yaml similarity index 72% rename from vscode-ssh/manifests/service.yaml rename to vscode/manifests/service.yaml index 29e4bb1..981420c 100644 --- a/vscode-ssh/manifests/service.yaml +++ b/vscode/manifests/service.yaml @@ -2,6 +2,8 @@ apiVersion: v1 kind: Service metadata: name: vote + annotations: + dev.okteto.com/auto-ingress: "true" spec: type: ClusterIP ports: diff --git a/vscode-ssh/okteto.yml b/vscode/okteto.yml similarity index 68% rename from vscode-ssh/okteto.yml rename to vscode/okteto.yml index 4479b85..ebff372 100644 --- a/vscode-ssh/okteto.yml +++ b/vscode/okteto.yml @@ -1,6 +1,7 @@ name: vote -image: okteto/vote-ssh:dev +image: okteto/vote:ssh +workdir: /src command: [ "sh", "-c", "cp /etc/ssh-key/* /root/.ssh && /usr/sbin/sshd -D" ] -workdir: /usr/src/app forward: + - 8080:8080 - 22000:22 diff --git a/vscode-ssh/requirements.txt b/vscode/requirements.txt similarity index 100% rename from vscode-ssh/requirements.txt rename to vscode/requirements.txt diff --git a/vscode-ssh/static/stylesheets/style.css b/vscode/static/stylesheets/style.css similarity index 100% rename from vscode-ssh/static/stylesheets/style.css rename to vscode/static/stylesheets/style.css diff --git a/vote/templates/index.html b/vscode/templates/index.html similarity index 100% rename from vote/templates/index.html rename to vscode/templates/index.html