@@ -56,40 +56,93 @@ def _proxy(self, method, base_url, path, params=None, payload=None, verify=False
56
56
def auth (self , url : str , cluster_alias : str , username : str ,
57
57
password = None , token = None , hub_url = None , cluster_fsid = None ,
58
58
prometheus_api_url = None , ssl_verify = False , ssl_certificate = None ):
59
+ try :
60
+ hub_fsid = mgr .get ('config' )['fsid' ]
61
+ except KeyError :
62
+ hub_fsid = ''
63
+
59
64
if password :
60
65
payload = {
61
66
'username' : username ,
62
67
'password' : password
63
68
}
64
- content = self ._proxy ('POST' , url , 'api/auth' , payload = payload )
65
- if 'token' not in content :
66
- raise DashboardException (
67
- "Could not authenticate to remote cluster" ,
68
- http_status_code = 400 ,
69
- component = 'dashboard' )
70
-
71
- cluster_token = content ['token' ]
69
+ cluster_token = self .check_cluster_connection (url , payload , username ,
70
+ ssl_verify , ssl_certificate )
72
71
73
72
self ._proxy ('PUT' , url , 'ui-api/multi-cluster/set_cors_endpoint' ,
74
73
payload = {'url' : hub_url }, token = cluster_token , verify = ssl_verify ,
75
74
cert = ssl_certificate )
75
+
76
76
fsid = self ._proxy ('GET' , url , 'api/health/get_cluster_fsid' , token = cluster_token )
77
77
78
+ managed_by_clusters_content = self ._proxy ('GET' , url ,
79
+ 'api/settings/MANAGED_BY_CLUSTERS' ,
80
+ token = cluster_token )
81
+
82
+ managed_by_clusters_config = managed_by_clusters_content ['value' ]
83
+
84
+ if managed_by_clusters_config is not None :
85
+ managed_by_clusters_config .append ({'url' : hub_url , 'fsid' : hub_fsid })
86
+
87
+ self ._proxy ('PUT' , url , 'api/settings/MANAGED_BY_CLUSTERS' ,
88
+ payload = {'value' : managed_by_clusters_config }, token = cluster_token ,
89
+ verify = ssl_verify , cert = ssl_certificate )
90
+
78
91
# add prometheus targets
79
92
prometheus_url = self ._proxy ('GET' , url , 'api/settings/PROMETHEUS_API_HOST' ,
80
93
token = cluster_token )
94
+
81
95
_set_prometheus_targets (prometheus_url ['value' ])
82
96
83
97
self .set_multi_cluster_config (fsid , username , url , cluster_alias ,
84
98
cluster_token , prometheus_url ['value' ],
85
99
ssl_verify , ssl_certificate )
86
- return
100
+ return True
87
101
88
102
if token and cluster_fsid and prometheus_api_url :
89
103
_set_prometheus_targets (prometheus_api_url )
90
104
self .set_multi_cluster_config (cluster_fsid , username , url ,
91
105
cluster_alias , token , prometheus_api_url ,
92
106
ssl_verify , ssl_certificate )
107
+ return True
108
+
109
+ def check_cluster_connection (self , url , payload , username , ssl_verify , ssl_certificate ):
110
+ try :
111
+ content = self ._proxy ('POST' , url , 'api/auth' , payload = payload ,
112
+ verify = ssl_verify , cert = ssl_certificate )
113
+ if 'token' not in content :
114
+ raise DashboardException (msg = content ['detail' ], code = 'invalid_credentials' ,
115
+ component = 'multi-cluster' )
116
+
117
+ user_content = self ._proxy ('GET' , url , f'api/user/{ username } ' ,
118
+ token = content ['token' ])
119
+
120
+ if 'status' in user_content and user_content ['status' ] == '403 Forbidden' :
121
+ raise DashboardException (msg = 'User is not an administrator' ,
122
+ code = 'invalid_permission' , component = 'multi-cluster' )
123
+ if 'roles' in user_content and 'administrator' not in user_content ['roles' ]:
124
+ raise DashboardException (msg = 'User is not an administrator' ,
125
+ code = 'invalid_permission' , component = 'multi-cluster' )
126
+
127
+ except Exception as e :
128
+ if '[Errno 111] Connection refused' in str (e ):
129
+ raise DashboardException (msg = 'Connection refused' ,
130
+ code = 'connection_refused' , component = 'multi-cluster' )
131
+ raise DashboardException (msg = str (e ), code = 'connection_failed' ,
132
+ component = 'multi-cluster' )
133
+
134
+ cluster_token = content ['token' ]
135
+
136
+ managed_by_clusters_content = self ._proxy ('GET' , url , 'api/settings/MANAGED_BY_CLUSTERS' ,
137
+ token = cluster_token )
138
+
139
+ managed_by_clusters_config = managed_by_clusters_content ['value' ]
140
+
141
+ if len (managed_by_clusters_config ) > 1 :
142
+ raise DashboardException (msg = 'Cluster is already managed by another cluster' ,
143
+ code = 'cluster_managed_by_another_cluster' ,
144
+ component = 'multi-cluster' )
145
+ return cluster_token
93
146
94
147
def set_multi_cluster_config (self , fsid , username , url , cluster_alias , token ,
95
148
prometheus_url = None , ssl_verify = False , ssl_certificate = None ):
@@ -144,7 +197,7 @@ def set_config(self, config: object):
144
197
145
198
@Endpoint ('PUT' )
146
199
@UpdatePermission
147
- # pylint: disable=unused-variable
200
+ # pylint: disable=W0613
148
201
def reconnect_cluster (self , url : str , username = None , password = None , token = None ,
149
202
ssl_verify = False , ssl_certificate = None ):
150
203
multicluster_config = self .load_multi_cluster_config ()
@@ -153,24 +206,18 @@ def reconnect_cluster(self, url: str, username=None, password=None, token=None,
153
206
'username' : username ,
154
207
'password' : password
155
208
}
156
- content = self ._proxy ('POST' , url , 'api/auth' , payload = payload ,
157
- verify = ssl_verify , cert = ssl_certificate )
158
- if 'token' not in content :
159
- raise DashboardException (
160
- "Could not authenticate to remote cluster" ,
161
- http_status_code = 400 ,
162
- component = 'dashboard' )
163
209
164
- token = content ['token' ]
210
+ cluster_token = self .check_cluster_connection (url , payload , username ,
211
+ ssl_verify , ssl_certificate )
165
212
166
- if username and token :
213
+ if username and cluster_token :
167
214
if "config" in multicluster_config :
168
215
for _ , cluster_details in multicluster_config ["config" ].items ():
169
216
for cluster in cluster_details :
170
217
if cluster ["url" ] == url and cluster ["user" ] == username :
171
- cluster ['token' ] = token
218
+ cluster ['token' ] = cluster_token
172
219
Settings .MULTICLUSTER_CONFIG = multicluster_config
173
- return Settings . MULTICLUSTER_CONFIG
220
+ return True
174
221
175
222
@Endpoint ('PUT' )
176
223
@UpdatePermission
@@ -189,10 +236,17 @@ def edit_cluster(self, url, cluster_alias, username):
189
236
@DeletePermission
190
237
def delete_cluster (self , cluster_name , cluster_user ):
191
238
multicluster_config = self .load_multi_cluster_config ()
239
+ try :
240
+ hub_fsid = mgr .get ('config' )['fsid' ]
241
+ except KeyError :
242
+ hub_fsid = ''
192
243
if "config" in multicluster_config :
193
244
for key , value in list (multicluster_config ['config' ].items ()):
194
245
if value [0 ]['name' ] == cluster_name and value [0 ]['user' ] == cluster_user :
195
-
246
+ cluster_url = value [0 ]['url' ]
247
+ cluster_token = value [0 ]['token' ]
248
+ cluster_ssl_certificate = value [0 ]['ssl_certificate' ]
249
+ cluster_ssl_verify = value [0 ]['ssl_verify' ]
196
250
orch_backend = mgr .get_module_option_ex ('orchestrator' , 'orchestrator' )
197
251
try :
198
252
if orch_backend == 'cephadm' :
@@ -204,55 +258,25 @@ def delete_cluster(self, cluster_name, cluster_user):
204
258
except KeyError :
205
259
pass
206
260
261
+ managed_by_clusters_content = self ._proxy ('GET' , cluster_url ,
262
+ 'api/settings/MANAGED_BY_CLUSTERS' ,
263
+ token = cluster_token )
264
+
265
+ managed_by_clusters_config = managed_by_clusters_content ['value' ]
266
+ for cluster in managed_by_clusters_config :
267
+ if cluster ['fsid' ] == hub_fsid :
268
+ managed_by_clusters_config .remove (cluster )
269
+
270
+ self ._proxy ('PUT' , cluster_url , 'api/settings/MANAGED_BY_CLUSTERS' ,
271
+ payload = {'value' : managed_by_clusters_config }, token = cluster_token ,
272
+ verify = cluster_ssl_verify , cert = cluster_ssl_certificate )
273
+
207
274
del multicluster_config ['config' ][key ]
208
275
break
209
276
210
277
Settings .MULTICLUSTER_CONFIG = multicluster_config
211
278
return Settings .MULTICLUSTER_CONFIG
212
279
213
- @Endpoint ('POST' )
214
- @CreatePermission
215
- # pylint: disable=R0911
216
- def verify_connection (self , url = None , username = None , password = None , token = None ,
217
- ssl_verify = False , ssl_certificate = None ):
218
- if token :
219
- try :
220
- payload = {
221
- 'token' : token
222
- }
223
- content = self ._proxy ('POST' , url , 'api/auth/check' , payload = payload ,
224
- verify = ssl_verify , cert = ssl_certificate )
225
- if 'permissions' not in content :
226
- return content ['detail' ]
227
- user_content = self ._proxy ('GET' , url , f'api/user/{ username } ' ,
228
- token = content ['token' ])
229
- if 'status' in user_content and user_content ['status' ] == '403 Forbidden' :
230
- return 'User is not an administrator'
231
- except Exception as e : # pylint: disable=broad-except
232
- if '[Errno 111] Connection refused' in str (e ):
233
- return 'Connection refused'
234
- return 'Connection failed'
235
-
236
- if username and password :
237
- try :
238
- payload = {
239
- 'username' : username ,
240
- 'password' : password
241
- }
242
- content = self ._proxy ('POST' , url , 'api/auth' , payload = payload ,
243
- verify = ssl_verify , cert = ssl_certificate )
244
- if 'token' not in content :
245
- return content ['detail' ]
246
- user_content = self ._proxy ('GET' , url , f'api/user/{ username } ' ,
247
- token = content ['token' ])
248
- if 'status' in user_content and user_content ['status' ] == '403 Forbidden' :
249
- return 'User is not an administrator'
250
- except Exception as e : # pylint: disable=broad-except
251
- if '[Errno 111] Connection refused' in str (e ):
252
- return 'Connection refused'
253
- return 'Connection failed'
254
- return 'Connection successful'
255
-
256
280
@Endpoint ()
257
281
@ReadPermission
258
282
def get_config (self ):
0 commit comments