Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions feature1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Clock Exercise Solution

#### 1. Code to perform the calculation - Please see file main.py
#### 2. 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? - Deployment will be done by Terraform
#### 3. How will you manage any infrastructure needed? - All GCP services used in the solution are Serverless so infrastruction management is not necessary
#### 4. Delivered as a feature branch in the repo fork - All code is available in the branch 'feature1'
#### 5. Bonus points for a working deployed solution in GCP that you can demo at the "sprint review" (ie interview) - A working prototype has been deployed on GCP
#### 6. Any DevOps/Cicd components that would support this feature in a production setting - Please see the workflow diagram below



![Workflow](https://github.com/pravin-svn/clocks/blob/feature1/feature1/workflow.png)
18 changes: 18 additions & 0 deletions feature1/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
steps:
- name: 'python:3.7-slim'
id: Test
entrypoint: /bin/sh
args:
- -c
- 'pip install google-cloud-datastore && python3 test.py'
- name: 'gcr.io/cloud-builders/gcloud'
id: Deploy
args:
- functions
- deploy
- cf_get_angle
- --source=.
- --trigger-topic=topic_time_value
- --runtime=python37
- --entry-point=cf_get_angle

46 changes: 46 additions & 0 deletions feature1/gcb_slack/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const { IncomingWebhook } = require('@slack/webhook');
const url = process.env.SLACK_WEBHOOK_URL;

const webhook = new IncomingWebhook(url);

// subscribeSlack is the main function called by Cloud Functions.
module.exports.subscribeSlack = (pubSubEvent, context) => {
const build = eventToBuild(pubSubEvent.data);

// Skip if the current status is not in the status list.
// Add additional statuses to list if you'd like:
// QUEUED, WORKING, SUCCESS, FAILURE,
// INTERNAL_ERROR, TIMEOUT, CANCELLED
const status = ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT'];
if (status.indexOf(build.status) === -1) {
return;
}

// Send message to Slack.
const message = createSlackMessage(build);
webhook.send(message);
};

// eventToBuild transforms pubsub event message to a build object.
const eventToBuild = (data) => {
return JSON.parse(Buffer.from(data, 'base64').toString());
}

// createSlackMessage creates a message from a build object.
const createSlackMessage = (build) => {
const message = {
text: `Build \`${build.id}\``,
mrkdwn: true,
attachments: [
{
title: 'Build logs for cf_get_angle',
title_link: build.logUrl,
fields: [{
title: 'Status',
value: build.status
}]
}
]
};
return message;
}
9 changes: 9 additions & 0 deletions feature1/gcb_slack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "google-container-slack",
"version": "0.0.1",
"description": "Slack integration for Google Cloud Build, using Google Cloud Functions",
"main": "index.js",
"dependencies": {
"@slack/webhook": "5.0.1"
}
}
64 changes: 64 additions & 0 deletions feature1/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#from google.cloud import pubsub_v1
from google.cloud import datastore
import datetime
import base64

client = datastore.Client('pravin-clock-exercise')


def getAngles(t):

hh, mm = map(int, t.split(':'))

# validate the input
if (hh < 0 or mm < 0 or hh > 24 or mm > 60):
print('The input for time value is Invalid')

if (hh >= 12):
hh = hh - 12
if (mm == 60):
mm = 0

# The minute hand moves 360 degree in 60 minute(or 6 degree in one minute)
# and hour hand moves 360 degree in 12 hours(or 0.5 degree in 1 minute).
# In h hours and m minutes, the minute hand would move (h*60 + m)*6
# and hour hand would move (h*60 + m)*0.5.

hour_angle = 0.5 * (hh * 60 + mm)
minute_angle = 6 * mm

# Find the difference between two angles
angle = abs(hour_angle - minute_angle)

# Return the smaller angle of two possible angles
angle = min(360 - angle, angle)

return angle


def cf_get_angle(event, context):

'''
if context.event_type == 'google.pubsub.topic.publish':
str_time = base64.b64decode(event['data']).decode('utf-8')
else:
str_time = event['data']
'''
str_time = event['data']
angle = int(getAngles(str_time))
result = f"Angle for time value {str_time} is {angle} degrees"
print(result)

key = client.key('ClockAngles')

ds_table = datastore.Entity(
key, exclude_from_indexes=['result'])

ds_table.update({
'created': datetime.datetime.utcnow(),
'result': result,
'input': str_time,
'angle': angle
})

client.put(ds_table)
1 change: 1 addition & 0 deletions feature1/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
google-cloud-datastore
12 changes: 12 additions & 0 deletions feature1/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import unittest
import main


class TestMain(unittest.TestCase):
def test_case_1(self):
time_value = "03:00"
result = main.getAngles(time_value)
self.assertEqual(result, 90)


unittest.main()
Binary file added feature1/workflow.pdf
Binary file not shown.
Binary file added feature1/workflow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.