Skip to content

Commit 99c574d

Browse files
committed
Added cloud manager secret
Signed-off-by: Andrew Perry <[email protected]>
1 parent 1a77941 commit 99c574d

File tree

1 file changed

+54
-9
lines changed

1 file changed

+54
-9
lines changed

manager_net.py

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ class ManagerNet(object):
2121
username = ''
2222
password = ''
2323
hostname = ''
24-
client_id = "caa87d9a-8cd7-4686-8b6e-ee2cdc5ee267"
25-
client_secret = "3ecff363-7eb3-44be-9e07-6d4386c48b0b"
24+
default_client_id = "caa87d9a-8cd7-4686-8b6e-ee2cdc5ee267"
25+
default_client_secret = "3ecff363-7eb3-44be-9e07-6d4386c48b0b"
26+
client_id = default_client_id
27+
client_secret = default_client_secret
2628
grant_type = 'password'
29+
cm_token = None # Cloud manager access token
30+
cm_token_expires = 0 # Cloud manager access token expiration
2731
token = None
2832
token_expires = 0
2933
max_frequency = 600
@@ -43,7 +47,7 @@ def __init__(self, config, trawler):
4347
self.namespace = config.get('namespace', 'default')
4448
# Maximum frequency to pull data from APIC
4549
self.max_frequency = int(config.get('frequency', 600))
46-
self.grant_type = config.get('grant_type', 'password')
50+
#self.grant_type = config.get('grant_type', 'password')
4751
self.org_metrics = (config.get('process_org_metrics', 'true') == 'true')
4852
self.version = Gauge('apiconnect_build_info',
4953
"A metric with a constant '1' value labeled with API Connect version details",
@@ -54,7 +58,15 @@ def __init__(self, config, trawler):
5458
self.load_credentials_from_secret(
5559
config.get('secret'),
5660
config.get('secret_namespace', self.namespace))
57-
else:
61+
62+
if 'cloud_manager_secret' in config:
63+
# If config points to a secret, then load from that
64+
# either in this namespace, or the specified one
65+
self.load_credentials_from_secret(
66+
config.get('cloud_manager_secret' ),
67+
config.get('secret_namespace', self.namespace))
68+
69+
if not 'secret' in config and not 'cloud_manager_secret' in config:
5870
# Cloud manager username to use for REST calls
5971
self.username = config.get('username', 'admin')
6072
if self.grant_type == 'client_credentials':
@@ -63,9 +75,11 @@ def __init__(self, config, trawler):
6375
else:
6476
# Load password from secret `cloudmanager_password`
6577
self.password = trawler.read_secret('cloudmanager_password')
78+
6679
if self.password is None:
6780
# Use out of box default password
6881
self.password = 'admin'
82+
6983
self.hostname = self.find_hostname()
7084
logger.debug("Hostname found is {}".format(self.hostname))
7185
self.trawler = trawler
@@ -87,6 +101,7 @@ def load_credentials_from_secret(self, secret_name, namespace):
87101
if 'client_secret' in secrets_response.data:
88102
self.client_secret = base64.b64decode(secrets_response.data['client_secret']).decode('utf-8')
89103
self.client_id = base64.b64decode(secrets_response.data['client_id']).decode('utf-8')
104+
self.grant_type = 'client_credentials'
90105
logger.info("Client ID to use is {}, Client Secret length is {}".format(self.client_id, len(self.client_secret)))
91106

92107
except client.rest.ApiException as e:
@@ -128,6 +143,9 @@ def find_hostname(self):
128143
logger.exception(e)
129144

130145
def get_webhook_status(self):
146+
"""Get the webhook data from the API Manager
147+
This requires cloud manager access
148+
"""
131149
logger.info("Getting webhook data from API Manager")
132150
try:
133151
url = "https://{}/api/cloud/webhooks".format(self.hostname)
@@ -136,7 +154,7 @@ def get_webhook_status(self):
136154
headers={
137155
"Accept": "application/json",
138156
"Content-Type": "application/json",
139-
"Authorization": "Bearer {}".format(self.token),
157+
"Authorization": "Bearer {}".format(self.cm_token),
140158
},
141159
verify=False
142160
)
@@ -200,6 +218,10 @@ def fish(self):
200218
logger.debug("Disabled because a fatal error already occurred")
201219
return
202220

221+
# Allow 10 seconds to run
222+
if self.cm_token_expires - 10 < time.time():
223+
self.get_token(self.hostname, cloud_manager=True)
224+
203225
# Allow 10 seconds to run
204226
if self.token_expires - 10 < time.time():
205227
self.get_token(self.hostname)
@@ -214,6 +236,7 @@ def fish(self):
214236
logger.debug(self.data)
215237
else:
216238
logger.warning("No token")
239+
217240
if 'counts' in self.data:
218241
for object_type in self.data['counts']:
219242
logger.debug("Type: {}, Value: {}".format(object_type, self.data['counts'][object_type]))
@@ -223,6 +246,7 @@ def fish(self):
223246
if org['org_type'] != 'admin':
224247
for catalog in org['catalogs']['results']:
225248
self.process_org_metrics(org['name'], catalog['name'])
249+
226250
self.get_webhook_status()
227251

228252
@alog.timed_function(logger.trace)
@@ -273,7 +297,13 @@ def process_org_metrics(self, org_name, catalog_name):
273297

274298
# Get the authorization bearer token
275299
# See https://chrisphillips-cminion.github.io/apiconnect/2019/09/18/GettingoAuthTokenFromAPIC.html
276-
def get_token(self, host):
300+
def get_token(self, host, cloud_manager=False):
301+
"""Get the auth token from API Manager or Cloud Manager
302+
API Manager requires client credentials, client_id and client_secret
303+
Cloud Manager requires username and password, along with the known client_id and client_secret
304+
The secret in the config could be either grant_type client_credentials or password,
305+
but cloud manager access is always requried to be grant_type password.
306+
"""
277307
logger.debug("Getting bearer token")
278308

279309
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
@@ -284,6 +314,12 @@ def get_token(self, host):
284314
data['username'] = self.username
285315
data['password'] = self.password
286316
data['realm'] = 'admin/default-idp-1'
317+
if cloud_manager:
318+
data['client_id'] = self.default_client_id
319+
data['client_secret'] = self.default_client_secret
320+
data['username'] = self.username
321+
data['password'] = self.password
322+
data['realm'] = 'admin/default-idp-1'
287323

288324
url = "https://{}/api/token".format(host)
289325
response = requests.post(
@@ -293,10 +329,19 @@ def get_token(self, host):
293329
verify=False)
294330

295331
if response.status_code == 200:
332+
token_expires = 0
333+
token_type = "Token"
296334
json_data = response.json()
297-
self.token = json_data['access_token']
298-
self.token_expires = json_data['expires_in'] + time.time()
299-
logger.info("Token expires at {} UTC".format(datetime.datetime.utcfromtimestamp(int(self.token_expires))))
335+
if cloud_manager:
336+
self.cm_token = json_data['access_token']
337+
self.cm_token_expires = json_data['expires_in'] + time.time()
338+
token_expires = self.cm_token_expires
339+
token_type = "Cloud Manager Token"
340+
else:
341+
self.token = json_data['access_token']
342+
self.token_expires = json_data['expires_in'] + time.time()
343+
token_expires = self.token_expires
344+
logger.info("{} expires at {} UTC".format(token_type, datetime.datetime.utcfromtimestamp(int(token_expires))))
300345
else:
301346
logger.error("Disabled manager net as failed to get bearer token: {}".format(response.status_code))
302347
self.errored = True

0 commit comments

Comments
 (0)