calagoapi 1.0.dev1__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.
- calagoapi/__init__.py +190 -0
- calagoapi/account/__init__.py +14 -0
- calagoapi/account/account.py +292 -0
- calagoapi/account/auth.py +72 -0
- calagoapi/account/models.py +221 -0
- calagoapi/admin/__init__.py +48 -0
- calagoapi/admin/admin.py +341 -0
- calagoapi/admin/managers.py +490 -0
- calagoapi/admin/resources.py +970 -0
- calagoapi/aio/__init__.py +9 -0
- calagoapi/aio/console.py +289 -0
- calagoapi/aio/panel.py +176 -0
- calagoapi/api/__init__.py +63 -0
- calagoapi/api/account.py +195 -0
- calagoapi/api/admin.py +402 -0
- calagoapi/api/attachments.py +27 -0
- calagoapi/api/auth.py +52 -0
- calagoapi/api/backups.py +99 -0
- calagoapi/api/client.py +198 -0
- calagoapi/api/databases.py +217 -0
- calagoapi/api/files.py +210 -0
- calagoapi/api/network.py +84 -0
- calagoapi/api/public.py +13 -0
- calagoapi/api/schedules.py +79 -0
- calagoapi/api/servers.py +114 -0
- calagoapi/api/users.py +27 -0
- calagoapi/api/versions.py +29 -0
- calagoapi/backups/__init__.py +8 -0
- calagoapi/backups/backup.py +292 -0
- calagoapi/backups/manager.py +177 -0
- calagoapi/console/__init__.py +6 -0
- calagoapi/console/console.py +392 -0
- calagoapi/databases/__init__.py +12 -0
- calagoapi/databases/database.py +445 -0
- calagoapi/databases/explorer.py +159 -0
- calagoapi/databases/manager.py +122 -0
- calagoapi/files/__init__.py +9 -0
- calagoapi/files/file.py +196 -0
- calagoapi/files/manager.py +437 -0
- calagoapi/network/__init__.py +8 -0
- calagoapi/network/allocation.py +99 -0
- calagoapi/network/manager.py +132 -0
- calagoapi/nodes/__init__.py +6 -0
- calagoapi/nodes/node.py +477 -0
- calagoapi/panel.py +162 -0
- calagoapi/schedules/__init__.py +14 -0
- calagoapi/schedules/builders.py +461 -0
- calagoapi/schedules/manager.py +107 -0
- calagoapi/schedules/schedule.py +214 -0
- calagoapi/servers/__init__.py +13 -0
- calagoapi/servers/admin.py +430 -0
- calagoapi/servers/generic.py +785 -0
- calagoapi/servers/manager.py +167 -0
- calagoapi/servers/minecraft.py +207 -0
- calagoapi/tunnels/__init__.py +5 -0
- calagoapi/tunnels/tunnel.py +112 -0
- calagoapi/users/__init__.py +11 -0
- calagoapi/users/activity.py +45 -0
- calagoapi/users/subuser.py +127 -0
- calagoapi/users/user.py +267 -0
- calagoapi/utils/__init__.py +43 -0
- calagoapi/utils/convert.py +113 -0
- calagoapi/utils/exceptions.py +72 -0
- calagoapi/utils/model.py +142 -0
- calagoapi/utils/resource.py +100 -0
- calagoapi/utils/time.py +68 -0
- calagoapi-1.0.dev1.dist-info/METADATA +266 -0
- calagoapi-1.0.dev1.dist-info/RECORD +71 -0
- calagoapi-1.0.dev1.dist-info/WHEEL +5 -0
- calagoapi-1.0.dev1.dist-info/licenses/LICENSE +674 -0
- calagoapi-1.0.dev1.dist-info/top_level.txt +1 -0
calagoapi/api/account.py
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
from calagoapi.api.client import segment
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Internal Calagopus AccountAPI
|
|
5
|
+
class AccountAPI:
|
|
6
|
+
def __init__(self, client):
|
|
7
|
+
self.client = client
|
|
8
|
+
|
|
9
|
+
def _path(self, suffix=''):
|
|
10
|
+
return f'/api/client/account{suffix}'
|
|
11
|
+
|
|
12
|
+
# profile
|
|
13
|
+
def get(self):
|
|
14
|
+
return self.client.get(self._path())['user']
|
|
15
|
+
|
|
16
|
+
def update(self, username=None, name_first=None, name_last=None, language=None):
|
|
17
|
+
return self.client.patch(self._path(), json={
|
|
18
|
+
'username': username,
|
|
19
|
+
'name_first': name_first,
|
|
20
|
+
'name_last': name_last,
|
|
21
|
+
'language': language,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
def permissions(self):
|
|
25
|
+
return self.client.get('/api/client/permissions')
|
|
26
|
+
|
|
27
|
+
def activity(self, search=None, page=None, per_page=None):
|
|
28
|
+
return self.client.list(self._path('/activity'), 'activities', {'search': search}, page, per_page)
|
|
29
|
+
|
|
30
|
+
def settings(self):
|
|
31
|
+
return self.client.get(self._path('/settings'))['settings']
|
|
32
|
+
|
|
33
|
+
def updateSettings(self, settings):
|
|
34
|
+
return self.client.patch(self._path('/settings'), json={'settings': settings})
|
|
35
|
+
|
|
36
|
+
def setAvatar(self, content, content_type='image/png'):
|
|
37
|
+
return self.client.request(
|
|
38
|
+
'PUT', self._path('/avatar'), data=content, headers={'Content-Type': content_type}
|
|
39
|
+
)['avatar']
|
|
40
|
+
|
|
41
|
+
def deleteAvatar(self):
|
|
42
|
+
return self.client.delete(self._path('/avatar'))
|
|
43
|
+
|
|
44
|
+
def logout(self):
|
|
45
|
+
return self.client.post(self._path('/logout'))
|
|
46
|
+
|
|
47
|
+
# email and password
|
|
48
|
+
def changeEmail(self, email, password):
|
|
49
|
+
return self.client.put(self._path('/email'), json={'email': email, 'password': password})
|
|
50
|
+
|
|
51
|
+
def resendVerification(self):
|
|
52
|
+
return self.client.post(self._path('/email/resend-verification'))
|
|
53
|
+
|
|
54
|
+
def changePassword(self, password, new_password):
|
|
55
|
+
return self.client.put(self._path('/password'), json={'password': password, 'new_password': new_password})
|
|
56
|
+
|
|
57
|
+
def setPasswordLogin(self, disabled, password):
|
|
58
|
+
return self.client.put(self._path('/password-login'), json={'disabled': disabled, 'password': password})
|
|
59
|
+
|
|
60
|
+
# two factor
|
|
61
|
+
def twoFactorSetup(self):
|
|
62
|
+
return self.client.get(self._path('/two-factor'))
|
|
63
|
+
|
|
64
|
+
def enableTwoFactor(self, code, password):
|
|
65
|
+
return self.client.post(self._path('/two-factor'), json={'code': code, 'password': password})['recovery_codes']
|
|
66
|
+
|
|
67
|
+
def disableTwoFactor(self, code, password):
|
|
68
|
+
return self.client.delete(self._path('/two-factor'), json={'code': code, 'password': password})
|
|
69
|
+
|
|
70
|
+
def enableEmailTwoFactor(self, password):
|
|
71
|
+
return self.client.post(self._path('/two-factor/email'), json={'password': password})['recovery_codes']
|
|
72
|
+
|
|
73
|
+
def disableEmailTwoFactor(self, password):
|
|
74
|
+
return self.client.delete(self._path('/two-factor/email'), json={'password': password})
|
|
75
|
+
|
|
76
|
+
# api keys
|
|
77
|
+
def apiKeys(self, search=None, page=None, per_page=None):
|
|
78
|
+
return self.client.list(self._path('/api-keys'), 'api_keys', {'search': search}, page, per_page)
|
|
79
|
+
|
|
80
|
+
def apiKeyByIdentifier(self, identifier):
|
|
81
|
+
return self.client.get(self._path(f'/api-keys/identifier/{segment(identifier)}'))['api_key']
|
|
82
|
+
|
|
83
|
+
def createApiKey(self, name, allowed_ips=None, user_permissions=None, admin_permissions=None, server_permissions=None, enabled=None, expires=None):
|
|
84
|
+
return self.client.post(self._path('/api-keys'), json={
|
|
85
|
+
'name': name,
|
|
86
|
+
'allowed_ips': allowed_ips or [],
|
|
87
|
+
'user_permissions': user_permissions or [],
|
|
88
|
+
'admin_permissions': admin_permissions or [],
|
|
89
|
+
'server_permissions': server_permissions or [],
|
|
90
|
+
'enabled': enabled,
|
|
91
|
+
'expires': expires,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
def updateApiKey(self, api_key_id, allowed_ips, name=None, enabled=None, user_permissions=None, admin_permissions=None, server_permissions=None, expires=None):
|
|
95
|
+
return self.client.patch(self._path(f'/api-keys/{api_key_id}'), json={
|
|
96
|
+
'allowed_ips': allowed_ips,
|
|
97
|
+
'name': name,
|
|
98
|
+
'enabled': enabled,
|
|
99
|
+
'user_permissions': user_permissions,
|
|
100
|
+
'admin_permissions': admin_permissions,
|
|
101
|
+
'server_permissions': server_permissions,
|
|
102
|
+
'expires': expires,
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
def deleteApiKey(self, api_key_id):
|
|
106
|
+
return self.client.delete(self._path(f'/api-keys/{api_key_id}'))
|
|
107
|
+
|
|
108
|
+
def duplicateApiKey(self, api_key_id, name):
|
|
109
|
+
return self.client.post(self._path(f'/api-keys/{api_key_id}/duplicate'), json={'name': name})
|
|
110
|
+
|
|
111
|
+
def recreateApiKey(self, api_key_id):
|
|
112
|
+
return self.client.post(self._path(f'/api-keys/{api_key_id}/recreate'))['key']
|
|
113
|
+
|
|
114
|
+
# ssh keys
|
|
115
|
+
def sshKeys(self, search=None, page=None, per_page=None):
|
|
116
|
+
return self.client.list(self._path('/ssh-keys'), 'ssh_keys', {'search': search}, page, per_page)
|
|
117
|
+
|
|
118
|
+
def createSshKey(self, name, public_key):
|
|
119
|
+
return self.client.post(self._path('/ssh-keys'), json={'name': name, 'public_key': public_key})['ssh_key']
|
|
120
|
+
|
|
121
|
+
def importSshKeys(self, provider, username):
|
|
122
|
+
return self.client.post(self._path('/ssh-keys/import'), json={'provider': provider, 'username': username})['ssh_keys']
|
|
123
|
+
|
|
124
|
+
def updateSshKey(self, ssh_key_id, name):
|
|
125
|
+
return self.client.patch(self._path(f'/ssh-keys/{ssh_key_id}'), json={'name': name})
|
|
126
|
+
|
|
127
|
+
def deleteSshKey(self, ssh_key_id):
|
|
128
|
+
return self.client.delete(self._path(f'/ssh-keys/{ssh_key_id}'))
|
|
129
|
+
|
|
130
|
+
# security keys
|
|
131
|
+
def securityKeys(self, search=None, page=None, per_page=None):
|
|
132
|
+
return self.client.list(self._path('/security-keys'), 'security_keys', {'search': search}, page, per_page)
|
|
133
|
+
|
|
134
|
+
def createSecurityKey(self, name, password, allow_usernameless_login=None):
|
|
135
|
+
return self.client.post(self._path('/security-keys'), json={
|
|
136
|
+
'name': name,
|
|
137
|
+
'password': password,
|
|
138
|
+
'allow_usernameless_login': allow_usernameless_login,
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
def challengeSecurityKey(self, security_key_id, public_key_credential):
|
|
142
|
+
return self.client.post(
|
|
143
|
+
self._path(f'/security-keys/{security_key_id}/challenge'),
|
|
144
|
+
json={'public_key_credential': public_key_credential}
|
|
145
|
+
)['credential_id']
|
|
146
|
+
|
|
147
|
+
def updateSecurityKey(self, security_key_id, name):
|
|
148
|
+
return self.client.patch(self._path(f'/security-keys/{security_key_id}'), json={'name': name})
|
|
149
|
+
|
|
150
|
+
def deleteSecurityKey(self, security_key_id, password=None):
|
|
151
|
+
return self.client.delete(self._path(f'/security-keys/{security_key_id}'), json={'password': password})
|
|
152
|
+
|
|
153
|
+
# sessions
|
|
154
|
+
def sessions(self, search=None, page=None, per_page=None):
|
|
155
|
+
return self.client.list(self._path('/sessions'), 'sessions', {'search': search}, page, per_page)
|
|
156
|
+
|
|
157
|
+
def deleteSession(self, session_id):
|
|
158
|
+
return self.client.delete(self._path(f'/sessions/{session_id}'))
|
|
159
|
+
|
|
160
|
+
def deleteOtherSessions(self):
|
|
161
|
+
return self.client.delete(self._path('/sessions'))['deleted']
|
|
162
|
+
|
|
163
|
+
# oauth links
|
|
164
|
+
def oauthLinks(self, page=None, per_page=None):
|
|
165
|
+
return self.client.list(self._path('/oauth-links'), 'oauth_links', None, page, per_page)
|
|
166
|
+
|
|
167
|
+
def oauthLink(self, oauth_link_id):
|
|
168
|
+
return self.client.get(self._path(f'/oauth-links/{oauth_link_id}'))['oauth_link']
|
|
169
|
+
|
|
170
|
+
def deleteOauthLink(self, oauth_link_id):
|
|
171
|
+
return self.client.delete(self._path(f'/oauth-links/{oauth_link_id}'))
|
|
172
|
+
|
|
173
|
+
# command snippets
|
|
174
|
+
def commandSnippets(self, search=None, page=None, per_page=None):
|
|
175
|
+
return self.client.list(self._path('/command-snippets'), 'command_snippets', {'search': search}, page, per_page)
|
|
176
|
+
|
|
177
|
+
def createCommandSnippet(self, name, command, eggs=None):
|
|
178
|
+
return self.client.post(self._path('/command-snippets'), json={
|
|
179
|
+
'name': name,
|
|
180
|
+
'command': command,
|
|
181
|
+
'eggs': eggs or [],
|
|
182
|
+
})['command_snippet']
|
|
183
|
+
|
|
184
|
+
def updateCommandSnippet(self, snippet_id, name, command=None, eggs=None):
|
|
185
|
+
return self.client.patch(self._path(f'/command-snippets/{snippet_id}'), json={
|
|
186
|
+
'name': name,
|
|
187
|
+
'command': command,
|
|
188
|
+
'eggs': eggs,
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
def deleteCommandSnippet(self, snippet_id):
|
|
192
|
+
return self.client.delete(self._path(f'/command-snippets/{snippet_id}'))
|
|
193
|
+
|
|
194
|
+
def duplicateCommandSnippet(self, snippet_id, name):
|
|
195
|
+
return self.client.post(self._path(f'/command-snippets/{snippet_id}/duplicate'), json={'name': name})['command_snippet']
|
calagoapi/api/admin.py
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
from calagoapi.api.client import segment
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Internal Calagopus AdminAPI
|
|
5
|
+
class ResourceAPI:
|
|
6
|
+
'''Standard CRUD calls for one admin collection, e.g. /api/admin/locations'''
|
|
7
|
+
def __init__(self, client, path, key, plural, parent=None):
|
|
8
|
+
self.client = client
|
|
9
|
+
self.path = f'/api/admin{path}'
|
|
10
|
+
self.key = key
|
|
11
|
+
self.plural = plural
|
|
12
|
+
# id(s) of the owning object for nested collections, e.g. the nest of an egg
|
|
13
|
+
self.parent = parent
|
|
14
|
+
|
|
15
|
+
def list(self, search=None, page=None, per_page=None, **params):
|
|
16
|
+
if search is not None:
|
|
17
|
+
params['search'] = search
|
|
18
|
+
return self.client.list(self.path, self.plural, params, page, per_page)
|
|
19
|
+
|
|
20
|
+
def listAll(self):
|
|
21
|
+
'''For collections that are not paginated'''
|
|
22
|
+
return self.client.get(self.path)[self.plural]
|
|
23
|
+
|
|
24
|
+
def get(self, resource_id):
|
|
25
|
+
return self.client.get(f'{self.path}/{resource_id}')[self.key]
|
|
26
|
+
|
|
27
|
+
def create(self, **fields):
|
|
28
|
+
return self.client.post(self.path, json=fields)[self.key]
|
|
29
|
+
|
|
30
|
+
def update(self, resource_id, **fields):
|
|
31
|
+
return self.client.patch(f'{self.path}/{resource_id}', json=fields)
|
|
32
|
+
|
|
33
|
+
def delete(self, resource_id, **body):
|
|
34
|
+
return self.client.delete(f'{self.path}/{resource_id}', json=body or None)
|
|
35
|
+
|
|
36
|
+
def duplicate(self, resource_id, **fields):
|
|
37
|
+
return self.client.post(f'{self.path}/{resource_id}/duplicate', json=fields or None)[self.key]
|
|
38
|
+
|
|
39
|
+
# sub-collections like /locations/{id}/nodes
|
|
40
|
+
def related(self, resource_id, suffix, key, search=None, page=None, per_page=None, **params):
|
|
41
|
+
if search is not None:
|
|
42
|
+
params['search'] = search
|
|
43
|
+
return self.client.list(f'{self.path}/{resource_id}/{suffix}', key, params, page, per_page)
|
|
44
|
+
|
|
45
|
+
def attach(self, resource_id, suffix, field, value):
|
|
46
|
+
return self.client.post(f'{self.path}/{resource_id}/{suffix}', json={field: value})
|
|
47
|
+
|
|
48
|
+
def detach(self, resource_id, suffix, child_id):
|
|
49
|
+
return self.client.delete(f'{self.path}/{resource_id}/{suffix}/{child_id}')
|
|
50
|
+
|
|
51
|
+
def action(self, resource_id, suffix, method='POST', json=None, params=None):
|
|
52
|
+
return self.client.request(method, f'{self.path}/{resource_id}/{suffix}', json=json, params=params)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class AdminAPI:
|
|
56
|
+
def __init__(self, client):
|
|
57
|
+
self.client = client
|
|
58
|
+
|
|
59
|
+
self.users = ResourceAPI(client, '/users', 'user', 'users')
|
|
60
|
+
self.servers = ResourceAPI(client, '/servers', 'server', 'servers')
|
|
61
|
+
self.nodes = ResourceAPI(client, '/nodes', 'node', 'nodes')
|
|
62
|
+
self.locations = ResourceAPI(client, '/locations', 'location', 'locations')
|
|
63
|
+
self.nests = ResourceAPI(client, '/nests', 'nest', 'nests')
|
|
64
|
+
self.mounts = ResourceAPI(client, '/mounts', 'mount', 'mounts')
|
|
65
|
+
self.devices = ResourceAPI(client, '/devices', 'device', 'devices')
|
|
66
|
+
self.roles = ResourceAPI(client, '/roles', 'role', 'roles')
|
|
67
|
+
self.announcements = ResourceAPI(client, '/announcements', 'announcement', 'announcements')
|
|
68
|
+
self.oauth_providers = ResourceAPI(client, '/oauth-providers', 'oauth_provider', 'oauth_providers')
|
|
69
|
+
self.database_hosts = ResourceAPI(client, '/database-hosts', 'database_host', 'database_hosts')
|
|
70
|
+
self.database_agent_hosts = ResourceAPI(client, '/database-agent-hosts', 'database_agent_host', 'database_agent_hosts')
|
|
71
|
+
self.database_agent_templates = ResourceAPI(client, '/database-agent-templates', 'database_agent_template', 'database_agent_templates')
|
|
72
|
+
self.backup_configurations = ResourceAPI(client, '/backup-configurations', 'backup_configuration', 'backup_configurations')
|
|
73
|
+
self.system_backup_policies = ResourceAPI(client, '/system-backup-policies', 'system_backup_policy', 'system_backup_policies')
|
|
74
|
+
self.egg_repositories = ResourceAPI(client, '/egg-repositories', 'egg_repository', 'egg_repositories')
|
|
75
|
+
self.egg_configurations = ResourceAPI(client, '/egg-configurations', 'egg_configuration', 'egg_configurations')
|
|
76
|
+
self.subdomain_domains = ResourceAPI(client, '/extensions/dev.0x7d8.subdomainmanager/domains', 'domain', 'domains')
|
|
77
|
+
|
|
78
|
+
# nested collections
|
|
79
|
+
def eggs(self, nest_id):
|
|
80
|
+
return ResourceAPI(self.client, f'/nests/{nest_id}/eggs', 'egg', 'eggs', nest_id)
|
|
81
|
+
|
|
82
|
+
def eggVariables(self, nest_id, egg_id):
|
|
83
|
+
return ResourceAPI(self.client, f'/nests/{nest_id}/eggs/{egg_id}/variables', 'variable', 'variables', (nest_id, egg_id))
|
|
84
|
+
|
|
85
|
+
def orderEggVariables(self, nest_id, egg_id, variable_order):
|
|
86
|
+
return self.client.put(f'/api/admin/nests/{nest_id}/eggs/{egg_id}/variables/order', json={'variable_order': variable_order})
|
|
87
|
+
|
|
88
|
+
def oauthMappings(self, oauth_provider_id):
|
|
89
|
+
return ResourceAPI(self.client, f'/oauth-providers/{oauth_provider_id}/mappings', 'oauth_mapping', 'oauth_mappings', oauth_provider_id)
|
|
90
|
+
|
|
91
|
+
def userOauthLinks(self, user_id):
|
|
92
|
+
return ResourceAPI(self.client, f'/users/{user_id}/oauth-links', 'oauth_link', 'oauth_links', user_id)
|
|
93
|
+
|
|
94
|
+
# users
|
|
95
|
+
def userByExternalId(self, external_id):
|
|
96
|
+
return self.client.get(f'/api/admin/users/external/{segment(external_id)}')['user']
|
|
97
|
+
|
|
98
|
+
def userServers(self, user_id, owned=None, search=None, page=None, per_page=None):
|
|
99
|
+
return self.users.related(user_id, 'servers', 'servers', search, page, per_page, owned=owned)
|
|
100
|
+
|
|
101
|
+
def userActivity(self, user_id, search=None, page=None, per_page=None):
|
|
102
|
+
return self.users.related(user_id, 'activity', 'activities', search, page, per_page)
|
|
103
|
+
|
|
104
|
+
def userDisableTwoFactor(self, user_id):
|
|
105
|
+
return self.client.delete(f'/api/admin/users/{user_id}/two-factor')
|
|
106
|
+
|
|
107
|
+
def userSendPasswordReset(self, user_id):
|
|
108
|
+
return self.client.post(f'/api/admin/users/{user_id}/email/reset-password')
|
|
109
|
+
|
|
110
|
+
def userVerifyEmail(self, user_id):
|
|
111
|
+
return self.client.post(f'/api/admin/users/{user_id}/email/verify')
|
|
112
|
+
|
|
113
|
+
# servers
|
|
114
|
+
def serverByExternalId(self, external_id):
|
|
115
|
+
return self.client.get(f'/api/admin/servers/external/{segment(external_id)}')['server']
|
|
116
|
+
|
|
117
|
+
def deployServer(self, **fields):
|
|
118
|
+
return self.client.post('/api/admin/servers/deploy', json=fields)['server']
|
|
119
|
+
|
|
120
|
+
def serverLogs(self, server_id, lines=None, install=False):
|
|
121
|
+
suffix = 'logs/install' if install else 'logs'
|
|
122
|
+
return self.client.get(f'/api/admin/servers/{server_id}/{suffix}', params={'lines': lines})
|
|
123
|
+
|
|
124
|
+
def serverVariables(self, server_id):
|
|
125
|
+
return self.client.get(f'/api/admin/servers/{server_id}/variables')['variables']
|
|
126
|
+
|
|
127
|
+
def setServerVariables(self, server_id, variables):
|
|
128
|
+
return self.client.put(f'/api/admin/servers/{server_id}/variables', json={'variables': variables})
|
|
129
|
+
|
|
130
|
+
def serverAllocations(self, server_id, search=None, page=None, per_page=None):
|
|
131
|
+
return self.servers.related(server_id, 'allocations', 'allocations', search, page, per_page)
|
|
132
|
+
|
|
133
|
+
def addServerAllocation(self, server_id, allocation_uuid):
|
|
134
|
+
return self.client.post(f'/api/admin/servers/{server_id}/allocations', json={'allocation_uuid': allocation_uuid})['allocation']
|
|
135
|
+
|
|
136
|
+
def updateServerAllocation(self, server_id, allocation_id, notes=None, primary=None):
|
|
137
|
+
return self.client.patch(f'/api/admin/servers/{server_id}/allocations/{allocation_id}', json={'notes': notes, 'primary': primary})
|
|
138
|
+
|
|
139
|
+
def removeServerAllocation(self, server_id, allocation_id):
|
|
140
|
+
return self.client.delete(f'/api/admin/servers/{server_id}/allocations/{allocation_id}')
|
|
141
|
+
|
|
142
|
+
def serverBackups(self, server_id, partially_detached=None, search=None, page=None, per_page=None):
|
|
143
|
+
return self.servers.related(server_id, 'backups', 'backups', search, page, per_page, partially_detached=partially_detached)
|
|
144
|
+
|
|
145
|
+
def serverDeleteFailedBackups(self, server_id, force=False, partially_detached=None):
|
|
146
|
+
return self.client.post(
|
|
147
|
+
f'/api/admin/servers/{server_id}/backups/delete-failed',
|
|
148
|
+
json={'force': force, 'partially_detached': partially_detached}
|
|
149
|
+
)['queued']
|
|
150
|
+
|
|
151
|
+
def serverDatabases(self, server_id, search=None, page=None, per_page=None):
|
|
152
|
+
return self.servers.related(server_id, 'databases', 'databases', search, page, per_page)
|
|
153
|
+
|
|
154
|
+
def serverDatabaseInstances(self, server_id, search=None, page=None, per_page=None):
|
|
155
|
+
return self.servers.related(server_id, 'databases/instances', 'instances', search, page, per_page)
|
|
156
|
+
|
|
157
|
+
def serverMounts(self, server_id, available=False, search=None, page=None, per_page=None):
|
|
158
|
+
suffix = 'mounts/available' if available else 'mounts'
|
|
159
|
+
return self.servers.related(server_id, suffix, 'mounts', search, page, per_page)
|
|
160
|
+
|
|
161
|
+
def serverDevices(self, server_id, available=False, search=None, page=None, per_page=None):
|
|
162
|
+
suffix = 'devices/available' if available else 'devices'
|
|
163
|
+
return self.servers.related(server_id, suffix, 'devices', search, page, per_page)
|
|
164
|
+
|
|
165
|
+
def clearServerState(self, server_id):
|
|
166
|
+
return self.client.post(f'/api/admin/servers/{server_id}/clear-state')
|
|
167
|
+
|
|
168
|
+
def transferServer(self, server_id, **fields):
|
|
169
|
+
return self.client.post(f'/api/admin/servers/{server_id}/transfer', json=fields)
|
|
170
|
+
|
|
171
|
+
def cancelServerTransfer(self, server_id):
|
|
172
|
+
return self.client.post(f'/api/admin/servers/{server_id}/transfer/cancel')
|
|
173
|
+
|
|
174
|
+
# nodes
|
|
175
|
+
def nodeAllocations(self, node_id, search=None, ip=None, port_from=None, port_to=None, assigned=None, page=None, per_page=None):
|
|
176
|
+
return self.nodes.related(
|
|
177
|
+
node_id, 'allocations', 'allocations', search, page, per_page,
|
|
178
|
+
ip=ip, port_from=port_from, port_to=port_to, assigned=assigned
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def nodeAvailableAllocations(self, node_id, search=None, page=None, per_page=None):
|
|
182
|
+
return self.nodes.related(node_id, 'allocations/available', 'allocations', search, page, per_page)
|
|
183
|
+
|
|
184
|
+
def nodeAllocationIps(self, node_id):
|
|
185
|
+
return self.client.get(f'/api/admin/nodes/{node_id}/allocations/ips')['ips']
|
|
186
|
+
|
|
187
|
+
def createNodeAllocations(self, node_id, ip, ports, ip_alias=None):
|
|
188
|
+
return self.client.post(f'/api/admin/nodes/{node_id}/allocations', json={'ip': ip, 'ports': ports, 'ip_alias': ip_alias})['created']
|
|
189
|
+
|
|
190
|
+
def updateNodeAllocations(self, node_id, selector, ip, ip_alias=None):
|
|
191
|
+
return self.client.patch(f'/api/admin/nodes/{node_id}/allocations', json={'selector': selector, 'ip': ip, 'ip_alias': ip_alias})
|
|
192
|
+
|
|
193
|
+
def deleteNodeAllocations(self, node_id, selector, force=None):
|
|
194
|
+
return self.client.delete(f'/api/admin/nodes/{node_id}/allocations', json={'selector': selector, 'force': force})
|
|
195
|
+
|
|
196
|
+
def nodeBackups(self, node_id, detached=None, search=None, page=None, per_page=None):
|
|
197
|
+
return self.nodes.related(node_id, 'backups', 'backups', search, page, per_page, detached=detached)
|
|
198
|
+
|
|
199
|
+
def nodeBackup(self, node_id, backup_id):
|
|
200
|
+
return self.client.get(f'/api/admin/nodes/{node_id}/backups/{backup_id}')['backup']
|
|
201
|
+
|
|
202
|
+
def nodeBackupAction(self, node_id, backup_id, action, method='POST', json=None):
|
|
203
|
+
suffix = f'/{action}' if action else ''
|
|
204
|
+
return self.client.request(method, f'/api/admin/nodes/{node_id}/backups/{backup_id}{suffix}', json=json)
|
|
205
|
+
|
|
206
|
+
def nodeDeleteFailedBackups(self, node_id, force=False, detached=None):
|
|
207
|
+
return self.client.post(f'/api/admin/nodes/{node_id}/backups/delete-failed', json={'force': force, 'detached': detached})['queued']
|
|
208
|
+
|
|
209
|
+
def nodeConfig(self, node_id):
|
|
210
|
+
return self.client.get(f'/api/admin/nodes/{node_id}/config')
|
|
211
|
+
|
|
212
|
+
def updateNodeConfig(self, node_id, config):
|
|
213
|
+
return self.client.patch(f'/api/admin/nodes/{node_id}/config', json=config)['applied']
|
|
214
|
+
|
|
215
|
+
def updateNodesConfig(self, node_ids, config):
|
|
216
|
+
return self.client.patch('/api/admin/nodes/config', json={'node_uuids': node_ids, 'config': config})
|
|
217
|
+
|
|
218
|
+
def nodeCapacities(self):
|
|
219
|
+
return self.client.get('/api/admin/nodes/capacities')['allocated']
|
|
220
|
+
|
|
221
|
+
def probeNode(self, url, pairing_code):
|
|
222
|
+
return self.client.post('/api/admin/nodes/probe', json={'url': url, 'pairing_code': pairing_code})['probe']
|
|
223
|
+
|
|
224
|
+
def nodeGet(self, node_id, suffix, params=None):
|
|
225
|
+
return self.client.get(f'/api/admin/nodes/{node_id}/{suffix}', params=params)
|
|
226
|
+
|
|
227
|
+
def nodePost(self, node_id, suffix, json=None):
|
|
228
|
+
return self.client.post(f'/api/admin/nodes/{node_id}/{suffix}', json=json)
|
|
229
|
+
|
|
230
|
+
def nodeSystemLog(self, node_id, file, lines=None):
|
|
231
|
+
return self.client.get(f'/api/admin/nodes/{node_id}/system/logs/{segment(file)}', params={'lines': lines})
|
|
232
|
+
|
|
233
|
+
def nodeServerPower(self, node_id, action, server_ids=None):
|
|
234
|
+
selector = {'type': 'uuids', 'uuids': server_ids} if server_ids else {'type': 'all'}
|
|
235
|
+
return self.client.post(f'/api/admin/nodes/{node_id}/servers/power', json={'servers': selector, 'action': action})['affected']
|
|
236
|
+
|
|
237
|
+
def nodeServerTransfer(self, node_id, **fields):
|
|
238
|
+
return self.client.post(f'/api/admin/nodes/{node_id}/servers/transfer', json=fields)
|
|
239
|
+
|
|
240
|
+
def nodeTunnel(self, node_id, method='GET', json=None, suffix=''):
|
|
241
|
+
return self.client.request(method, f'/api/admin/nodes/{node_id}/tunnel{suffix}', json=json)
|
|
242
|
+
|
|
243
|
+
# nests and eggs
|
|
244
|
+
def allEggs(self):
|
|
245
|
+
return self.client.get('/api/admin/nests/eggs')['nests']
|
|
246
|
+
|
|
247
|
+
# egg repositories
|
|
248
|
+
def syncEggRepository(self, repository_id):
|
|
249
|
+
return self.client.post(f'/api/admin/egg-repositories/{repository_id}/sync')['found']
|
|
250
|
+
|
|
251
|
+
def installRepositoryEggs(self, repository_id, egg_ids, nest_uuid):
|
|
252
|
+
return self.client.post(
|
|
253
|
+
f'/api/admin/egg-repositories/{repository_id}/eggs/install',
|
|
254
|
+
json={'egg_uuids': egg_ids, 'nest_uuid': nest_uuid}
|
|
255
|
+
)['installed']
|
|
256
|
+
|
|
257
|
+
def installRepositoryEgg(self, repository_id, egg_id, nest_uuid):
|
|
258
|
+
return self.client.post(
|
|
259
|
+
f'/api/admin/egg-repositories/{repository_id}/eggs/{egg_id}/install',
|
|
260
|
+
json={'nest_uuid': nest_uuid}
|
|
261
|
+
)['egg']
|
|
262
|
+
|
|
263
|
+
# oauth
|
|
264
|
+
def discoverOauthProvider(self, url):
|
|
265
|
+
return self.client.post('/api/admin/oauth-providers/discover', json={'url': url})['oauth_provider']
|
|
266
|
+
|
|
267
|
+
def oauthProviderUserLink(self, oauth_provider_id, identifier):
|
|
268
|
+
return self.client.get(f'/api/admin/oauth-providers/{oauth_provider_id}/users/identifier/{segment(identifier)}')['user_oauth_link']
|
|
269
|
+
|
|
270
|
+
# database agent hosts
|
|
271
|
+
def databaseAgentHostGet(self, host_id, suffix, params=None):
|
|
272
|
+
return self.client.get(f'/api/admin/database-agent-hosts/{host_id}/{suffix}', params=params)
|
|
273
|
+
|
|
274
|
+
def databaseAgentHostPost(self, host_id, suffix, json=None):
|
|
275
|
+
return self.client.post(f'/api/admin/database-agent-hosts/{host_id}/{suffix}', json=json)
|
|
276
|
+
|
|
277
|
+
def databaseAgentInstance(self, host_id, instance_id, method='GET', json=None):
|
|
278
|
+
return self.client.request(method, f'/api/admin/database-agent-hosts/{host_id}/instances/{instance_id}', json=json)
|
|
279
|
+
|
|
280
|
+
def updateDatabaseAgentHostConfig(self, host_id, config):
|
|
281
|
+
return self.client.patch(f'/api/admin/database-agent-hosts/{host_id}/config', json=config)['applied']
|
|
282
|
+
|
|
283
|
+
def updateDatabaseAgentHostsConfig(self, host_ids, config):
|
|
284
|
+
return self.client.patch('/api/admin/database-agent-hosts/config', json={'database_agent_host_uuids': host_ids, 'config': config})
|
|
285
|
+
|
|
286
|
+
def databaseAgentCapacities(self):
|
|
287
|
+
return self.client.get('/api/admin/database-agent-hosts/capacities')['allocated']
|
|
288
|
+
|
|
289
|
+
def updateTemplateInstances(self, template_id, instances):
|
|
290
|
+
return self.client.post(
|
|
291
|
+
f'/api/admin/database-agent-templates/{template_id}/instances/update',
|
|
292
|
+
json={'instances': instances}
|
|
293
|
+
)['updated']
|
|
294
|
+
|
|
295
|
+
# database hosts
|
|
296
|
+
def testDatabaseHost(self, host_id):
|
|
297
|
+
return self.client.post(f'/api/admin/database-hosts/{host_id}/test')
|
|
298
|
+
|
|
299
|
+
def deleteHostDatabase(self, host_id, database_id, force=False):
|
|
300
|
+
return self.client.delete(f'/api/admin/database-hosts/{host_id}/databases/{database_id}', json={'force': force})
|
|
301
|
+
|
|
302
|
+
# backup configurations
|
|
303
|
+
def testBackupConfiguration(self, node_uuid, backup_disk, backup_configs):
|
|
304
|
+
return self.client.post('/api/admin/backup-configurations/test', json={
|
|
305
|
+
'node_uuid': node_uuid,
|
|
306
|
+
'backup_disk': backup_disk,
|
|
307
|
+
'backup_configs': backup_configs,
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
def deleteFailedBackups(self, collection, resource_id, force=False):
|
|
311
|
+
return self.client.post(f'/api/admin/{collection}/{resource_id}/backups/delete-failed', json={'force': force})['queued']
|
|
312
|
+
|
|
313
|
+
def backupConfigurationStats(self, configuration_id):
|
|
314
|
+
return self.client.get(f'/api/admin/backup-configurations/{configuration_id}/stats')
|
|
315
|
+
|
|
316
|
+
def triggerSystemBackupPolicy(self, policy_id):
|
|
317
|
+
return self.client.post(f'/api/admin/system-backup-policies/{policy_id}/trigger')
|
|
318
|
+
|
|
319
|
+
# subdomain manager
|
|
320
|
+
def testSubdomainDomain(self, domain_id):
|
|
321
|
+
return self.client.post(f'/api/admin/extensions/dev.0x7d8.subdomainmanager/domains/{domain_id}/test')
|
|
322
|
+
|
|
323
|
+
# settings and stats
|
|
324
|
+
def settings(self):
|
|
325
|
+
return self.client.get('/api/admin/settings')['settings']
|
|
326
|
+
|
|
327
|
+
def updateSettings(self, **fields):
|
|
328
|
+
return self.client.put('/api/admin/settings', json=fields)
|
|
329
|
+
|
|
330
|
+
def activity(self, user=None, search=None, page=None, per_page=None):
|
|
331
|
+
return self.client.list('/api/admin/activity', 'activities', {'user': user, 'search': search}, page, per_page)
|
|
332
|
+
|
|
333
|
+
def generalStats(self):
|
|
334
|
+
return self.client.get('/api/admin/stats/general')['stats']
|
|
335
|
+
|
|
336
|
+
def backupStats(self):
|
|
337
|
+
return self.client.get('/api/admin/stats/backups')
|
|
338
|
+
|
|
339
|
+
# system
|
|
340
|
+
def system(self, suffix, method='GET', json=None, params=None):
|
|
341
|
+
return self.client.request(method, f'/api/admin/system/{suffix}', json=json, params=params)
|
|
342
|
+
|
|
343
|
+
# email
|
|
344
|
+
def emailTemplates(self):
|
|
345
|
+
return self.client.get('/api/admin/system/email/templates')['email_templates']
|
|
346
|
+
|
|
347
|
+
def emailTemplate(self, identifier):
|
|
348
|
+
return self.client.get(f'/api/admin/system/email/templates/{segment(identifier)}')['email_template']
|
|
349
|
+
|
|
350
|
+
def updateEmailTemplate(self, identifier, subject=None, content=None, enabled=None):
|
|
351
|
+
return self.client.put(f'/api/admin/system/email/templates/{segment(identifier)}', json={'subject': subject, 'content': content, 'enabled': enabled})
|
|
352
|
+
|
|
353
|
+
def emailVariables(self, identifier=None):
|
|
354
|
+
path = f'templates/{segment(identifier)}/variables' if identifier else 'variables'
|
|
355
|
+
return self.client.get(f'/api/admin/system/email/{path}')['email_variables']
|
|
356
|
+
|
|
357
|
+
def createEmailVariable(self, name, value, value_translations=None, identifier=None):
|
|
358
|
+
path = f'templates/{segment(identifier)}/variables' if identifier else 'variables'
|
|
359
|
+
return self.client.post(f'/api/admin/system/email/{path}', json={'name': name, 'value': value, 'value_translations': value_translations})
|
|
360
|
+
|
|
361
|
+
def updateEmailVariable(self, name, value=None, value_translations=None, identifier=None):
|
|
362
|
+
path = f'templates/{segment(identifier)}/variables' if identifier else 'variables'
|
|
363
|
+
return self.client.put(f'/api/admin/system/email/{path}/{segment(name)}', json={'value': value, 'value_translations': value_translations})
|
|
364
|
+
|
|
365
|
+
def deleteEmailVariable(self, name, identifier=None):
|
|
366
|
+
path = f'templates/{segment(identifier)}/variables' if identifier else 'variables'
|
|
367
|
+
return self.client.delete(f'/api/admin/system/email/{path}/{segment(name)}')
|
|
368
|
+
|
|
369
|
+
def sendTestEmail(self, email):
|
|
370
|
+
return self.client.post('/api/admin/system/email/test', json={'email': email})
|
|
371
|
+
|
|
372
|
+
# assets
|
|
373
|
+
def assets(self, directory=None, page=None, per_page=None):
|
|
374
|
+
return self.client.list('/api/admin/assets', 'assets', {'directory': directory}, page, per_page)
|
|
375
|
+
|
|
376
|
+
def uploadAsset(self, content, directory=None, content_type='application/octet-stream'):
|
|
377
|
+
return self.client.request(
|
|
378
|
+
'PUT', '/api/admin/assets', params={'directory': directory},
|
|
379
|
+
data=content, headers={'Content-Type': content_type}
|
|
380
|
+
)['assets']
|
|
381
|
+
|
|
382
|
+
def searchAssets(self, search, directory=None, per_page=None):
|
|
383
|
+
return self.client.post('/api/admin/assets/search', json={'search': search, 'directory': directory, 'per_page': per_page})['assets']
|
|
384
|
+
|
|
385
|
+
def deleteAssets(self, names):
|
|
386
|
+
return self.client.post('/api/admin/assets/delete', json={'names': names})['deleted']
|
|
387
|
+
|
|
388
|
+
# extensions
|
|
389
|
+
def extensions(self):
|
|
390
|
+
return self.client.get('/api/admin/extensions')
|
|
391
|
+
|
|
392
|
+
def setExtensionEnabled(self, extension_id, enabled):
|
|
393
|
+
return self.client.patch(f'/api/admin/extensions/{segment(extension_id)}', json={'enabled': enabled})['pending_restart']
|
|
394
|
+
|
|
395
|
+
def manageExtensions(self, suffix, method='GET', json=None, params=None, data=None, headers=None):
|
|
396
|
+
return self.client.request(method, f'/api/admin/extensions/manage/{suffix}', json=json, params=params, data=data, headers=headers)
|
|
397
|
+
|
|
398
|
+
def removeExtension(self, extension_id, remove_migrations=False):
|
|
399
|
+
return self.client.delete(f'/api/admin/extensions/manage/{segment(extension_id)}', json={'remove_migrations': remove_migrations})
|
|
400
|
+
|
|
401
|
+
def extension(self, extension_id, suffix, method='GET', json=None):
|
|
402
|
+
return self.client.request(method, f'/api/admin/extensions/{extension_id}/{suffix}', json=json)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Internal Calagopus AttachmentsAPI (server mounts and devices)
|
|
2
|
+
class AttachmentsAPI:
|
|
3
|
+
def __init__(self, client):
|
|
4
|
+
self.client = client
|
|
5
|
+
|
|
6
|
+
def _path(self, server_id, suffix=''):
|
|
7
|
+
return f'/api/client/servers/{server_id}{suffix}'
|
|
8
|
+
|
|
9
|
+
# mounts
|
|
10
|
+
def mounts(self, server_id, search=None, page=None, per_page=None):
|
|
11
|
+
return self.client.list(self._path(server_id, '/mounts'), 'mounts', {'search': search}, page, per_page)
|
|
12
|
+
|
|
13
|
+
def attachMount(self, server_id, mount_uuid):
|
|
14
|
+
return self.client.post(self._path(server_id, '/mounts'), json={'mount_uuid': mount_uuid})
|
|
15
|
+
|
|
16
|
+
def detachMount(self, server_id, mount_uuid):
|
|
17
|
+
return self.client.delete(self._path(server_id, f'/mounts/{mount_uuid}'))
|
|
18
|
+
|
|
19
|
+
# devices
|
|
20
|
+
def devices(self, server_id, search=None, page=None, per_page=None):
|
|
21
|
+
return self.client.list(self._path(server_id, '/devices'), 'devices', {'search': search}, page, per_page)
|
|
22
|
+
|
|
23
|
+
def attachDevice(self, server_id, device_uuid):
|
|
24
|
+
return self.client.post(self._path(server_id, '/devices'), json={'device_uuid': device_uuid})
|
|
25
|
+
|
|
26
|
+
def detachDevice(self, server_id, device_uuid):
|
|
27
|
+
return self.client.delete(self._path(server_id, f'/devices/{device_uuid}'))
|