From b413eefd3be0da373c206b6fe2193dd7a83f3b53 Mon Sep 17 00:00:00 2001 From: Dheeraj Tingloo Date: Thu, 30 Apr 2020 11:11:27 +0530 Subject: [PATCH 1/7] v1.0 --- .idea/.gitignore | 3 + .idea/clocks.iml | 15 ++++ .../inspectionProfiles/profiles_settings.xml | 6 ++ .idea/misc.xml | 4 + .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ Dockerfile | 16 ++++ README.md | 73 ++++++------------- __main__.py | 0 cloudbuild.yaml | 20 +++++ main.py | 39 ++++++++++ requirements.txt | 4 + templates/index.html | 42 +++++++++++ 13 files changed, 187 insertions(+), 49 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/clocks.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 Dockerfile create mode 100644 __main__.py create mode 100644 cloudbuild.yaml create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 templates/index.html diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/clocks.iml b/.idea/clocks.iml new file mode 100644 index 0000000..4f2c9af --- /dev/null +++ b/.idea/clocks.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a2e120d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..bd03109 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7e2902c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +from alpine:latest + +RUN apk add --no-cache python3-dev \ + && pip3 install --upgrade pip + +WORKDIR /app +COPY . /app + +RUN pip3 --no-cache-dir install -r requirements.txt + +RUN pylint main.py + +EXPOSE 5000 + +ENTRYPOINT ["python3"] +CMD ["main.py"] \ No newline at end of file diff --git a/README.md b/README.md index 4a77c09..433c784 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,33 @@ -# Clock Exercise -We are interested in running code of course, but even more in your development process and understanding of Software Development Lifecycle Management. +Calculating angle between Clock handles Exercise- -**Fork this repo, then get to work.** Remember that this is a DevOps team, so make sure your repo reflects that. Spend however much time you feel is reasonable. It doesn’t matter if the project is ‘done’, nothing ever is. **When you’re ready push your changes back to Github and put in a pull request back to the base repo.** +This codebase shows how to calculate angle between clock handles. -This exercise is not meant to take an excessive amount of time. It is an opportunity for you to demonstrate your skills without the stress of an interview. If you start to run out of time, it’s ok to leave an imaginary team member a TODO list that details all the things you didn’t quite have time to do in order for your solution to go to prod. +For example - If user pass input as 03:00, it should yield an angle of 90 degree. -If you need clarification, or would like to request additional information, pease reach out to the interviewer by email. +Deployed URL: https://ca-cr-app-icbqkvt2oa-uc.a.run.app/ -## Scenario +Technology Stack -You have just joined a DevOps team. This team lives by DevOps principles and you want to let them know you mean business! This particular team is developing a product that is deployed in a Google Cloud Project. + 1. Python 3.7 + 2. Cloud Source Repository + 3. Cloud Build + 4. Docker + 5. Cloud Run + 6. HTML5 + 7. Ajax + +Following is the approach steps: -This sprint, the team has been asked to work on a new feature that depends on being able to calculate the angle between the hands on a clock face. They’ve asked you to write some code to help out with that. This is an IOT project, and they have sensors emitting times at a pretty low frequency (about 10 a minute), and for some reason they need to be processed and stored as angles. + i) Using python language build Flask application that calculates the angle between clock handles. + ii) Using python3 packages like Flask, Request,Render_Template, Jsonify etc and HTML5, AJAX to build interactive front end/web page for accepting user parameters . + iii) Using GIT create local repository. + iv) Using Docker to convert Python Flask application into Docker Image -You may need to make some assupmtions, that's OK, just document what they are and move on. +Deployment using GCP developer tools- -The team loves innovation, so you can use whatever languages and technologies you like to complete this. Approach this problem as if your code will go to production. Whilst we don’t expect the code to be perfect, we are not looking for a hacked together script. - -Your solution should offer the rest of the team a way to submit a time and receive an angle in return or store it somewhere. They are little fuzzy on the best way to get this low frequency data to your service, so if you can offer them any hints on that, they’d be really happy. - -## How to proceed - -**Fork this repo, then get to work.** Remember that this is a DevOps team, so make sure your repo reflects that. Spend however much time you feel is reasonable. It doesn’t matter if the project is ‘done’, nothing ever is. **When you’re ready push your changes back to Github and put in a pull request back to the base repo.** - -Be sure to add in instructions for how to deploy your solution, and document things in a way that the rest of the team can pick this up and run with it. Remember you have all the tools in the GCP arsenal at your disposal. - -We are looking for you to demonstrate your abilities in software practices and DevOps, including reusability, portability, reliability, ease of maintenance etc. - -Think about how this will actually be deployed and maintained in the future as you build on it and expand it. You don’t have to implement deployment practices if you don’t have the time or resources, its ok to just document those. - ---- - -## Product Backlog Item (Sprint Story) - -Here is the story that is in the backlog. - -As with all stories, the team may have been optimistic with how much can be done in the time permitted. It's ok to meet some of the acceptance criteria by documenting what you would do in the next sprint! Prioritize your time and make sure you have some technical content to deliver. - -### Description:- - -As a team
-We need a serivce that we can send a time value to and have it return or store an angle value
-So that we can use it in downstream processing - -### Detail:- - -We need to calculate the angle between the hands on a clock face. For example input 03:00 would yield 90 degrees. - -### Acceptance Criteria:- - -1) Code to perform the calculation -1) How will you deploy this solution (in code or as a todo list if time is limited). i.e. how and where will this run? -1) How will you manage any infrastructure needed? -1) Delivered as a feature branch in the repo fork -1) Bonus points for a working deployed solution in GCP that you can demo at the "sprint review" (ie interview) -1) Any DevOps/Cicd components that would support this feature in a production setting + 1. Cloud Build to create a CI/CD pipeline for building, deploying. + 2. Cloud Run that is a server-less compute platform that enables above hosted app URL. + 3. Cloud Source Repositories, a private Git repositories hosted on Google Cloud. + Author : Dheeraj Tingloo + Created date : 29-April-2020 diff --git a/__main__.py b/__main__.py new file mode 100644 index 0000000..e69de29 diff --git a/cloudbuild.yaml b/cloudbuild.yaml new file mode 100644 index 0000000..674d5ba --- /dev/null +++ b/cloudbuild.yaml @@ -0,0 +1,20 @@ +steps: + # build the container image Need to implement later + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/ind-coe/ca-repo:$COMMIT_SHA', '.'] + # push the container image to Container Registry + - name: 'gcr.io/cloud-builders/docker' + args: ['push', 'gcr.io/ind-coe/ca-rep:$COMMIT_SHA'] + # Deploy container image to Cloud Run + - name: 'gcr.io/cloud-builders/gcloud' + args: + - 'run' + - 'deploy' + - 'ca-cr-app' + - '--image' + - 'gcr.io/ind-coe/ca-repo:$COMMIT_SHA' + - '--region' + - 'us-central1' + - '--platform' + - 'managed' + - '--allow-unauthenticated' diff --git a/main.py b/main.py new file mode 100644 index 0000000..894cf13 --- /dev/null +++ b/main.py @@ -0,0 +1,39 @@ +""" +########### + Author: Dheeraj Tingloo + Created Date: 27-April-2020 + Use Case: Calculating angle between clock hands! +########### +""" +from flask import Flask, render_template, request, jsonify + +APP = Flask(__name__) + + +@APP.route('/') +def index(): + """Calling default web page.""" + return render_template('index.html') + + +@APP.route('/cal_clock_angle') +def cal_clock_angle(): + """ + Getting arguments from user. + Using abs() to make generalised formula. + And return calculation back to web call in JSON format. + """ + hrs = request.args.get('hrs', 0, type=str) + mins = request.args.get('min', 0, type=str) + + # Input validation for hours and minutes. + if 1 <= int(hrs) <= 12 and 0 <= int(mins) < 60: + angle = float(abs(11 / 2 * int(mins) - 30 * int(hrs))) + else: + return jsonify(result="Error in input hours or minutes.") + + return jsonify(result=" {}:{} makes the following angle {}°".format(hrs, mins, angle)) + + +if __name__ == "__main__": + APP.run(host='0.0.0.0', debug=True) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4eaec70 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +Flask==1.1.1 +gunicorn==20.0.4 +pytest==5.2.2 +pylint==2.4.3 \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..b787c1f --- /dev/null +++ b/templates/index.html @@ -0,0 +1,42 @@ + + + + + + + + + +
+
+

