Skip to content

Commit

Permalink
Merge pull request #624 from grycap/egi_brand_v2
Browse files Browse the repository at this point in the history
Egi brand v2
  • Loading branch information
micafer authored Feb 27, 2025
2 parents 4f31d51 + 1e2ea99 commit 55049c3
Show file tree
Hide file tree
Showing 18 changed files with 461 additions and 53 deletions.
114 changes: 110 additions & 4 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# under the License.
"""Main Flask App file."""

import datetime
import yaml
import io
import os
Expand Down Expand Up @@ -129,7 +130,9 @@ def authorized_with_valid_token(f):
@wraps(f)
def decorated_function(*args, **kwargs):

if settings.debug_oidc_token:
if 'token' in session:
oidc_blueprint.session.token = {'access_token': session['token']}
elif settings.debug_oidc_token:
oidc_blueprint.session.token = {'access_token': settings.debug_oidc_token}
else:
try:
Expand Down Expand Up @@ -190,7 +193,11 @@ def home():
if v['description'].find(template_filter) != -1 and "parents" not in tosca["metadata"]:
templates[k] = v

if settings.debug_oidc_token:
# To make easier test endpoints
if 'token' in request.args:
session["token"] = request.args['token']
oidc_blueprint.session.token = {'access_token': request.args['token']}
elif settings.debug_oidc_token:
oidc_blueprint.session.token = {'access_token': settings.debug_oidc_token}
else:
if not oidc_blueprint.session.authorized:
Expand Down Expand Up @@ -408,7 +415,7 @@ def managevm(op=None, infid=None, vmid=None):
vminfo.systems[0].addFeature(Feature("cpu.count", ">=", cpu),
conflict="other", missing="other")
vminfo.systems[0].delValue("memory.size")
vminfo.systems[0].addFeature(Feature("memory.size", ">=", memory, "GB"),
vminfo.systems[0].addFeature(Feature("memory.size", ">=", memory, "GiB"),
conflict="other", missing="other")
if gpu > 0:
vminfo.systems[0].delValue("gpu.count")
Expand All @@ -417,7 +424,7 @@ def managevm(op=None, infid=None, vmid=None):
if disk_size > 0:
vminfo.systems[0].delValue("disks.free_size")
vminfo.systems[0].delValue("disks.0.free_size")
vminfo.systems[0].addFeature(Feature("disks.free_size", ">=", disk_size, "GB"),
vminfo.systems[0].addFeature(Feature("disks.free_size", ">=", disk_size, "GiB"),
conflict="other", missing="other")
response = im.resize_vm(infid, vmid, str(vminfo), auth_data)
else:
Expand Down Expand Up @@ -1622,6 +1629,105 @@ def get_cred_id():
else:
return session['userid']

@app.route('/stats')
@authorized_with_valid_token
def show_stats():
init_date = request.args.get('init_date')
end_date = request.args.get('end_date')
active = request.args.get('active')
today = datetime.datetime.today().date()

if not end_date:
end_date = str(today)

if not init_date:
init_date = str(today - datetime.timedelta(days=180))

access_token = oidc_blueprint.session.token['access_token']

auth_data = utils.getIMUserAuthData(access_token, cred, get_cred_id())
fedcloud_sites = None
inf_actives = []
# Add an element in the first date
infs = [0]
vms = [0]
cpus = [0]
mems = [0]
labels = ["%s 00:00:00" % init_date]
cloud_hosts = []
clouds = [""]
site_name = None
try:
for inf_stat in sorted(im.get_stats(auth_data, init_date, end_date),
key=lambda stat: stat['creation_date']):
if inf_stat['cloud_host']:
# only load this data if a EGI Cloud site appears
if fedcloud_sites is None:
fedcloud_sites = {}
for site in list(utils.getCachedSiteList().values()):
site_host = urlparse(site['url'])[1].split(":")[0]
fedcloud_sites[site_host] = site["name"]

site_name = inf_stat['cloud_host']
if site_name in fedcloud_sites:
site_name = fedcloud_sites[site_name]
elif inf_stat['cloud_type']:
site_name = inf_stat['cloud_type']

if site_name not in cloud_hosts:
cloud_hosts.append(site_name)

if active:
curr_date = datetime.datetime.strptime(inf_stat['creation_date'], "%Y-%m-%d %H:%M:%S")
inf_list = list(inf_actives)
for inf in inf_list:
del_time = datetime.datetime.strptime(inf[4], "%Y-%m-%d %H:%M:%S")
if del_time <= curr_date:
infs.append(-1)
vms.append(inf[0] * -1)
mems.append(inf[1] * -1.0)
cpus.append(inf[2] * -1)
clouds.append(inf[3])
labels.append(inf[4])
inf_actives.remove(inf)

inf_actives.append((inf_stat['vm_count'], (inf_stat['memory_size'] / 1024),
inf_stat['cpu_count'], site_name, "%s 12:00:00" % inf_stat['last_date']))

infs.append(1)
vms.append(inf_stat['vm_count'])
mems.append((inf_stat['memory_size'] / 1024))
cpus.append(inf_stat['cpu_count'])
labels.append(inf_stat['creation_date'])
clouds.append(site_name)

if active:
curr_date = datetime.datetime.strptime("%s 23:59:59" % end_date, "%Y-%m-%d %H:%M:%S")
for inf in inf_actives:
del_time = datetime.datetime.strptime(inf[4], "%Y-%m-%d %H:%M:%S")
if del_time <= curr_date:
infs.append(-1)
vms.append(inf[0])
mems.append(inf[1])
cpus.append(inf[2])
clouds.append(inf[3])
labels.append(inf[4])

# Add an element in the last date
infs.append(0)
vms.append(0)
mems.append(0)
cpus.append(0)
labels.append("%s 23:59:59" % end_date)
clouds.append("")

except Exception as ex:
flash("Error Getting Stats: %s." % ex, 'error')

return render_template('stats.html', infs=infs, vms=vms, cpus=cpus, mems=mems, labels=labels,
today=str(today), init_date=init_date or "", end_date=end_date or "",
cloud_hosts=cloud_hosts, clouds=clouds)

return app


Expand Down
2 changes: 1 addition & 1 deletion app/cred.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def validate_cred(self, userid, new_cred):
if isequal:
return 1, "Credentials already available."

if new_cred["type"] == "EUNode":
if new_cred["type"] in ["EUNode", "EUNodeCont"]:
if new_cred["node"] == cred["node"]:
return 2, ("This site has already a Credential with the same EU Node site." +
" This may cause problems authenticating with the site." +
Expand Down
18 changes: 17 additions & 1 deletion app/im.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

class InfrastructureManager():

def __init__(self, im_url, timeout=60):
def __init__(self, im_url, timeout=120):
self.im_url = im_url
self.timeout = timeout

Expand Down Expand Up @@ -160,6 +160,22 @@ def change_user(self, infid, token, overwrite, auth_data):

return requests.post(url, headers=headers, timeout=self.timeout, data=new_auth)

def get_stats(self, auth_data, init_date=None, end_date=None):
headers = {"Authorization": auth_data}
url = "%s/stats" % self.im_url
if init_date:
url += "?init_date=%s" % init_date
if end_date:
if init_date:
url += "&"
else:
url += "?"
url += "end_date=%s" % end_date
response = requests.get(url, headers=headers, timeout=self.timeout)
response.raise_for_status()
stats = response.json()
return stats['stats']

def remove_resources(self, infid, vm_list, auth_data):
headers = {"Authorization": auth_data}
url = "%s/infrastructures/%s/vms/%s" % (self.im_url, infid, vm_list)
Expand Down
2 changes: 1 addition & 1 deletion app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(self, config):
self.static_sites_url = config.get('STATIC_SITES_URL', "")
self.appdb_cache_timeout = config.get('APPDB_CACHE_TIMEOUT', 3600)
self.debug_oidc_token = config.get('DEBUG_OIDC_TOKEN', None)
self.imTimeout = config.get('IM_TIMEOUT', 60)
self.imTimeout = config.get('IM_TIMEOUT', 120)
self.checkToscaChangesTime = config.get('CHECK_TOSCA_CHANGES_TIME', 120)
self.vault_url = config.get('VAULT_URL', None)
self.im_auth = config.get('IM_AUTH', None)
Expand Down
7 changes: 0 additions & 7 deletions app/static/chart/Chart.min.js

This file was deleted.

13 changes: 13 additions & 0 deletions app/static/chart/chart.min.js

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions app/static/chart/chartjs-adapter-date-fns.bundle.min.js

Large diffs are not rendered by default.

30 changes: 16 additions & 14 deletions app/templates/advanced_config.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ <h5>Cloud Provider:</h5>
</div>


<script src="{{ url_for('static', filename='chart/Chart.min.js') }}"></script>
<script src="{{ url_for('static', filename='chart/chart.min.js') }}"></script>
<script src="{{ url_for('static', filename='chart/utils.js') }}"></script>

<script>
Expand All @@ -29,15 +29,17 @@ <h5>Cloud Provider:</h5>
borderWidth: 0
}
},
legend: {
display: false
},
responsive: false,
title: {
display: true,
text: 'VCPUs',
padding: 0
}
plugins: {
legend: {
display: false
},
title: {
display: true,
text: 'VCPUs',
padding: 0
}
}
}
};

