Skip to content

Commit

Permalink
support rejecting entitlements (#10)
Browse files Browse the repository at this point in the history
Co-authored-by: Dave Cavaletto <[email protected]>
  • Loading branch information
caddac and caddac authored Jul 6, 2022
1 parent fb8b8d3 commit 37e7bcd
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 15 deletions.
10 changes: 6 additions & 4 deletions backend-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

This is a User Interface for the backend integration API.

## Environment Variables

# TODO
- [ ] Code up this solution
- [ ] show an approve button for each requested entitlement
- [ ] drop-down filter to show different status entitlements (active, cancelled, etc)
|Variable Name|Platform|Description| Example|
|--|--|---|--|
|PORT|GKE|The port the container should run on |8080|
|API_URL|GKE|The URL for the backend integration API|http://doit-easily-api.prod.svc.cluster.local:8080|
|URL_PREFIX|GKE|The prefix to append to all routes, should match path rules in your ingress|/be|
53 changes: 48 additions & 5 deletions backend-ui/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,25 @@
import requests
from flask import Flask, request, render_template

app = Flask(__name__, static_folder="static", static_url_path="/be")

API_URL = os.environ["API_URL"]
assert API_URL
URL_PREFIX = os.environ.get("URL_PREFIX", "")

# :embarassed: don't look at me, I'm ugly
# this is super hacky and lets us set the url prefix on the static js code. we should not do this.
# this entire app should become an SPA and the backend should the backend API rather than a separate server.
# for now this hack lets us set the url prefix to whatever the customer needs based on their ingress settings
with open("static/approve.js", 'r') as file:
filedata = file.read()
filedata = filedata.replace('{URL_PREFIX}', URL_PREFIX)
with open("static/approve.js", 'w') as file:
file.write(filedata)

app = Flask(__name__, static_folder="static", static_url_path=URL_PREFIX)


# assert URL_PREFIX starts with a /

def get_entitlements(state):
try:
query_string = f'?state={state}' if state else ''
Expand All @@ -22,18 +35,48 @@ def get_entitlements(state):


# NOTE: we could just make this an SPA...then we don't need a server at all
@app.route("/be/entitlements")
@app.route(f"{URL_PREFIX}/entitlements")
def entitlements():
try:
state = request.args.get('state', "ACTIVATION_REQUESTED")
page_context = {}
print("loading index")
entitlement_response = get_entitlements(state=state)
print(f"entitlements: {entitlement_response}")
page_context["entitlements"] = list(entitlement_response['entitlements']) if 'entitlements' in entitlement_response else []
page_context["entitlements"] = list(
entitlement_response['entitlements']) if 'entitlements' in entitlement_response else []

return render_template("noauth.html", **page_context)
except Exception:
except Exception as e:
print(e)
return {"error": "Loading failed"}, 500


@app.route(f"{URL_PREFIX}/approve", methods=["POST"])
def approve():
try:
# call the backend api /entitlement/approve endpoint
msg_json = request.json
response = requests.post(f"{API_URL}/entitlement/approve", json={"entitlement_id": msg_json['entitlement_id']})
return {}, response.status_code
except Exception as e:
print(e)
return {"error": "Loading failed"}, 500


@app.route(f"{URL_PREFIX}/reject", methods=["POST"])
def reject():
try:
# call the backend api /entitlement/reject endpoint
msg_json = request.json
print(f"rejecting: {msg_json['entitlement_id']}")
response = requests.post(f"{API_URL}/entitlement/reject",
json={"entitlement_id": msg_json['entitlement_id'],
"reason": msg_json["reason"]})
print(f"response: {response}")
return {}, response.status_code
except Exception as e:
print(e)
return {"error": "Loading failed"}, 500


Expand Down
35 changes: 33 additions & 2 deletions backend-ui/static/approve.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ async function approve(entitlement_id) {
try {
// const token = await firebase.auth().currentUser.getIdToken();
//no auth because the entire site needs to be secured behind IAP
const response = await fetch('/approve', {
const response = await fetch('{URL_PREFIX}/approve', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Expand All @@ -12,15 +12,46 @@ async function approve(entitlement_id) {
});
if (response.ok) {
const text = await response.json();
window.alert(text);
console.log(text)
// window.alert(text);
window.location.reload();
}
else {
window.alert('Something went wrong... Please try again!');
}
} catch (err) {
console.log(`Error when submitting approval: ${err}`);
window.alert('Something went wrong... Please try again!');
}
}

async function reject(entitlement_id, reason) {
try {
// const token = await firebase.auth().currentUser.getIdToken();
//no auth because the entire site needs to be secured behind IAP
const response = await fetch('{URL_PREFIX}/reject', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
// Authorization: `Bearer ${token}`,
},
body: JSON.stringify({entitlement_id, reason})
});
if (response.ok) {
const text = await response.json();
console.log(text)
// window.alert(text);
window.location.reload();
}
else {
window.alert('Something went wrong... Please try again!');
}
} catch (err) {
console.log(`Error when submitting rejection: ${err}`);
window.alert('Something went wrong... Please try again!');
}
}

// function go() {
// console.log('here we go')
// const elem = document.querySelector('select')
Expand Down
6 changes: 3 additions & 3 deletions backend-ui/templates/noauth.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ <h4 class="header center">Entitlement Requests</h4>
<div style="width: 25px">
<table class="striped responsive-table">
<thead>

<tr>
<th>Account ID</th>
<th>Create Time</th>
Expand All @@ -50,7 +49,7 @@ <h4 class="header center">Entitlement Requests</h4>
<th>State</th>
<th>Update Time</th>
<th>Usage Reporting ID</th>
<th>Approval</th>
<th>Approve/Reject</th>
</tr>
</thead>
<tbody>
Expand All @@ -67,7 +66,8 @@ <h4 class="header center">Entitlement Requests</h4>
<td>{{ entity['state'] }}</td>
<td>{{ entity['updateTime'] }}</td>
<td>{{ entity['usageReportingId'] }}</td>
<td><button class="btn" onClick="approve('{{ entity['account'].split('/')[-1] }}')">Approve</button></td>
<td><button class="btn" onClick="approve('{{ entity['name'].split('/')[-1] }}')">Approve</button>
<button class="btn" onClick="reject('{{ entity['name'].split('/')[-1] }}', 'cancelled from UI')">Reject</button></td>
</tr>
{% endfor %}
</tbody>
Expand Down
2 changes: 1 addition & 1 deletion schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ x-google-marketplace:
applicationApiVersion: v1beta1
# The published version is required and MUST match the tag
# of the deployer image
publishedVersion: '0.1.2'
publishedVersion: '0.2.0'
publishedVersionMetadata:
releaseNote: >-
Initial Release of Doit Easily backend integration.
Expand Down

0 comments on commit 37e7bcd

Please sign in to comment.