Skip to content

Commit

Permalink
Merge branch 'development' into 'master'
Browse files Browse the repository at this point in the history
Fix #44 which was causing error when the adh6 search for a user was returning different users. Now, the user account is selected by checking the exact username (instead of a research)

Add a job (in production only) able to stop VM of expired account

Introduce environment (PROD, DEV and TEST) to have different application behavior

Use of new replicated 2 times pool to use the new cluster

Fix #3. Admin can now transfer the ownership of a VM between user

Fix #46 which was causing an error and no deletion button when VM was in db but not in proxmox

Fix #45 which was causing the real creation of a vm during test. Mock function has been corrected

New tests have been implemented for each new feature
  • Loading branch information
SeaweedbrainCY committed Jan 21, 2023
2 parents 3114a5e + 4ef4f3f commit d4a192e
Show file tree
Hide file tree
Showing 21 changed files with 554 additions and 187 deletions.
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ test_backend:
- export no_proxy="192.168.104.7"
- apt update
- apt install sqlite3
- export ENVIRONMENT='DEV'
- export ENVIRONMENT='TEST'
- export KEYRING_DNS_SECRET=$KEYRING_DNS_SECRET
- export PROXMOX_API_KEY_NAME=$PROXMOX_API_KEY_NAME
- export PROXMOX_API_KEY=$PROXMOX_API_KEY
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ KEYRING_DNS_SECRET : clé pour utiliser le ddns (ajouter / supprimer des entrée
PROXMOX_API_KEY_NAME : nom de la clé pour accéder à l'api proxmox
PROXMOX_API_KEY : clé pour utiliser l'api proxmox
PROXMOX_BACK_DB : mysql:// lien vers la db contenant le passwd, user, nom de la database et bien sûr ip de celle-ci
ENVIRONMENT="DEV" ou "TEST" (ou "PROD")
```
L'environnement conditionne certains composants de l'application.
1. "PROD" est réservé à l'execution de l'application dans un environnement de production. C'est par exemple au sein de cet environment que les cron jobs s'executeront. Il est impératif que seul l'env de PROD soit en charge de ce genre d'opérations
2. "DEV" désactive certaines fonctionnalités réservées à la prod, comme les cron jobs. Mais il utilise la même pas de données la production. C'est l'environment à utiliser en local ou sur hosting-dev
3. "TEST" est l'environment utilisé pour effectuer les tests unitaires et d'intégrations du backend. Il déploie un base de donnée particulière réservée aux tests.

- vous ensuite devez vous rendre dans backend/ et exécuter la commande `python3 -m proxmox_api`. Le serveur se lance alors. *Assurez vous qu'il est joignable via le port 8080 de votre machine pour qu'il puisse être joint par le `frontend`*


Expand Down
33 changes: 15 additions & 18 deletions backend/proxmox_api/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@


print("config = ", config.ENV)
if config.ENV == "DEV":
if config.ENV == "TEST":
print("**************************************************")
print("**************************************************")
print("**************************************************")
print("************* ENTERING IN DEV MODE ***************")
print("************* ENTERING IN TEST MODE ***************")
print("********* NOT DESIGNED FOR PRODUCTION ************")
print("**************************************************")
print("**************************************************")
Expand All @@ -32,27 +32,24 @@ def create_app():


def conf_jobs(app):
app.app.config['JOBS'] = JOBS
app.app.config['SCHEDULER_API_ENABLE'] = False






## init db
app, scheduler = create_app()

#JOBS = [
# {
# "id": "update_vm_ips",
# "func": "proxmox_api.proxmox:update_vm_ips_job",
# "args": (app.app,),
# "trigger": "interval",
# "seconds": 120,
# }
# ]
#
#conf_jobs(app)
JOBS = [
{
"id": "stop_expired_vm",
"func": "proxmox_api.proxmox:stop_expired_vm",
"args": (app.app,),
"trigger": "interval",
'seconds': 86400,# 1 day
}
]

if config.ENV == "PROD":
conf_jobs(app)


db.init_app(app.app)
Expand Down
7 changes: 5 additions & 2 deletions backend/proxmox_api/config/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@
"""Be sure to set "set global log_bin_trust_function_creators=1"; in the database if mysql"""


if os.environ.get('ENVIRONMENT') == 'DEV':
ENV = "DEV"
if os.environ.get('ENVIRONMENT') == 'TEST':
ENV = "TEST"
#DATABASE_URI = os.environ.get('PROXMOX_BACK_DB_DEV')
DATABASE_URI = 'sqlite:///proxmox_dev.db'
elif os.environ.get('ENVIRONMENT') == 'DEV':
ENV = "DEV"
DATABASE_URI = os.environ.get('PROXMOX_BACK_DB')
else :
ENV = "PROD"
DATABASE_URI = os.environ.get('PROXMOX_BACK_DB')
Expand Down
2 changes: 1 addition & 1 deletion backend/proxmox_api/config/vm_creation_status.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{}
{"999": {"status": "creating"}, "999": {"status": "creating"}}
26 changes: 17 additions & 9 deletions backend/proxmox_api/controllers/default_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ def delete_vm_id(vmid): # noqa: E501
if freezeAccountState >= 3 and not admin: # if freeze state 1 or 2 user still have access to proxmox
return {"status": "cotisation expired"}, 403

node = proxmox.get_node_from_vm(vmid)
if not node : #doesn't exist
node,status = proxmox.get_node_from_vm(vmid)
if status != 200 : #doesn't exist
return {"error": "VM doesn't exist"}, 404

Thread(target=delete_vm_in_thread, args=(vmid, user_id, node,False,)).start()
Expand Down Expand Up @@ -251,8 +251,8 @@ def delete_vm_in_thread(vmid, user_id, node="", dueToError=False):
#if freezeAccountState >= 3 and not admin: # if freeze state 1 or 2 user still have access to proxmox
# return {"status": "cotisation expired"}, 403

node = proxmox.get_node_from_vm(vmid)
if not node:
node,status = proxmox.get_node_from_vm(vmid)
if status != 200:
return {"status": "vm not exists"}, 404
if vmid in map(int, proxmox.get_vm(user_id)[0]):
return proxmox.delete_vm(vmid, node)
Expand Down Expand Up @@ -420,12 +420,14 @@ def get_vm_id(vmid): # noqa: E501
return {"error": "Unknown vm status"}, 400


node = proxmox.get_node_from_vm(vmid)
node,status = proxmox.get_node_from_vm(vmid)


if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
return {'error' : "Forbidden"} , 403
elif node == None and not admin: # exist in the db but not in proxmox. It's a error
elif status != 200 and not admin: # exist in the db but not in proxmox. It's a error
return {"error": "VM not found in proxmox"}, 500
elif node == None and admin:
elif status != 200 and admin:
return {'error' : "VM no found"} , 404


Expand Down Expand Up @@ -722,8 +724,8 @@ def patch_vm(vmid, body=None): # noqa: E501
user_id = slugify(cas['sub'].replace('_', '-'))

if admin or dbfct.get_vm_userid(vmid) == user_id : # if not admin, we check if the user is the owner of the vm
node = proxmox.get_node_from_vm(vmid)
if not node:
node,status = proxmox.get_node_from_vm(vmid)
if status != 200:
return {"status": "vm not exists"}, 404
if requetsBody.status == "start":
return proxmox.start_vm(vmid, node)
Expand All @@ -733,6 +735,12 @@ def patch_vm(vmid, body=None): # noqa: E501
return proxmox.stop_vm(vmid, node)
elif requetsBody.status == "switch_autoreboot":
return proxmox.switch_autoreboot(vmid, node)
elif requetsBody.status == "transfering_ownership":
if admin :
new_owner = slugify(requetsBody.user.replace('_', '-'))
return proxmox.transfer_ownership(vmid, new_owner)
else:
return {"status": "Permission denied"}, 403
else:
return {"status": "uknown status"}, 500
else:
Expand Down
16 changes: 16 additions & 0 deletions backend/proxmox_api/db/db_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ def get_user_list(user_id=None, searchItem = None): # filter is for the user nam
else :
return User.query.all()

def update_vm_userid(vmid, userid):
vm = Vm.query.filter_by(id=vmid).first()
vm.userId = userid
db.session.commit()

# Return all the VM of an user
def get_vm_list(user_id=""):
if user_id != "": # dans ce cas on affiche ce qui est lié à l'user
Expand Down Expand Up @@ -217,4 +222,15 @@ def setNeedToBeRestored(vmid, needToBeRestored):
vm.needToBeRestored = needToBeRestored
db.session.commit()


# Return expired users with a freezeState >= minimumFreezeState
def get_expired_users(minimumFreezeState = 1):
list = []
for user in User.query.all():
if user.freezeState !=None:
state = user.freezeState.split(".")[0]
if int(state) >= minimumFreezeState:
list.append(user.id)
return list

#######
2 changes: 1 addition & 1 deletion backend/proxmox_api/db/db_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class History(db.Model):
date = db.Column(db.TIMESTAMP,default=db.func.current_timestamp(), nullable=False)


if ENV != "DEV":
if ENV != "TEST":
### Trigger for ip tracking
TRIGGER_CREATION = """
CREATE TRIGGER history_insert_vm AFTER UPDATE ON vm
Expand Down
Loading

0 comments on commit d4a192e

Please sign in to comment.