Skip to content
Snippets Groups Projects
Commit 8f86652e authored by Dimitrios Spatharakis's avatar Dimitrios Spatharakis
Browse files

cleanup

parent d1d23514
No related branches found
No related tags found
2 merge requests!2Main,!1Main
Showing
with 8560 additions and 0 deletions
import requests
import json
# Base URL of the Flask application
BASE_URL = 'http://localhost:3000'
hdag_descriptor = {
"description": "string",
"hdaGraphIntent": "string",
"id": "string",
"services": [
{
"deploymentType": "auto",
"intent": {
"affinity": "string",
"consumption": "LOW",
"location": "FOLLOWUSER",
"sla": "MMTC"
},
"ref": "string"
}
]
}
# Registration endpoint
def register_user(username, password, email):
url = f"{BASE_URL}/register"
data = {
'username': username,
'password': password,
'email': email
}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(data), headers=headers)
print(response.json())
# Login endpoint
def login(username, password):
url = f"{BASE_URL}/login"
data = {
'username': username,
'password': password
}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(data), headers=headers)
if response.status_code == 200:
access_token = response.json().get('access_token')
refresh_token = response.json().get('refresh_token')
print (access_token)
return access_token, refresh_token
else:
print("Login failed.")
return None, None
# Create project endpoint
def create_project(project_name, access_token):
url = f"{BASE_URL}/create_project"
headers = {'Authorization': f'Bearer {access_token}'}
data = {'project': project_name}
response = requests.post(url, headers=headers, data=data)
print(response.json())
# Fetch artifacts endpoint
def fetch_artifacts(access_token, project_name, artifact_type):
print ("Testing fetch information")
url = f"{BASE_URL}/{project_name}/fetch_artifacts"
headers = {'Authorization': f'Bearer {access_token}'}
data = {'artifact_type': artifact_type, 'project_name': project_name}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Fetch artifacts information endpoint
def fetch_artifacts_information(access_token, project_name, artifact_id, artifact_type):
print ("Testing fetch_artifacts_information")
url = f"{BASE_URL}/{project_name}/fetch_artifacts_information"
headers = {'Authorization': f'Bearer {access_token}'}
data = {'artifact_id' : artifact_id,'artifact_type': artifact_type, 'project_name': project_name}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Test the /clusters endpoint
def test_clusters_endpoint(access_token):
print('Testing /clusters endpoint...')
url = f"{BASE_URL}/clusters"
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get(url, headers=headers)
print(f'Response Status Code: {response.status_code}')
print('Response JSON:')
print(response.json())
# Test the /devices endpoint
def test_devices_endpoint(access_token):
print('Testing /devices endpoint...')
url = f"{BASE_URL}/devices"
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get(url, headers=headers)
print(f'Response Status Code: {response.status_code}')
print('Response JSON:')
print(response.json())
def test_refresh_token(refresh_token):
url = f"{BASE_URL}/refresh_token"
data = {'refresh_token': refresh_token}
response = requests.post(url, data=data)
if response.status_code == 200:
access_token = response.json().get('access_token')
print(f"Access token: {access_token}")
else:
print("Token refresh failed.")
def test_get_user_groups(access_token):
url = f"{BASE_URL}/user_groups"
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.post(url, headers=headers)
print(response.json())
def publish_hdag(descriptor_json, project_name, access_token):
url = f"{BASE_URL}/publish_hdag"
headers = {
'accept': 'text/plain',
'Content-Type': 'application/json',
'Authorization': f'Bearer {access_token}'
}
hdag_json = {'project_name' : project_name,'hdag_descriptor': descriptor_json}
response = requests.post(url, json=hdag_json, headers=headers)
if response.status_code == 200:
print("HDAG published successfully.")
print("Response:")
print(response.text)
else:
print(f"Error: {response.status_code} - {response.text}")
# Main function to test all endpoints
def test_endpoints():
# Register a new user
# register_user('testuser', 'testpassword', 'test@example.com')
project_name = 'brussels-demo'
artifact_type = 'HDAG' #'VO'
artifact_id = 'brussels-demo' # 'image-compression-vo' #
# Login as the registered user
access_token, refresh_token = login('testuser', 'testpassword')
# test_refresh_token(refresh_token)
# test_get_user_groups(access_token)
# create_project(project_name, access_token)
test_devices_endpoint(access_token)
test_clusters_endpoint(access_token)
# fetch_artifacts(access_token, project_name, artifact_type)
# fetch_artifacts_information (access_token, artifact_id, project_name, artifact_type)
# publish_hdag(hdag_descriptor, project_name, access_token)
print ("refresh token", refresh_token)
test_endpoints()
\ No newline at end of file
import json
import requests
# Flask login endpoint URL
login_url = 'http://localhost:5000/login'
# Request payload for login
login_data = {
'username': 'example_user',
'password': 'your_password'
}
# Make the login request
login_response = requests.post(login_url, json=login_data)
# Check if the login request was successful
if login_response.status_code == 200:
# Extract the access token from the JSON response
access_token = login_response.json().get('access_token')
# URL of the Flask application for creating project
create_project_url = 'http://localhost:5000/create_project'
# Project name provided by the user
project_name = "nephele_test" #input("Enter project name: ")
# Payload for the POST request to create project
create_project_payload = {
"name": project_name
}
# Headers for the POST request
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {access_token}' # Include access token in headers
}
# Make the POST request to create project
create_project_response = requests.post(create_project_url, json=create_project_payload, headers=headers)
print ("Status", create_project_response.status_code)
# Check the response for creating project
if create_project_response.status_code == 200:
print("Project created successfully!")
print("Response:", create_project_response.json())
elif create_project_response.status_code == 401:
print("User is not logged in. Please log in first.")
elif create_project_response.status_code == 400:
print("Bad request. Please provide a valid project name.")
else:
print("Failed to create project. Status code:", create_project_response.status_code)
print("Response:", create_project_response.text)
else:
print("Login failed")
\ No newline at end of file
import requests
# Flask login endpoint URL
login_url = 'http://localhost:5000/login'
# Request payload
data = {
'username': 'example_user',
'password': 'your_password',
'email' : 'example@example.com'
}
# Make the request
response = requests.post(login_url, json=data)
# Check if the request was successful
if response.status_code == 200:
# Extract the access token from the JSON response
access_token = response.json().get('access_token')
print("Access token:", access_token)
else:
print("Login failed")
\ No newline at end of file
import requests
# Registration endpoint URL
registration_url = 'http://localhost:5000/register'
# Request payload
data = {
"username": "example_user",
"email": "example@example.com",
"password": "your_password"
}
# Make the request
response = requests.post(registration_url, json=data)
# Check if the request was successful
if response.status_code == 200:
# Extract the access token from the JSON response
access_token = response.json().get('access_token')
print ("User is Registered")
print("Access token:", access_token)
else:
print('Registration failed')
\ No newline at end of file
import os
import json
from dotenv import load_dotenv
# Get the path of the directory where the Flask app is located
app_dir = os.path.abspath(os.path.dirname(__file__))
# Set the SQLite database path to the Flask app directory
SQLITE_DATABASE_PATH = os.path.join(app_dir, 'dashboard.db')
load_dotenv()
class Config:
FLASK_USERNAME = os.getenv('FLASK_USERNAME')
FLASK_PASSWORD = os.getenv('FLASK_PASSWORD')
with open('keycloak.json', 'r') as file:
keycloak_config = json.load(file)
KEYCLOAK_URL = keycloak_config['web']['keycloak_url']
REALM_NAME = keycloak_config['web']['realm']
CLIENT_ID = keycloak_config['web']['client_id']
CLIENT_SECRET = keycloak_config['web']['client_secret']
SECRET_KEY = keycloak_config['web'].get('app_secret_key', 'your_secret_key')
SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(SQLITE_DATABASE_PATH)
# SQLALCHEMY_DATABASE_URI = 'postgresql://{}:{}@{}:5432/{}'.format(
# os.getenv('DB_USER', 'root'),
# os.getenv('DB_PASSWORD', 'password'),
# os.getenv('DB_HOST', 'localhost'),
# os.getenv('DB_NAME', 'smo')
# )
class ProdConfig(Config):
FLASK_ENV = 'production'
DEBUG = False
class DevConfig(Config):
FLASK_ENV = 'development'
DEBUG = True
configs = {
'default': ProdConfig,
'production': ProdConfig,
'development': DevConfig,
}
dashboard_config=Config()
\ No newline at end of file
File added
"""Flask error handlers."""
from flask import jsonify
def handle_subprocess_error(e):
response = {
'error': e.description,
'message': e.message
}
return jsonify(response), e.code
def handle_yaml_read_error(e):
response = {
'error': e.description,
'message': e.message
}
return jsonify(response), e.code
"""Flask error classes."""
import subprocess
import yaml
class SubprocessError(subprocess.CalledProcessError):
code = 500
description = 'Subprocess error'
class YamlReadError(yaml.YAMLError):
code = 500
description = 'Yaml read error'
{
"web1": {
"keycloak_url": "https://keycloak-w:8443/",
"client_id": "dashboard",
"client_secret": "W9jnouJfxFsmcvq6Qk8LoqSIE7881O3J",
"realm": "nephele",
"auth_uri": "https://keycloak-w:8443/realms/nephele/protocol/openid-connect/auth",
"token_uri": "https://keycloak-w:8443/realms/nephele/openid-connect/token",
"issuer": "https://keycloak-w:8443/realms/nephele",
"userinfo_uri": "https://keycloak-w:8443/realms/nephele/protocol/openid-connect/userinfo",
"token_introspection_uri": "https://keycloak-w:8443/realms/nephele/protocol/openid-connect/token/introspect",
"redirect_uris": [
"http://localhost:5000/*"
]
},
"web": {
"keycloak_url": "https://nephele-dashboard.netmode.ntua.gr:443/",
"client_id": "dashboard",
"client_secret": "W9jnouJfxFsmcvq6Qk8LoqSIE7881O3J",
"realm": "nephele",
"auth_uri": "https://nephele-dashboard.netmode.ntua.gr:443/realms/nephele/protocol/openid-connect/auth",
"token_uri": "https://nephele-dashboard.netmode.ntua.gr:443/realms/nephele/openid-connect/token",
"issuer": "https://nephele-dashboard.netmode.ntua.gr:443/realms/nephele",
"userinfo_uri": "https://nephele-dashboard.netmode.ntua.gr:443/realms/nephele/protocol/openid-connect/userinfo",
"token_introspection_uri": "https://nephele-dashboard.netmode.ntua.gr:443/realms/nephele/protocol/openid-connect/token/introspect",
"redirect_uris": [
"http://localhost:5000/*"
]
}
}
\ No newline at end of file
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class NepheleCluster(db.Model):
id = db.Column(db.Integer, primary_key=True)
cluster_name = db.Column(db.String(100), nullable=False)
location = db.Column(db.String(100), nullable=False)
available_cpu = db.Column(db.String, nullable=False)
available_ram = db.Column(db.String, nullable=False)
availability = db.Column(db.Boolean, nullable=False)
grafana = db.Column(db.String, nullable=False)
class RegisteredIoTDevice(db.Model):
id = db.Column(db.Integer, primary_key=True)
device_type = db.Column(db.String(100), nullable=False)
ip = db.Column(db.String(100), nullable=False)
thing_descriptor = db.Column(db.JSON, nullable=False)
location = db.Column(db.String(100), nullable=False)
def update_cluster(cluster_id, data):
cluster = NepheleCluster.query.get(cluster_id)
if not cluster:
return False
cluster.cluster_name = data.get('cluster_name', cluster.cluster_name)
cluster.location = data.get('location', cluster.location)
cluster.available_ram = data.get('available_ram', cluster.available_ram)
cluster.available_cpu = data.get('available_cpu', cluster.available_cpu)
cluster.availability = data.get('availability', cluster.availability)
db.session.commit()
return True
def update_device(device_id, data):
device = RegisteredIoTDevice.query.get(device_id)
if not device:
return False
device.device_type = data.get('device_type', device.device_type)
device.ip = data.get('ip', device.ip)
device.thing_descriptor = data.get('thing_descriptor', device.thing_descriptor)
device.location = data.get('location', device.location)
db.session.commit()
return True
# Function to add initial data to tables
def add_initial_data():
# Add initial clusters
cluster1 = NepheleCluster(cluster_name='Netmode', location='NTUA', available_cpu="72 vCPUs", available_ram="234 GiB", availability=True, grafana="http://10.0.2.114:30150/d/dUMN5x0mk/first-cluster?orgId=1")
cluster2 = NepheleCluster(cluster_name='CNIT', location='Italy', available_cpu="50 vCPUs", available_ram="150 GiB", availability=True, grafana="http://10.0.2.114:30150/d/dUMN5x0mk1/second-cluster?orgId=1")
db.session.add_all([cluster1, cluster2])
# Add initial devices
device1 = RegisteredIoTDevice(device_type='Raspberry Pi', ip='147.102.13.100', thing_descriptor={
"title": "vo",
"id": "urn:dev:wot:plenary:vo",
"description": "Image detection VO.",
"securityDefinitions": {
"no_sc": {
"scheme": "nosec"
}
},
"security": "no_sc",
"@context": [
"https://www.w3.org/2022/wot/td/v1.1"
],
"actions": {
"detectImage": {
"type": "boolean"
}
}
# "title": "device1",
# "id": "urn:dev:wot:plenary:device1",
# "description": "'Lille Plenary Meeting Descriptor for Device 1 (with computing capabilities).'",
# "securityDefinitions": {
# "basic_sec": {
# "scheme": "basic"
# }
# },
# "security": "basic_sec",
# "@context": [
# "https://www.w3.org/2022/wot/td/v1.1"
# ],
# "properties": {
# "temperature": {
# "type": "integer"
# },
# "humidity": {
# "type": "integer"
# }
# },
# "actions": {
# "currentValues": {
# "description": "Returns the current values"
# }
# }
}, location='Netmode')
db.session.add_all([device1])
db.session.commit()
\ No newline at end of file
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
/dist
/src-capacitor
/src-cordova
/.quasar
/node_modules
.eslintrc.js
/src-ssr
/quasar.config.*.temporary.compiled*
module.exports = {
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
// https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
// Must use parserOptions instead of 'parser' to allow vue-eslint-parser to keep working
// `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
parserOptions: {
parser: require.resolve('@typescript-eslint/parser'),
extraFileExtensions: ['.vue'],
},
env: {
browser: true,
es2021: true,
node: true,
'vue/setup-compiler-macros': true,
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Uncomment any of the lines below to choose desired strictness,
// but leave only one uncommented!
// See https://eslint.vuejs.org/rules/#available-rules
//'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'prettier',
],
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
globals: {
ga: 'readonly', // Google Analytics
cordova: 'readonly',
__statics: 'readonly',
__QUASAR_SSR__: 'readonly',
__QUASAR_SSR_SERVER__: 'readonly',
__QUASAR_SSR_CLIENT__: 'readonly',
__QUASAR_SSR_PWA__: 'readonly',
process: 'readonly',
Capacitor: 'readonly',
chrome: 'readonly',
},
// add your custom rules here
rules: {
'prefer-promise-reject-errors': 'off',
eqeqeq: 'error',
strict: 'error',
'no-undef': 'error',
semi: 'error',
'max-len': [
'error',
{
code: 180,
ignoreComments: true,
ignoreTrailingComments: true,
},
],
// this rule, if on, would require explicit return type on the `render` function
'@typescript-eslint/explicit-function-return-type': 'off',
// in plain CommonJS modules, you can't use `import foo = require('foo')` to pass this rule, so it has to be disabled
'@typescript-eslint/no-var-requires': 'off',
// The core 'no-unused-vars' rules (in the eslint:recommended ruleset)
// does not work with type definitions
'no-unused-vars': 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
},
};
.DS_Store
.thumbs.db
node_modules
# Quasar core related directories
.quasar
/dist
/quasar.config.*.temporary.compiled*
# Cordova related directories and files
/src-cordova/node_modules
/src-cordova/platforms
/src-cordova/plugins
/src-cordova/www
# Capacitor related directories and files
/src-capacitor/www
/src-capacitor/node_modules
# BEX related directories and files
/src-bex/www
/src-bex/js/core
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
# local .env files
.env.local*
# pnpm-related options
shamefully-hoist=true
strict-peer-dependencies=false
{
"singleQuote": true,
"semi": true
}
# Nephele Repository (nephele-frontend)
Placeholder, for now
## Install the dependencies
```bash
yarn
```
### Start the app in development mode (hot-code reloading, error reporting, etc.)
```bash
quasar dev
```
### Lint the files
```bash
yarn lint
```
### Format the files
```bash
yarn format
```
### Build the app for production
```bash
quasar build
```
### Serve the build
```bash
quasar serve dist/spa --history
```
### Customize the configuration
See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js).
<!doctype html>
<html>
<head>
<title><%= productName %></title>
<meta charset="utf-8" />
<meta name="description" content="<%= productDescription %>" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta
name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
/>
<link
rel="icon"
type="image/png"
sizes="128x128"
href="icons/favicon-128x128.png"
/>
<link
rel="icon"
type="image/png"
sizes="96x96"
href="icons/favicon-96x96.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="icons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="icons/favicon-16x16.png"
/>
<link rel="icon" type="image/ico" href="favicon.ico" />
</head>
<body>
<!-- quasar:entry-point -->
</body>
</html>
This diff is collapsed.
{
"name": "nephele-frontend",
"version": "0.0.1",
"description": "Placeholder, for now",
"productName": "Nephele Repository",
"author": "Nikos Astrinakis <nikos.astrin@gmail.com>",
"private": true,
"scripts": {
"lint": "eslint --ext .js,.ts,.vue ./",
"format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test": "vitest --dom",
"dev": "quasar dev",
"build": "quasar build",
"test:unit:ui": "vitest --ui",
"test:unit": "vitest",
"test:unit:ci": "vitest run"
},
"dependencies": {
"@quasar/extras": "^1.16.9",
"axios": "^1.6.2",
"dotenv": "^16.3.1",
"js-yaml": "^4.1.0",
"pinia": "^2.1.7",
"quasar": "^2.14.1",
"v-network-graph": "^0.9.15",
"vue": "^3.3.9",
"vue-i18n": "^9.8.0",
"vue-query": "^1.26.0",
"vue-router": "^4.2.5",
"vuex": "^4.0.2"
},
"devDependencies": {
"@intlify/vite-plugin-vue-i18n": "^7.0.0",
"@quasar/app-vite": "^1.7.0",
"@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
"@types/node": "^20.10.1",
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/parser": "^6.13.1",
"@vue/test-utils": "^2.4.3",
"autoprefixer": "^10.4.16",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-vue": "^9.19.2",
"happy-dom": "^12.10.3",
"prettier": "^3.1.0",
"typescript": "^5.3.2",
"vitest": "^0.34.6"
},
"engines": {
"node": "^18 || ^16 || ^14.19",
"npm": ">= 6.13.4",
"yarn": ">= 1.21.1"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment