Skip to content

Commit

Permalink
Handle IndexError, KeyError; add help messages (#61)
Browse files Browse the repository at this point in the history
* Handle IndexError, KeyError; add help messages

Closes #58
Closes #60

* Output errors returned by GQL to assist support
  • Loading branch information
kolanos authored Jan 14, 2020
1 parent 6389ad6 commit 7cb1160
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 28 deletions.
108 changes: 80 additions & 28 deletions newrelic_lambda_cli/api.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
"""
This client is adapted from:
https://github.com/newrelic/nr-lambda-onboarding/blob/master/newrelic-cloud#L56
However this client uses a GQL client that supports schema introspection to eliminate
the error handling boilerplate for schema related errors.
Example usage:
>>> from newrelic_lambda_cli.gql import NewRelicGQL
>>> from newrelic_lambda_cli.api import NewRelicGQL
>>> gql = NewRelicGQL("api key here", "account id here")
>>> gql.get_linked_accounts()
Expand Down Expand Up @@ -77,7 +71,10 @@ def get_linked_accounts(self):
""",
accountId=self.account_id,
)
return res["actor"]["account"]["cloud"]["linkedAccounts"]
try:
return res["actor"]["account"]["cloud"]["linkedAccounts"]
except KeyError:
return []

def get_license_key(self):
"""
Expand All @@ -100,14 +97,20 @@ def get_license_key(self):
""",
accountId=self.account_id,
)
return res["actor"]["account"]["licenseKey"]
try:
return res["actor"]["account"]["licenseKey"]
except KeyError:
return None

def get_linked_account_by_name(self, account_name):
"""
return a specific linked account of the New Relic account
"""
accounts = self.get_linked_accounts()
return next((a for a in accounts if a["name"] == account_name), None)
try:
return next((a for a in accounts if a["name"] == account_name), None)
except KeyError:
return None

def link_account(self, role_arn, account_name):
"""
Expand All @@ -131,13 +134,21 @@ def link_account(self, role_arn, account_name):
accountId=self.account_id,
accounts={"aws": {"arn": role_arn, "name": account_name}},
)
return res["cloudLinkAccount"]["linkedAccounts"][0]
try:
return res["cloudLinkAccount"]["linkedAccounts"][0]
except (IndexError, KeyError):
if "errors" in res:
failure(
"Error while linking account with New Relic:\n%s"
% "\n".join([e["message"] for e in res["errors"] if "message" in e])
)
return None

def unlink_account(self, linked_account_id):
"""
Unlink a New Relic Cloud integrations account
"""
return self.query(
res = self.query(
"""
mutation ($accountId: Int!, $accounts: CloudUnlinkCloudAccountsInput!) {
cloudUnLinkAccount (accountId: $accountId, accounts: $accounts) {
Expand All @@ -155,6 +166,12 @@ def unlink_account(self, linked_account_id):
accountId=self.account_id,
accounts={"linkedAccountId": linked_account_id},
)
if "errors" in res:
failure(
"Error while unlinking account with New Relic:\n%s"
% "\n".join([e["message"] for e in res["errors"] if "message" in e])
)
return res

def get_integrations(self, linked_account_id):
"""
Expand Down Expand Up @@ -186,19 +203,28 @@ def get_integrations(self, linked_account_id):
accountId=self.account_id,
linkedAccountId=int(linked_account_id),
)
return res["actor"]["account"]["cloud"]["linkedAccount"]["integrations"]
try:
return res["actor"]["account"]["cloud"]["linkedAccount"]["integrations"]
except KeyError:
return []

def get_integration_by_service_slug(self, linked_account_id, service_slug):
integrations = self.get_integrations(linked_account_id)
return next(
(i for i in integrations if i["service"]["slug"] == service_slug), None
)
try:
return next(
(i for i in integrations if i["service"]["slug"] == service_slug), None
)
except KeyError:
return None

def is_integration_enabled(self, linked_account_id, service_slug):
integration = self.get_integration_by_service_slug(
linked_account_id, service_slug
)
return integration and integration["service"]["isEnabled"]
try:
return integration and integration["service"]["isEnabled"]
except KeyError:
return False

def enable_integration(self, linked_account_id, provider_slug, service_slug):
"""
Expand Down Expand Up @@ -231,13 +257,21 @@ def enable_integration(self, linked_account_id, provider_slug, service_slug):
provider_slug: {service_slug: [{"linkedAccountId": linked_account_id}]}
},
)
return res["cloudConfigureIntegration"]["integrations"][0]
try:
return res["cloudConfigureIntegration"]["integrations"][0]
except (IndexError, KeyError):
if "errors" in res:
failure(
"Error while enabling integration with New Relic:\n%s"
% "\n".join([e["message"] for e in res["errors"] if "message" in e])
)
return None

