Skip to content

Commit

Permalink
INSTA 16270 update api credentials (#107)
Browse files Browse the repository at this point in the history
* Remove api and add new one for patch credential

* add update cred with multiple associations

* update readme

* add patch credential value

* update readme
  • Loading branch information
swethalohith2 authored Oct 19, 2024
1 parent ef25925 commit 521b3ea
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 47 deletions.
8 changes: 8 additions & 0 deletions docs/synctl-patch-credential.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,27 @@ synctl patch cred <cred-name> [options]
-h, --help show this help message and exit
--verify-tls verify tls certificate
--value <value> set credential value
--apps, --applications [<id> ...] set multiple applications
--websites <id> [<id> ...] set websites
--mobile-apps <id> [<id> ...] set mobile appliactions
```
## Examples
### Patch a synthetic credential value
```
synctl patch cred swecred --value <value>
```

### Patch a Synthetic credential with multiple applications.
```
synctl patch cred <cred-name> --applications/--apps "$APPLICATION1" "$APPLICATION2" "$APPLICATION3" ..."
```

### Patch a Synthetic credential with multiple websites.
```
synctl patch cred <cred-name> --websites "$WEBSITE1" "$WEBSITE2" ...
```

### Patch a Synthetic credential with multiple mobile applications.
```
synctl patch cred <cred-name> --mobile-applications/--mobile-apps "$APPLICATION1" "$APPLICATION2" "$APPLICATION3" ..."
Expand Down
20 changes: 17 additions & 3 deletions docs/synctl-update-credential.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,25 @@ Update Synthetic credential

## Syntax
```
synctl update cred <cred-name> --value <value>
synctl update cred <cred-name> [options]
```
## Options

### Common options
```
-h, --help show this help message and exit
--verify-tls verify tls certificate
-h, --help show this help message and exit
--verify-tls verify tls certificate
--value <value> set credential value
--apps, --applications [<id> ...] set multiple applications
--websites [<id> ...] set multiple websites
--mobile-apps, --mobile-applications [<id> ...] set multiple mobile appliactions
```
## Examples
### Common Example for credentials
```
synctl update cred swecred --value <value> \
--apps "$APPID-1" "$APPID-2" ...\
--websites "$MOBILE-APPID-1" "$MOBILE-APPID-2" ...\
--mobile-apps "$WEBSITE-1" "$WEBSITE-2" ...
```
111 changes: 67 additions & 44 deletions synctl/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,23 @@ def validate_args(args):
# Estimate the cost of Instana-hosted Pop
synctl get pop-cost"""

PATCH_USAGE = """synctl patch test id [options]
PATCH_USAGE = """synctl patch {test,cred} id [options]
examples:
# set active to false
synctl patch test <syn-id> --active false
# update frequency to 5, run test every 5min
synctl patch test <id> --frequency 5"""
synctl patch test <id> --frequency 5
UPDATE_USAGE = """synctl update {test,alert} <id> [options]
# update a credential value
synctl patch cred <cred-name> --value <value>
# update a credential with multiple applications
synctl patch cred <cred-name> --apps "$APPLICATION1" "$APPLICATION2" ...
"""

UPDATE_USAGE = """synctl update {test,alert, cred} <id> [options]
examples:
# update synthetic test/smart alert using file
Expand All @@ -244,6 +251,12 @@ def validate_args(args):
--test "$SYNTHETIC_TEST1" "$SYNTHETIC_TEST2" "$SYNTHETIC_TEST3" ... \\
--violation-count 2 \\
--severity warning
# update credential with multiple options
synctl update cred <cred-name> \\
--apps "$APP-ID1" "$APP-ID2" \\
--websites "$WEBSITE-ID1" "$WEBSITE-ID2" \\
--mobile-apps "$MOBILEAPP-ID1" "$MOBILEAPP-ID2"
# enable/disable a smart alert
synctl update alert <alert-id> --enable
Expand Down Expand Up @@ -1410,7 +1423,10 @@ def __init__(self):
Base.__init__(self)
self.credential_config = {
"credentialName": "",
"credentialValue": ""
"credentialValue": "",
"applications": [],
"mobileApps": [],
"websites": []
}

def set_credential_name(self, key):
Expand All @@ -1425,15 +1441,13 @@ def set_credential_applications(self, applications: list):
def set_credential_websites(self, websites: list):
self.credential_config["websites"] = websites

def set_credential_mobile_apps(self, mobile_apps):
def set_credential_mobile_apps(self, mobile_apps: list):
self.credential_config["mobileApps"] = mobile_apps

def get_json(self):
"""return payload as json"""
if len(self.credential_config["credentialName"]) == 0:
self.exit_synctl(ERROR_CODE, "Error: no credential name, set --key <credential-name>")
elif len(self.credential_config["credentialValue"]) == 0:
self.exit_synctl(ERROR_CODE, "Error: no credential value, set --value <credential-value> ")

result = json.dumps(self.credential_config)
return result
Expand Down Expand Up @@ -1605,53 +1619,42 @@ def delete_credentials(self, cred_list):

def update_a_credential(self, cred):
self.check_host_and_token(self.auth["host"], self.auth["token"])
host = self.auth["host"]
token = self.auth["token"]
if cred is None:
print("credential should not be empty")
self.exit_synctl(ERROR_CODE, "credential should not be empty")
return

credential = self.retrieve_credentials()

host = self.auth["host"]
token = self.auth["token"]
cred_payload = self.payload
put_url = f"{host}/api/synthetics/settings/credentials/{cred}"

# delete cred
delete_url = f"{host}/api/synthetics/settings/credentials/{cred}"
headers = {
"Content-Type": "application/json",
'Content-Type': 'application/json',
"Authorization": f"apiToken {token}"
}
if cred in credential:
delete_res = requests.delete(delete_url,
try:
update_result = requests.put(put_url,
headers=headers,
data=cred_payload,
timeout=60,
verify=self.insecure)

if _status_is_204(delete_res.status_code):
pass
if _status_is_200(update_result.status_code):
print(f"cred {cred} updated")
elif _status_is_400(update_result.status_code):
print(f'Error: {update_result}', update_result.content)
elif _status_is_429(update_result.status_code):
print(update_result.content)
self.exit_synctl(ERROR_CODE, TOO_MANY_REQUEST_ERROR)
else:
self.exit_synctl(ERROR_CODE, f"Fail to delete {cred}")
else:
self.exit_synctl(ERROR_CODE, f"no credential {cred}")

# create cred
create_url = f"{host}/api/synthetics/settings/credentials/"
print(
f'update cred {cred} failed, status code: {update_result.status_code, }')
except requests.ConnectTimeout as timeout_error:
self.exit_synctl(f"Connection to {host} timed out, error is {timeout_error}")
except requests.ConnectionError as connect_error:
self.exit_synctl(f"Connection to {host} failed, error is {connect_error}")

credential = self.retrieve_credentials()
cred_payload = self.payload

if cred not in credential:
create_cred_res = requests.post(create_url,
headers=headers,
data=cred_payload,
timeout=60,
verify=self.insecure)
if _status_is_201(create_cred_res.status_code):
print(f"Credential \"{cred}\" updated")
else:
print('Update credential failed, status code:',
create_cred_res.status_code)
else:
print("Credential already exists")

def patch_applications(self, cred, applications):
payload = {"applications": []}
Expand Down Expand Up @@ -1680,6 +1683,15 @@ def patch_mobile_apps(self, cred, mobile_apps):
payload["mobileApps"] = mobile_apps
self.__patch_a_credential(cred, json.dumps(payload))

def patch_credential_value(self, cred, cred_value):
payload = {"credentialValue": ""}
if cred_value is None:
print("No value for credential")
return
else:
payload["credentialValue"] = cred_value
self.__patch_a_credential(cred, json.dumps(payload))

def __patch_a_credential(self, cred, data):
self.check_host_and_token(self.auth["host"], self.auth["token"])
host = self.auth["host"]
Expand All @@ -1689,7 +1701,7 @@ def __patch_a_credential(self, cred, data):
print("credential should not be empty")
return

patch_url = f"{host}/api/synthetics/settings/credentials/associations/{cred}"
patch_url = f"{host}/api/synthetics/settings/credentials/{cred}"

if data is None:
self.exit_synctl(ERROR_CODE, "Patch Error:data cannot be empty")
Expand Down Expand Up @@ -4955,6 +4967,8 @@ def patch_command_options(self):
'--remaining-days-check', type=int, metavar="<int>", help='check remaining days for expiration of SSL certificate')

# Patch cred
patch_exclusive_group.add_argument(
'--value', type=str, metavar="<string>", help='set credential value')
patch_exclusive_group.add_argument(
'--applications', '--apps', nargs="+", metavar="<id>", help="set applications")
patch_exclusive_group.add_argument(
Expand Down Expand Up @@ -5001,7 +5015,7 @@ def update_command_options(self):
update_group.add_argument(
'--custom-properties', type=str, metavar="<string>", help="set custom property of a test")
update_group.add_argument(
'--apps', '--applications', '--app-id', '--application-id', type=str, metavar="<application-id>", help="application id")
'--apps', '--applications', '--app-id', '--application-id',nargs='+', type=str, metavar="<application-id>", help="application id")
update_group.add_argument(
'--websites', type=str, nargs='+', metavar="<website-id>", help="website id, support multiple websites")
update_group.add_argument(
Expand Down Expand Up @@ -5672,6 +5686,8 @@ def main():
cred_instance.patch_websites(get_args.id, get_args.websites)
if get_args.mobile_apps is not None:
cred_instance.patch_mobile_apps(get_args.id, get_args.mobile_apps)
if get_args.value is not None:
cred_instance.patch_credential_value(get_args.id, get_args.value)
elif COMMAND_UPDATE == get_args.sub_command:
if get_args.syn_type == SYN_TEST:
invalid_options = ["name", "severity", "alert_channel", "test", "violation_count"]
Expand Down Expand Up @@ -5792,9 +5808,16 @@ def main():
update_alert.update_a_smart_alert(get_args.id, updated_alert_config)
if get_args.syn_type == SYN_CRED:
cred_payload = CredentialConfiguration()
if get_args.value is not None:
if get_args.id is not None:
cred_payload.set_credential_name(get_args.id)
cred_payload.set_credential_value(get_args.value)
if get_args.value is not None:
cred_payload.set_credential_value(get_args.value)
if get_args.apps is not None:
cred_payload.set_credential_applications(get_args.apps)
if get_args.websites is not None:
cred_payload.set_credential_websites(get_args.websites)
if get_args.mobile_apps is not None:
cred_payload.set_credential_mobile_apps(get_args.mobile_apps)

cred_instance.set_cred_payload(payload=cred_payload.get_json())
cred_instance.update_a_credential(get_args.id)
Expand Down

0 comments on commit 521b3ea

Please sign in to comment.