Skip to content

Commit d4a192e

Browse files
Merge branch 'development' into 'master'
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
2 parents 3114a5e + 4ef4f3f commit d4a192e

21 files changed

+554
-187
lines changed

.gitlab-ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ test_backend:
5555
- export no_proxy="192.168.104.7"
5656
- apt update
5757
- apt install sqlite3
58-
- export ENVIRONMENT='DEV'
58+
- export ENVIRONMENT='TEST'
5959
- export KEYRING_DNS_SECRET=$KEYRING_DNS_SECRET
6060
- export PROXMOX_API_KEY_NAME=$PROXMOX_API_KEY_NAME
6161
- export PROXMOX_API_KEY=$PROXMOX_API_KEY

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ KEYRING_DNS_SECRET : clé pour utiliser le ddns (ajouter / supprimer des entrée
1515
PROXMOX_API_KEY_NAME : nom de la clé pour accéder à l'api proxmox
1616
PROXMOX_API_KEY : clé pour utiliser l'api proxmox
1717
PROXMOX_BACK_DB : mysql:// lien vers la db contenant le passwd, user, nom de la database et bien sûr ip de celle-ci
18+
ENVIRONMENT="DEV" ou "TEST" (ou "PROD")
1819
```
20+
L'environnement conditionne certains composants de l'application.
21+
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
22+
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
23+
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.
24+
1925
- 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`*
2026

2127

backend/proxmox_api/__main__.py

+15-18
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88

99

1010
print("config = ", config.ENV)
11-
if config.ENV == "DEV":
11+
if config.ENV == "TEST":
1212
print("**************************************************")
1313
print("**************************************************")
1414
print("**************************************************")
15-
print("************* ENTERING IN DEV MODE ***************")
15+
print("************* ENTERING IN TEST MODE ***************")
1616
print("********* NOT DESIGNED FOR PRODUCTION ************")
1717
print("**************************************************")
1818
print("**************************************************")
@@ -32,27 +32,24 @@ def create_app():
3232

3333

3434
def conf_jobs(app):
35+
app.app.config['JOBS'] = JOBS
3536
app.app.config['SCHEDULER_API_ENABLE'] = False
3637

37-
38-
39-
40-
41-
4238
## init db
4339
app, scheduler = create_app()
4440

45-
#JOBS = [
46-
# {
47-
# "id": "update_vm_ips",
48-
# "func": "proxmox_api.proxmox:update_vm_ips_job",
49-
# "args": (app.app,),
50-
# "trigger": "interval",
51-
# "seconds": 120,
52-
# }
53-
# ]
54-
#
55-
#conf_jobs(app)
41+
JOBS = [
42+
{
43+
"id": "stop_expired_vm",
44+
"func": "proxmox_api.proxmox:stop_expired_vm",
45+
"args": (app.app,),
46+
"trigger": "interval",
47+
'seconds': 86400,# 1 day
48+
}
49+
]
50+
51+
if config.ENV == "PROD":
52+
conf_jobs(app)
5653

5754

5855
db.init_app(app.app)

backend/proxmox_api/config/configuration.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@
3131
"""Be sure to set "set global log_bin_trust_function_creators=1"; in the database if mysql"""
3232

3333

34-
if os.environ.get('ENVIRONMENT') == 'DEV':
35-
ENV = "DEV"
34+
if os.environ.get('ENVIRONMENT') == 'TEST':
35+
ENV = "TEST"
3636
#DATABASE_URI = os.environ.get('PROXMOX_BACK_DB_DEV')
3737
DATABASE_URI = 'sqlite:///proxmox_dev.db'
38+
elif os.environ.get('ENVIRONMENT') == 'DEV':
39+
ENV = "DEV"
40+
DATABASE_URI = os.environ.get('PROXMOX_BACK_DB')
3841
else :
3942
ENV = "PROD"
4043
DATABASE_URI = os.environ.get('PROXMOX_BACK_DB')
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{}
1+
{"999": {"status": "creating"}, "999": {"status": "creating"}}

backend/proxmox_api/controllers/default_controller.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ def delete_vm_id(vmid): # noqa: E501
204204
if freezeAccountState >= 3 and not admin: # if freeze state 1 or 2 user still have access to proxmox
205205
return {"status": "cotisation expired"}, 403
206206

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

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

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

422422

423-
node = proxmox.get_node_from_vm(vmid)
423+
node,status = proxmox.get_node_from_vm(vmid)
424+
425+
424426
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
425427
return {'error' : "Forbidden"} , 403
426-
elif node == None and not admin: # exist in the db but not in proxmox. It's a error
428+
elif status != 200 and not admin: # exist in the db but not in proxmox. It's a error
427429
return {"error": "VM not found in proxmox"}, 500
428-
elif node == None and admin:
430+
elif status != 200 and admin:
429431
return {'error' : "VM no found"} , 404
430432

431433

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

724726
if admin or dbfct.get_vm_userid(vmid) == user_id : # if not admin, we check if the user is the owner of the vm
725-
node = proxmox.get_node_from_vm(vmid)
726-
if not node:
727+
node,status = proxmox.get_node_from_vm(vmid)
728+
if status != 200:
727729
return {"status": "vm not exists"}, 404
728730
if requetsBody.status == "start":
729731
return proxmox.start_vm(vmid, node)
@@ -733,6 +735,12 @@ def patch_vm(vmid, body=None): # noqa: E501
733735
return proxmox.stop_vm(vmid, node)
734736
elif requetsBody.status == "switch_autoreboot":
735737
return proxmox.switch_autoreboot(vmid, node)
738+
elif requetsBody.status == "transfering_ownership":
739+
if admin :
740+
new_owner = slugify(requetsBody.user.replace('_', '-'))
741+
return proxmox.transfer_ownership(vmid, new_owner)
742+
else:
743+
return {"status": "Permission denied"}, 403
736744
else:
737745
return {"status": "uknown status"}, 500
738746
else:

backend/proxmox_api/db/db_functions.py

+16
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ def get_user_list(user_id=None, searchItem = None): # filter is for the user nam
4242
else :
4343
return User.query.all()
4444

45+
def update_vm_userid(vmid, userid):
46+
vm = Vm.query.filter_by(id=vmid).first()
47+
vm.userId = userid
48+
db.session.commit()
49+
4550
# Return all the VM of an user
4651
def get_vm_list(user_id=""):
4752
if user_id != "": # dans ce cas on affiche ce qui est lié à l'user
@@ -217,4 +222,15 @@ def setNeedToBeRestored(vmid, needToBeRestored):
217222
vm.needToBeRestored = needToBeRestored
218223
db.session.commit()
219224

225+
226+
# Return expired users with a freezeState >= minimumFreezeState
227+
def get_expired_users(minimumFreezeState = 1):
228+
list = []
229+
for user in User.query.all():
230+
if user.freezeState !=None:
231+
state = user.freezeState.split(".")[0]
232+
if int(state) >= minimumFreezeState:
233+
list.append(user.id)
234+
return list
235+
220236
#######

backend/proxmox_api/db/db_models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class History(db.Model):
3838
date = db.Column(db.TIMESTAMP,default=db.func.current_timestamp(), nullable=False)
3939

4040

41-
if ENV != "DEV":
41+
if ENV != "TEST":
4242
### Trigger for ip tracking
4343
TRIGGER_CREATION = """
4444
CREATE TRIGGER history_insert_vm AFTER UPDATE ON vm

0 commit comments

Comments
 (0)