def disable_integration(self, linked_account_id, provider_slug, service_slug):
"""
Disable monitoring of a Cloud provider service (integration)
"""
return self.query(
res = self.query(
"""
mutation ($accountId: Int!, $integrations: CloudIntegrationsInput!) {
cloudDisableIntegration (
Expand All @@ -261,6 +295,12 @@ def disable_integration(self, linked_account_id, provider_slug, service_slug):
provider_slug: {service_slug: [{"linkedAccountId": linked_account_id}]}
},
)
if "errors" in res:
failure(
"Error while disabling integration with New Relic:\n%s"
% "\n".join([e["message"] for e in res["errors"] if "message" in e])
)
return res


def validate_gql_credentials(nr_account_id, nr_api_key, nr_region):
Expand Down Expand Up @@ -291,18 +331,25 @@ def create_integration_account(gql, nr_account_id, linked_account_name, role):
"""
role_arn = role["Role"]["Arn"]
account = gql.get_linked_account_by_name(linked_account_name)
if account is None:
account = gql.link_account(role_arn, linked_account_name)
success(
"Cloud integrations account [%s] was created in New Relic account [%s]"
"with role [%s]." % (linked_account_name, nr_account_id, role_arn)
)
else:
if account:
success(
"Cloud integrations account [%s] already exists "
"in New Relic account [%d]." % (account["name"], nr_account_id)
)
return account
return account
account = account = gql.link_account(role_arn, linked_account_name)
if account:
success(
"Cloud integrations account [%s] was created in New Relic account [%s] "
"with role [%s]." % (linked_account_name, nr_account_id, role_arn)
)
return account
failure(
"Could not create Cloud integrations account [%s] in New Relic account [%s] "
"with role [%s]. This may be due to a previously installed integration. "
"Please contact New Relic support for assistance."
% (linked_account_name, nr_account_id, role_arn)
)


def enable_lambda_integration(gql, nr_account_id, linked_account_name):
Expand Down Expand Up @@ -334,7 +381,7 @@ def enable_lambda_integration(gql, nr_account_id, linked_account_name):
"Relic account is a Pro plan and try this command again."
)
return False
else:
if integration:
success(
"Integration [id=%s, name=%s] has been enabled in Cloud "
"integrations account [%s] of New Relic account [%d]."
Expand All @@ -346,3 +393,8 @@ def enable_lambda_integration(gql, nr_account_id, linked_account_name):
)
)
return True
failure(
"Something went wrong while enabling the New Relic AWS Lambda integration. "
"Please contact New Relic support for further assistance."
)
return False
2 changes: 2 additions & 0 deletions newrelic_lambda_cli/cli/integrations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import boto3
import click
import sys

from newrelic_lambda_cli import api, integrations, permissions
from newrelic_lambda_cli.cli.decorators import add_options, AWS_OPTIONS, NR_OPTIONS
Expand Down Expand Up @@ -82,6 +83,7 @@ def install(
done("Install Complete")
else:
failure("Install Incomplete. See messages above for details.")
sys.exit(1)


@click.command(name="uninstall")
Expand Down

0 comments on commit 7cb1160

Please sign in to comment.