rpyc-pve-cloud 0.2.0rc0__py3-none-any.whl → 0.2.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pve_cloud_rpc/_version.py +1 -1
- pve_cloud_rpc/server.py +55 -35
- {rpyc_pve_cloud-0.2.0rc0.dist-info → rpyc_pve_cloud-0.2.0rc1.dist-info}/METADATA +2 -2
- rpyc_pve_cloud-0.2.0rc1.dist-info/RECORD +12 -0
- rpyc_pve_cloud-0.2.0rc0.dist-info/RECORD +0 -12
- {rpyc_pve_cloud-0.2.0rc0.dist-info → rpyc_pve_cloud-0.2.0rc1.dist-info}/WHEEL +0 -0
- {rpyc_pve_cloud-0.2.0rc0.dist-info → rpyc_pve_cloud-0.2.0rc1.dist-info}/entry_points.txt +0 -0
- {rpyc_pve_cloud-0.2.0rc0.dist-info → rpyc_pve_cloud-0.2.0rc1.dist-info}/licenses/LICENSE.md +0 -0
- {rpyc_pve_cloud-0.2.0rc0.dist-info → rpyc_pve_cloud-0.2.0rc1.dist-info}/top_level.txt +0 -0
pve_cloud_rpc/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.2.0-
|
|
1
|
+
__version__ = "0.2.0-rc1"
|
pve_cloud_rpc/server.py
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import json
|
|
2
3
|
import socket
|
|
3
4
|
import sys
|
|
4
|
-
import json
|
|
5
5
|
|
|
6
6
|
import asyncssh
|
|
7
7
|
import grpc
|
|
8
8
|
import yaml
|
|
9
9
|
from pve_cloud.cli.pvclu import get_cluster_vars, get_ssh_master_kubeconfig
|
|
10
10
|
from pve_cloud.lib.inventory import *
|
|
11
|
+
from pve_cloud.orm.alchemy import ProxmoxCloudSecrets, VirtualMachineVars
|
|
12
|
+
from sqlalchemy import create_engine, delete, select
|
|
13
|
+
from sqlalchemy.exc import IntegrityError
|
|
14
|
+
from sqlalchemy.orm import Session
|
|
11
15
|
|
|
12
16
|
import pve_cloud_rpc.protos.cloud_pb2 as cloud_pb2
|
|
13
17
|
import pve_cloud_rpc.protos.cloud_pb2_grpc as cloud_pb2_grpc
|
|
14
18
|
import pve_cloud_rpc.protos.health_pb2 as health_pb2
|
|
15
19
|
import pve_cloud_rpc.protos.health_pb2_grpc as health_pb2_grpc
|
|
16
|
-
from pve_cloud.orm.alchemy import ProxmoxCloudSecrets, VirtualMachineVars
|
|
17
|
-
from sqlalchemy import create_engine, select, delete
|
|
18
|
-
from sqlalchemy.orm import Session
|
|
19
|
-
from sqlalchemy.exc import IntegrityError
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class HealthServicer(health_pb2_grpc.HealthServicer):
|
|
@@ -43,15 +43,11 @@ async def get_engine(online_pve_host):
|
|
|
43
43
|
async with asyncssh.connect(
|
|
44
44
|
online_pve_host, username="root", known_hosts=None
|
|
45
45
|
) as conn:
|
|
46
|
-
cmd = await conn.run(
|
|
47
|
-
"cat /etc/pve/cloud/secrets/patroni.pass", check=True
|
|
48
|
-
)
|
|
46
|
+
cmd = await conn.run("cat /etc/pve/cloud/secrets/patroni.pass", check=True)
|
|
49
47
|
patroni_pass = cmd.stdout.rstrip()
|
|
50
48
|
|
|
51
49
|
# fetch cluster vars to get internal proxy ip
|
|
52
|
-
cmd = await conn.run(
|
|
53
|
-
"cat /etc/pve/cloud/cluster_vars.yaml", check=True
|
|
54
|
-
)
|
|
50
|
+
cmd = await conn.run("cat /etc/pve/cloud/cluster_vars.yaml", check=True)
|
|
55
51
|
cluster_vars = yaml.safe_load(cmd.stdout)
|
|
56
52
|
|
|
57
53
|
# build the connection string
|
|
@@ -106,7 +102,6 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
106
102
|
|
|
107
103
|
return cloud_pb2.GetCloudFileSecretResponse(secret=catted_secret)
|
|
108
104
|
|
|
109
|
-
|
|
110
105
|
# non file proxmox cloud secrets are stored in the patroni database
|
|
111
106
|
async def CreateCloudSecret(self, request, context):
|
|
112
107
|
target_pve = request.target_pve
|
|
@@ -119,21 +114,24 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
119
114
|
|
|
120
115
|
with Session(engine) as session:
|
|
121
116
|
try:
|
|
122
|
-
session.add(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
session.add(
|
|
118
|
+
ProxmoxCloudSecrets(
|
|
119
|
+
target_pve=target_pve,
|
|
120
|
+
secret_name=secret_name,
|
|
121
|
+
secret_data=secret_data,
|
|
122
|
+
secret_type=secret_type,
|
|
123
|
+
)
|
|
124
|
+
)
|
|
128
125
|
session.commit()
|
|
129
|
-
|
|
126
|
+
|
|
130
127
|
except IntegrityError as e:
|
|
131
128
|
session.rollback()
|
|
132
|
-
return cloud_pb2.CreateCloudSecretResponse(
|
|
129
|
+
return cloud_pb2.CreateCloudSecretResponse(
|
|
130
|
+
success=False, err_message=str(e)
|
|
131
|
+
)
|
|
133
132
|
|
|
134
133
|
return cloud_pb2.CreateCloudSecretResponse(success=True)
|
|
135
134
|
|
|
136
|
-
|
|
137
135
|
async def DeleteCloudSecret(self, request, context):
|
|
138
136
|
target_pve = request.target_pve
|
|
139
137
|
secret_name = request.secret_name
|
|
@@ -144,15 +142,14 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
144
142
|
with Session(engine) as session:
|
|
145
143
|
stmt = delete(ProxmoxCloudSecrets).where(
|
|
146
144
|
ProxmoxCloudSecrets.target_pve == target_pve,
|
|
147
|
-
ProxmoxCloudSecrets.secret_name == secret_name
|
|
145
|
+
ProxmoxCloudSecrets.secret_name == secret_name,
|
|
148
146
|
)
|
|
149
|
-
|
|
147
|
+
|
|
150
148
|
result = session.execute(stmt)
|
|
151
149
|
session.commit()
|
|
152
150
|
|
|
153
151
|
return cloud_pb2.DeleteCloudSecretResponse(success=True)
|
|
154
152
|
|
|
155
|
-
|
|
156
153
|
async def GetCloudSecret(self, request, context):
|
|
157
154
|
target_pve = request.target_pve
|
|
158
155
|
secret_name = request.secret_name
|
|
@@ -161,7 +158,10 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
161
158
|
engine = await get_engine(online_pve_host)
|
|
162
159
|
|
|
163
160
|
with Session(engine) as session:
|
|
164
|
-
stmt = select(ProxmoxCloudSecrets).where(
|
|
161
|
+
stmt = select(ProxmoxCloudSecrets).where(
|
|
162
|
+
ProxmoxCloudSecrets.target_pve == target_pve
|
|
163
|
+
and ProxmoxCloudSecrets.secret_name == secret_name
|
|
164
|
+
)
|
|
165
165
|
record = session.scalars(stmt).first()
|
|
166
166
|
|
|
167
167
|
return cloud_pb2.GetCloudSecretResponse(secret=json.dumps(record.secret_data))
|
|
@@ -175,11 +175,17 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
175
175
|
engine = await get_engine(online_pve_host)
|
|
176
176
|
|
|
177
177
|
with Session(engine) as session:
|
|
178
|
-
stmt = select(ProxmoxCloudSecrets).where(
|
|
178
|
+
stmt = select(ProxmoxCloudSecrets).where(
|
|
179
|
+
ProxmoxCloudSecrets.target_pve == target_pve,
|
|
180
|
+
ProxmoxCloudSecrets.secret_type == secret_type,
|
|
181
|
+
)
|
|
179
182
|
records = session.scalars(stmt).all()
|
|
180
183
|
|
|
181
|
-
return cloud_pb2.GetCloudSecretsResponse(
|
|
182
|
-
|
|
184
|
+
return cloud_pb2.GetCloudSecretsResponse(
|
|
185
|
+
secrets=json.dumps(
|
|
186
|
+
{record.secret_name: record.secret_data for record in records}
|
|
187
|
+
)
|
|
188
|
+
)
|
|
183
189
|
|
|
184
190
|
async def GetVmVarsBlake(self, request, context):
|
|
185
191
|
blake_ids = request.blake_ids
|
|
@@ -189,11 +195,16 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
189
195
|
engine = await get_engine(online_pve_host)
|
|
190
196
|
|
|
191
197
|
with Session(engine) as session:
|
|
192
|
-
stmt = select(VirtualMachineVars).where(
|
|
198
|
+
stmt = select(VirtualMachineVars).where(
|
|
199
|
+
VirtualMachineVars.blake_id.in_(blake_ids)
|
|
200
|
+
)
|
|
193
201
|
records = session.scalars(stmt).all()
|
|
194
202
|
|
|
195
|
-
return cloud_pb2.GetVmVarsBlakeResponse(
|
|
196
|
-
|
|
203
|
+
return cloud_pb2.GetVmVarsBlakeResponse(
|
|
204
|
+
blake_id_vars={
|
|
205
|
+
entry.blake_id: json.dumps(entry.vm_vars) for entry in records
|
|
206
|
+
}
|
|
207
|
+
)
|
|
197
208
|
|
|
198
209
|
async def GetCephAccess(self, request, context):
|
|
199
210
|
target_pve = request.target_pve
|
|
@@ -242,7 +253,9 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
242
253
|
) as conn:
|
|
243
254
|
args_string = None
|
|
244
255
|
if request.get_args:
|
|
245
|
-
args_string = " ".join(
|
|
256
|
+
args_string = " ".join(
|
|
257
|
+
f"{k} '{v}'" for k, v in request.get_args.items()
|
|
258
|
+
)
|
|
246
259
|
|
|
247
260
|
cmd = await conn.run(
|
|
248
261
|
f"pvesh get {request.api_path} {args_string} --output-format json",
|
|
@@ -261,7 +274,9 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
261
274
|
) as conn:
|
|
262
275
|
args_string = None
|
|
263
276
|
if request.create_args:
|
|
264
|
-
args_string = " ".join(
|
|
277
|
+
args_string = " ".join(
|
|
278
|
+
f"{k} '{v}'" for k, v in request.create_args.items()
|
|
279
|
+
)
|
|
265
280
|
try:
|
|
266
281
|
print(f"pvesh create {request.api_path} {args_string}")
|
|
267
282
|
cmd = await conn.run(
|
|
@@ -270,7 +285,9 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
270
285
|
)
|
|
271
286
|
print(cmd.stdout)
|
|
272
287
|
except asyncssh.ProcessError as e:
|
|
273
|
-
return cloud_pb2.CreateProxmoxApiResponse(
|
|
288
|
+
return cloud_pb2.CreateProxmoxApiResponse(
|
|
289
|
+
success=False, err_message=f"Exit code {e.exit_status} - {e.stderr}"
|
|
290
|
+
)
|
|
274
291
|
|
|
275
292
|
return cloud_pb2.CreateProxmoxApiResponse(success=True)
|
|
276
293
|
|
|
@@ -288,7 +305,9 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
288
305
|
)
|
|
289
306
|
print(cmd.stdout)
|
|
290
307
|
except asyncssh.ProcessError as e:
|
|
291
|
-
return cloud_pb2.DeleteProxmoxApiResponse(
|
|
308
|
+
return cloud_pb2.DeleteProxmoxApiResponse(
|
|
309
|
+
success=False, err_message=f"Exit code {e.exit_status} - {e.stderr}"
|
|
310
|
+
)
|
|
292
311
|
|
|
293
312
|
return cloud_pb2.DeleteProxmoxApiResponse(success=True)
|
|
294
313
|
|
|
@@ -308,6 +327,7 @@ class CloudServiceServicer(cloud_pb2_grpc.CloudServiceServicer):
|
|
|
308
327
|
inventory=yaml.safe_dump(pve_inventory), cloud_domain=cloud_domain
|
|
309
328
|
)
|
|
310
329
|
|
|
330
|
+
|
|
311
331
|
def is_port_bound(port, host="0.0.0.0"):
|
|
312
332
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
313
333
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rpyc-pve-cloud
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.0rc1
|
|
4
4
|
Author-email: Tobias Huebner <tobias.huebner@vmzberlin.com>
|
|
5
5
|
License-Expression: GPL-3.0-or-later
|
|
6
6
|
License-File: LICENSE.md
|
|
7
|
-
Requires-Dist: py-pve-cloud==0.15.
|
|
7
|
+
Requires-Dist: py-pve-cloud==0.15.0rc1
|
|
8
8
|
Requires-Dist: grpcio==1.76.0
|
|
9
9
|
Requires-Dist: asyncssh==2.22.0
|
|
10
10
|
Requires-Dist: protobuf==6.33.4
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
pve_cloud_rpc/_version.py,sha256=4B6W4wFobVYBGfy-G_6ZpAcAFt9qJZfdNmpeTpnSLDM,26
|
|
2
|
+
pve_cloud_rpc/server.py,sha256=L7gJouzFHOd22yJeBtFoaN1zUkxKfe9Qe00CmMOrPuk,13577
|
|
3
|
+
pve_cloud_rpc/protos/cloud_pb2.py,sha256=2FFa9SSpkdSD1ie_NiAGFGjz92yx028DhEALJazCIdE,11237
|
|
4
|
+
pve_cloud_rpc/protos/cloud_pb2_grpc.py,sha256=V-q4n-dI0nstsuHZLbNyaxk4-3jU8aTWqbeFR8p5SDk,27826
|
|
5
|
+
pve_cloud_rpc/protos/health_pb2.py,sha256=532OgHM0bPu6uyJNyYETlRJp9BzcCZ53fnrRtEu7bnA,2188
|
|
6
|
+
pve_cloud_rpc/protos/health_pb2_grpc.py,sha256=XXT8lsH8YgKLqn07YfigSQ6TNW6s-P4V6S-X69fLfh0,3368
|
|
7
|
+
rpyc_pve_cloud-0.2.0rc1.dist-info/licenses/LICENSE.md,sha256=ADUqsZhl4juwq34PRTMiBqumpm11s_PMli_dZQjWPqQ,34260
|
|
8
|
+
rpyc_pve_cloud-0.2.0rc1.dist-info/METADATA,sha256=FXjGvqqwx9_xxzl4WFY0ULNVsLnyiz40OdPiHDuRv7I,338
|
|
9
|
+
rpyc_pve_cloud-0.2.0rc1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
10
|
+
rpyc_pve_cloud-0.2.0rc1.dist-info/entry_points.txt,sha256=h4ytTryc_8IlySP_ICyy6srHzF71qrQ0noUhqI-3aGw,52
|
|
11
|
+
rpyc_pve_cloud-0.2.0rc1.dist-info/top_level.txt,sha256=CTGM4RRp33khtroUiv-RiYXI4h6W6AaQQGIvsbwAetM,14
|
|
12
|
+
rpyc_pve_cloud-0.2.0rc1.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
pve_cloud_rpc/_version.py,sha256=W0Nz2M74b-kThgrTvkhrB8zIno6lQEZG0KXlqDMEO3k,26
|
|
2
|
-
pve_cloud_rpc/server.py,sha256=5aqTe7nyoBS5TIIFh2HAm1I3s8p7Zjr4VH7xBZrcaSQ,13183
|
|
3
|
-
pve_cloud_rpc/protos/cloud_pb2.py,sha256=2FFa9SSpkdSD1ie_NiAGFGjz92yx028DhEALJazCIdE,11237
|
|
4
|
-
pve_cloud_rpc/protos/cloud_pb2_grpc.py,sha256=V-q4n-dI0nstsuHZLbNyaxk4-3jU8aTWqbeFR8p5SDk,27826
|
|
5
|
-
pve_cloud_rpc/protos/health_pb2.py,sha256=532OgHM0bPu6uyJNyYETlRJp9BzcCZ53fnrRtEu7bnA,2188
|
|
6
|
-
pve_cloud_rpc/protos/health_pb2_grpc.py,sha256=XXT8lsH8YgKLqn07YfigSQ6TNW6s-P4V6S-X69fLfh0,3368
|
|
7
|
-
rpyc_pve_cloud-0.2.0rc0.dist-info/licenses/LICENSE.md,sha256=ADUqsZhl4juwq34PRTMiBqumpm11s_PMli_dZQjWPqQ,34260
|
|
8
|
-
rpyc_pve_cloud-0.2.0rc0.dist-info/METADATA,sha256=GR-y-u1pxB_Gdekwwy9mnW1ZpVU8l5_bExDtbU_is4I,338
|
|
9
|
-
rpyc_pve_cloud-0.2.0rc0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
10
|
-
rpyc_pve_cloud-0.2.0rc0.dist-info/entry_points.txt,sha256=h4ytTryc_8IlySP_ICyy6srHzF71qrQ0noUhqI-3aGw,52
|
|
11
|
-
rpyc_pve_cloud-0.2.0rc0.dist-info/top_level.txt,sha256=CTGM4RRp33khtroUiv-RiYXI4h6W6AaQQGIvsbwAetM,14
|
|
12
|
-
rpyc_pve_cloud-0.2.0rc0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|