Expand All @@ -47,10 +49,10 @@ <h5>Cloud Provider:</h5>
config[resource_types[i]] = JSON.parse(JSON.stringify(config["gen"]));;
}

config["ram"].options.title.text = "RAM (GB)"
config["instances"].options.title.text = "Instances"
config["floating_ips"].options.title.text = "Float IPs"
config["security_groups"].options.title.text = "SGs"
config["ram"].options.plugins.title.text = "RAM (GB)"
config["instances"].options.plugins.title.text = "Instances"
config["floating_ips"].options.plugins.title.text = "Float IPs"
config["security_groups"].options.plugins.title.text = "SGs"

window.onload = function() {
window.myPies = {};
Expand Down Expand Up @@ -119,7 +121,7 @@ <h5>Cloud Provider:</h5>
} else {
document.getElementById('imageID').setAttribute("placeholder", "Image ID");
}
if (cred_type == 'OSCAR' || cred_type == 'Kubernetes' ) {
if (cred_type == 'OSCAR' || cred_type == 'Kubernetes' || cred_type == 'EUNodeCont') {
// OSCAR or K8s do not set images
$('#cloudImages').hide();
activateSubmit();
Expand Down
1 change: 1 addition & 0 deletions app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">Advanced</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="{{ url_for("show_settings") }}">Settings</a>
<a class="dropdown-item" href="{{ url_for("show_stats") }}">Stats</a>
</div>
</li>
{% if session["external_links"]|length > 0 %}
Expand Down
20 changes: 20 additions & 0 deletions app/templates/modal_creds.html
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,26 @@
</select>
</div>
</div>
{% elif cred_type == "EUNodeCont" %}
<div class="row form-group">
<div class="col">
<input placeholder="Token" name="token" class="col-sm-12 form-control my-1" type="text" id="token" value="{{ creds['token'] if creds else '' }}" required/>
</div>
<div class="col">
<select class="js-example-basic-single js-states form-control" id="node" name="node" required>
<option name="node" value="">-- Set EU Node Provider --</option>
<option name="node" value="eu-1" {{ "selected" if creds and creds['node'] == "eu-1" else '' }}>eu-1</option>
<option name="node" value="eu-2" {{ "selected" if creds and creds['node'] == "eu-2" else '' }}>eu-2</option>
</select>
</div>
</div>
<div class="row form-group">
<div class="col">
<input placeholder="Project ID" name="namespace" class="col-sm-12 form-control my-1" type="text" id="namespace" value="{{ creds['namespace'] if creds else '' }}" required/>
</div>
<div class="col">
</div>
</div>
{% else %}


Expand Down
19 changes: 12 additions & 7 deletions app/templates/service_creds.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ <h4 class="font-weight-bold text-primary">Cloud Credentials</h4>
<a class="dropdown-item" data-id="" data-type="OSCAR" data-bs-toggle="modal" data-bs-target="#newModal" href="#"><img src="{{ url_for('static', filename='images/OSCARRow.png') }}"/></a>
<a class="dropdown-item" data-id="" data-type="CH" data-bs-toggle="modal" data-bs-target="#newModal" href="#"><img src="{{ url_for('static', filename='images/CHRow.png') }}"/></a>
<a class="dropdown-item" data-id="" data-type="EUNode" data-bs-toggle="modal" data-bs-target="#newModal" href="#"><img src="{{ url_for('static', filename='images/EUNodeRow.png') }}"/></a>
<!--
<a class="dropdown-item" data-id="" data-type="EUNodeCont" data-bs-toggle="modal" data-bs-target="#newModal" href="#"><img src="{{ url_for('static', filename='images/EUNodeContRow.png') }}"/></a>
-->
</div>
</div>
</div> <!-- / .row -->
Expand Down Expand Up @@ -200,13 +203,15 @@ <h5 class="modal-title">Vault Info</h5>
$(".updateBtn").click(function () {
var button = $(event.relatedTarget) // Button that triggered the modal
var cred_id = button.data('id')
// add spinner to button
$(this).parent().find(".updateBtn").addClass("disabled", true);
$(this).addClass("updateBtn", true);
if (cred_id == "") {
$(this).html( `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Adding ...` );
} else {
$(this).html( `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Updating...` );
if ($('#credForm')[0].checkValidity()) {
// add spinner to button
$(this).parent().find(".updateBtn").addClass("disabled", true);
$(this).addClass("updateBtn", true);
if (cred_id == "") {
$(this).html( `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Adding ...` );
} else {
$(this).html( `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Updating...` );
}
}
});
});
Expand Down
1 change: 0 additions & 1 deletion app/templates/ssh_keys.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,3 @@ <h5 class="modal-title">Confirm SSH Key deletion</h5>

</script>
{% endblock %}

Loading

0 comments on commit 55049c3

Please sign in to comment.