Calculate angle between clock handles.

+
+
+
+

+ : + = + ? +

+

+
+
+ + \ No newline at end of file From dbdc94190ad8a6dad2f9fbae5b7cb9f2be3d8ad4 Mon Sep 17 00:00:00 2001 From: dt1947in <64526241+dt1947in@users.noreply.github.com> Date: Thu, 30 Apr 2020 13:20:49 +0530 Subject: [PATCH 2/7] Update cloudbuild.yaml --- cloudbuild.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 674d5ba..5454e84 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -18,3 +18,5 @@ steps: - '--platform' - 'managed' - '--allow-unauthenticated' + - '--source=https://source.cloud.google.com/ind-coe/github_dt1947in_clocks/+/master:' + dir: 'functions/autodeploy' From 8002872534a141c20503163bcf779c550f3307f0 Mon Sep 17 00:00:00 2001 From: dt1947in <64526241+dt1947in@users.noreply.github.com> Date: Thu, 30 Apr 2020 13:39:19 +0530 Subject: [PATCH 3/7] Update cloudbuil.yaml --- cloudbuild.yaml | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 5454e84..cb74849 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -1,22 +1,25 @@ steps: - # build the container image Need to implement later - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/ind-coe/ca-repo:$COMMIT_SHA', '.'] - # push the container image to Container Registry - - name: 'gcr.io/cloud-builders/docker' - args: ['push', 'gcr.io/ind-coe/ca-rep:$COMMIT_SHA'] - # Deploy container image to Cloud Run - - name: 'gcr.io/cloud-builders/gcloud' - args: - - 'run' - - 'deploy' - - 'ca-cr-app' - - '--image' - - 'gcr.io/ind-coe/ca-repo:$COMMIT_SHA' - - '--region' - - 'us-central1' - - '--platform' - - 'managed' - - '--allow-unauthenticated' - - '--source=https://source.cloud.google.com/ind-coe/github_dt1947in_clocks/+/master:' - dir: 'functions/autodeploy' + - + name: gcr.io/cloud-builders/docker + args: + - build + - '-t' + - 'gcr.io/ind-coe/ca-rep:$COMMIT_SHA' + - . + - + name: gcr.io/cloud-builders/docker + args: + - push + - 'gcr.io/ind-coe/ca-rep:$COMMIT_SHA' + - + name: gcr.io/cloud-builders/gcloud + args: + - functions + - deploy + - ca-cr-app + - '--runtime' + - python37 + - '--trigger-http' + - '--allow-unauthenticated' + - '--source=https://source.cloud.google.com/ind-coe/github_dt1947in_clocks/+/master:' + dir: 'functions/autodeploy' From 1fb261000c85949a2add216edf9e42dd6e90201d Mon Sep 17 00:00:00 2001 From: dt1947in <64526241+dt1947in@users.noreply.github.com> Date: Thu, 30 Apr 2020 13:47:59 +0530 Subject: [PATCH 4/7] Update cloudbuild.yaml --- cloudbuild.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index cb74849..5a24e59 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -1,16 +1,20 @@ steps: - + # build the container image name: gcr.io/cloud-builders/docker args: - build - '-t' - - 'gcr.io/ind-coe/ca-rep:$COMMIT_SHA' + - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' - . + # push the container image to Container Registry - name: gcr.io/cloud-builders/docker args: - push - - 'gcr.io/ind-coe/ca-rep:$COMMIT_SHA' + - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' + + # Deploy container image to Cloud Run - name: gcr.io/cloud-builders/gcloud args: From 72af099502c5bfb0a1d7f96e8573fbb82e426af4 Mon Sep 17 00:00:00 2001 From: dt1947in <64526241+dt1947in@users.noreply.github.com> Date: Thu, 30 Apr 2020 14:04:50 +0530 Subject: [PATCH 5/7] Update in cloudbuild.yaml --- cloudbuild.yaml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 5a24e59..6454918 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -1,29 +1,28 @@ steps: - - # build the container image name: gcr.io/cloud-builders/docker args: - build - '-t' - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' - . - # push the container image to Container Registry - name: gcr.io/cloud-builders/docker args: - push - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' - - # Deploy container image to Cloud Run - name: gcr.io/cloud-builders/gcloud args: - - functions + - run - deploy - ca-cr-app - - '--runtime' - - python37 - - '--trigger-http' + - '--image' + - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' + - '--region' + - us-central1 + - '--platform' + - managed - '--allow-unauthenticated' - - '--source=https://source.cloud.google.com/ind-coe/github_dt1947in_clocks/+/master:' - dir: 'functions/autodeploy' + + From d0a1f8f54b4037b80bd69d24574d733db0f5f615 Mon Sep 17 00:00:00 2001 From: dt1947in <64526241+dt1947in@users.noreply.github.com> Date: Thu, 30 Apr 2020 14:10:59 +0530 Subject: [PATCH 6/7] Update main.py --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 894cf13..1a37b5c 100644 --- a/main.py +++ b/main.py @@ -32,7 +32,7 @@ def cal_clock_angle(): else: return jsonify(result="Error in input hours or minutes.") - return jsonify(result=" {}:{} makes the following angle {}°".format(hrs, mins, angle)) + return jsonify(result=" {}:{} This makes the following angle {}°".format(hrs, mins, angle)) if __name__ == "__main__": From bfe061951bedad228b354b2d432fb94e2089b0f5 Mon Sep 17 00:00:00 2001 From: dt1947in <64526241+dt1947in@users.noreply.github.com> Date: Thu, 30 Apr 2020 14:17:53 +0530 Subject: [PATCH 7/7] Update code commits in cloudbuild.yaml --- cloudbuild.yaml | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 6454918..0146531 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -1,4 +1,5 @@ steps: + # build the container image - name: gcr.io/cloud-builders/docker args: @@ -6,23 +7,24 @@ steps: - '-t' - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' - . + # push the container image to Container Registry - name: gcr.io/cloud-builders/docker args: - push - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' - - - name: gcr.io/cloud-builders/gcloud + + # Deploy container image to Cloud Run + - + name: 'gcr.io/cloud-builders/gcloud' args: - - run - - deploy - - ca-cr-app - - '--image' - - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' - - '--region' - - us-central1 - - '--platform' - - managed - - '--allow-unauthenticated' - - + - 'run' + - 'deploy' + - 'ca-cr-app' + - '--image' + - 'gcr.io/ind-coe/github-repo:$COMMIT_SHA' + - '--region' + - 'us-central1' + - '--platform' + - 'managed' + - '--allow-unauthenticated'