Skip to content

Commit 9a0762d

Browse files
authored
Support multiple --function arguments for subscription commands (#68)
1 parent 6ca41db commit 9a0762d

File tree

5 files changed

+164
-36
lines changed

5 files changed

+164
-36
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ newrelic-lambda subscriptions install \--function <name or arn>
170170

171171
| Option | Required? | Description |
172172
|--------|-----------|-------------|
173-
| `--function` or `-f` | Yes | The AWS Lambda function name or ARN in which to add a log subscription. |
173+
| `--function` or `-f` | Yes | The AWS Lambda function name or ARN in which to add a log subscription. Can provide multiple `--function` arguments. |
174174
| `--aws-profile` or `-p` | No | The AWS profile to use for this command. Can also use `AWS_PROFILE`. Will also check `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables if not using AWS CLI. |
175175
| `--aws-region` or `-r` | No | The AWS region this function is located. Can use `AWS_DEFAULT_REGION` environment variable. Defaults to AWS session region. |
176176

@@ -182,7 +182,7 @@ newrelic-lambda subscriptions uninstall --function <name or arn>
182182

183183
| Option | Required? | Description |
184184
|--------|-----------|-------------|
185-
| `--function` or `-f` | Yes | The AWS Lambda function name or ARN in which to remove a log subscription. |
185+
| `--function` or `-f` | Yes | The AWS Lambda function name or ARN in which to remove a log subscription. Can provide multiple `--function` arguments. |
186186
| `--aws-profile` or `-p` | No | The AWS profile to use for this command. Can also use `AWS_PROFILE`. Will also check `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables if not using AWS CLI. |
187187
| `--aws-region` or `-r` | No | The AWS region this function is located. Can use `AWS_DEFAULT_REGION` environment variable. Defaults to AWS session region. |
188188

newrelic_lambda_cli/cli/layers.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,12 @@ def register(group):
3939
metavar="<arn>",
4040
multiple=True,
4141
required=True,
42-
type=click.STRING,
4342
)
4443
@click.option(
4544
"--layer-arn",
4645
"-l",
4746
help="ARN for New Relic layer (default: auto-detect)",
4847
metavar="<arn>",
49-
type=click.STRING,
5048
)
5149
@click.option(
5250
"--upgrade",
@@ -65,7 +63,7 @@ def install(
6563
layer_arn,
6664
upgrade,
6765
):
68-
"""Install New Relic AWS Lambda Layer"""
66+
"""Install New Relic AWS Lambda Layers"""
6967
session = boto3.Session(profile_name=aws_profile, region_name=aws_region)
7068

7169
if aws_permissions_check:
@@ -77,7 +75,7 @@ def install(
7775
res = layers.install(session, function, layer_arn, nr_account_id, upgrade)
7876
install_success = res and install_success
7977
if res:
80-
success("Successfully installed layer on %s" % res["FunctionArn"])
78+
success("Successfully installed layer on %s" % function)
8179
if ctx.obj["VERBOSE"]:
8280
click.echo(json.dumps(res, indent=2))
8381

@@ -97,11 +95,10 @@ def install(
9795
metavar="<arn>",
9896
multiple=True,
9997
required=True,
100-
type=click.STRING,
10198
)
10299
@click.pass_context
103100
def uninstall(ctx, aws_profile, aws_region, aws_permissions_check, functions):
104-
"""Uninstall New Relic AWS Lambda Layer"""
101+
"""Uninstall New Relic AWS Lambda Layers"""
105102
session = boto3.Session(profile_name=aws_profile, region_name=aws_region)
106103

107104
if aws_permissions_check:
@@ -113,7 +110,7 @@ def uninstall(ctx, aws_profile, aws_region, aws_permissions_check, functions):
113110
res = layers.uninstall(session, function)
114111
uninstall_success = res and uninstall_success
115112
if res:
116-
success("Successfully uninstalled layer on %s" % res["FunctionArn"])
113+
success("Successfully uninstalled layer on %s" % function)
117114
if ctx.obj["VERBOSE"]:
118115
click.echo(json.dumps(res, indent=2))
119116

newrelic_lambda_cli/cli/subscriptions.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import click
33

44
from newrelic_lambda_cli import permissions, subscriptions
5-
from newrelic_lambda_cli.cliutils import done
5+
from newrelic_lambda_cli.cliutils import done, failure, success
66
from newrelic_lambda_cli.cli.decorators import add_options, AWS_OPTIONS
77

88

@@ -21,38 +21,62 @@ def register(group):
2121
@click.command(name="install")
2222
@add_options(AWS_OPTIONS)
2323
@click.option(
24+
"functions",
2425
"--function",
2526
"-f",
2627
help="AWS Lambda function name or ARN",
2728
metavar="<arn>",
29+
multiple=True,
2830
required=True,
2931
)
30-
def install(aws_profile, aws_region, aws_permissions_check, function):
31-
"""Install New Relic AWS Lambda Log Subscription"""
32+
def install(aws_profile, aws_region, aws_permissions_check, functions):
33+
"""Install New Relic AWS Lambda Log Subscriptions"""
3234
session = boto3.Session(profile_name=aws_profile, region_name=aws_region)
3335

3436
if aws_permissions_check:
3537
permissions.ensure_subscription_install_permissions(session)
3638

37-
subscriptions.create_log_subscription(session, function)
38-
done("Install Complete")
39+
install_success = True
40+
41+
for function in functions:
42+
result = subscriptions.create_log_subscription(session, function)
43+
install_success = result and install_success
44+
if result:
45+
success("Successfully installed log subscription on %s" % function)
46+
47+
if install_success:
48+
done("Install Complete")
49+
else:
50+
failure("Install Incomplete. See messages above for details.", exit=True)
3951

4052

4153
@click.command(name="uninstall")
4254
@add_options(AWS_OPTIONS)
4355
@click.option(
56+
"functions",
4457
"--function",
4558
"-f",
4659
help="Lambda function name or ARN",
4760
metavar="<arn>",
61+
multiple=True,
4862
required=True,
4963
)
50-
def uninstall(aws_profile, aws_region, aws_permissions_check, function):
51-
"""Uninstall New Relic AWS Lambda Log Subscription"""
64+
def uninstall(aws_profile, aws_region, aws_permissions_check, functions):
65+
"""Uninstall New Relic AWS Lambda Log Subscriptions"""
5266
session = boto3.Session(profile_name=aws_profile, region_name=aws_region)
5367

5468
if aws_permissions_check:
5569
permissions.ensure_subscription_uninstall_permissions(session)
5670

57-
subscriptions.remove_log_subscription(session, function)
58-
done("Uninstall Complete")
71+
uninstall_success = True
72+
73+
for function in functions:
74+
result = subscriptions.remove_log_subscription(session, function)
75+
uninstall_success = result and uninstall_success
76+
if result:
77+
success("Successfully uninstalled log subscription on %s" % function)
78+
79+
if uninstall_success:
80+
done("Uninstall Complete")
81+
else:
82+
failure("Uninstall Incomplete. See messages above for details.", exit=True)

newrelic_lambda_cli/subscriptions.py

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,44 @@ def get_subscription_filters(session, function_name):
2222
and e.response["ResponseMetadata"]["HTTPStatusCode"] == 404
2323
):
2424
return []
25-
raise click.UsageError(str(e))
25+
failure(
26+
"Error retrieving log subscription filters for '%s': %s"
27+
% (function_name, e)
28+
)
2629
else:
2730
return res.get("subscriptionFilters", [])
2831

2932

3033
def create_subscription_filter(session, function_name, destination_arn):
3134
try:
32-
return session.client("logs").put_subscription_filter(
35+
session.client("logs").put_subscription_filter(
3336
logGroupName="/aws/lambda/%s" % function_name,
3437
filterName="NewRelicLogStreaming",
3538
filterPattern=DEFAULT_FILTER_PATTERN,
3639
destinationArn=destination_arn,
3740
)
3841
except botocore.exceptions.ClientError as e:
39-
raise click.UsageError(str(e))
42+
failure(
43+
"Error creating log subscription filter for '%s': %s" % (function_name, e)
44+
)
45+
return False
46+
else:
47+
return True
4048

4149

4250
def remove_subscription_filter(session, function_name):
4351
try:
44-
return session.client("logs").delete_subscription_filter(
52+
session.client("logs").delete_subscription_filter(
4553
logGroupName="/aws/lambda/%s" % function_name,
4654
filterName="NewRelicLogStreaming",
4755
)
4856
except botocore.exceptions.ClientError as e:
49-
raise click.UsageError(str(e))
57+
failure(
58+
"Error removing log subscription filter for '%s': %s" % (function_name, e)
59+
)
60+
return False
61+
else:
62+
return True
5063

5164

5265
def create_log_subscription(session, function_name):
@@ -56,11 +69,11 @@ def create_log_subscription(session, function_name):
5669
"Could not find 'newrelic-log-ingestion' function. Is the New Relic AWS "
5770
"integration installed?"
5871
)
59-
return
72+
return False
6073
destination_arn = destination["Configuration"]["FunctionArn"]
61-
subscription_filters = [
62-
filter for filter in get_subscription_filters(session, function_name)
63-
]
74+
subscription_filters = get_subscription_filters(session, function_name)
75+
if subscription_filters is None:
76+
return False
6477
newrelic_filters = [
6578
filter
6679
for filter in subscription_filters
@@ -79,27 +92,31 @@ def create_log_subscription(session, function_name):
7992
)
8093
if not newrelic_filters:
8194
click.echo("Adding New Relic log subscription to '%s'" % function_name)
82-
create_subscription_filter(session, function_name, destination_arn)
95+
return create_subscription_filter(session, function_name, destination_arn)
8396
else:
8497
click.echo(
8598
"Found log subscription for '%s', verifying configuration" % function_name
8699
)
87100
newrelic_filter = newrelic_filters[0]
88-
if newrelic_filter["filterPattern"] == "":
89-
remove_subscription_filter(session, function_name)
90-
create_subscription_filter(session, function_name, destination_arn)
101+
if newrelic_filter["filterPattern"] != DEFAULT_FILTER_PATTERN:
102+
return remove_subscription_filter(
103+
session, function_name
104+
) and create_subscription_filter(session, function_name, destination_arn)
91105

92106

93107
def remove_log_subscription(session, function_name):
94-
subscription_filters = [
108+
subscription_filters = get_subscription_filters(session, function_name)
109+
if subscription_filters is None:
110+
return False
111+
newrelic_filters = [
95112
filter
96-
for filter in get_subscription_filters(session, function_name)
113+
for filter in subscription_filters
97114
if filter["filterName"] == "NewRelicLogStreaming"
98115
]
99-
if not subscription_filters:
116+
if not newrelic_filters:
100117
click.echo(
101118
"No New Relic subscription filters found for '%s', skipping" % function_name
102119
)
103-
return
120+
return False
104121
click.echo("Removing New Relic log subscription from '%s'" % function_name)
105-
remove_subscription_filter(session, function_name)
122+
return remove_subscription_filter(session, function_name)

tests/cli/test_subscriptions.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from moto import mock_lambda, mock_logs
2+
3+
from newrelic_lambda_cli.cli import cli, register_groups
4+
5+
6+
@mock_lambda
7+
@mock_logs
8+
def test_subscriptions_install(aws_credentials, cli_runner):
9+
"""
10+
Assert that 'newrelic-lambda subscriptions install' attempts to install the
11+
New Relic log subscription on a function.
12+
"""
13+
register_groups(cli)
14+
15+
result = cli_runner.invoke(
16+
cli,
17+
[
18+
"subscriptions",
19+
"install",
20+
"--no-aws-permissions-check",
21+
"--function",
22+
"foobar",
23+
],
24+
env={"AWS_DEFAULT_REGION": "us-east-1"},
25+
)
26+
27+
assert result.exit_code == 1
28+
assert result.stdout == ""
29+
assert "✖️ Install Incomplete. See messages above for details." in result.stderr
30+
31+
result2 = cli_runner.invoke(
32+
cli,
33+
[
34+
"subscriptions",
35+
"install",
36+
"--no-aws-permissions-check",
37+
"--function",
38+
"foobar",
39+
"--function",
40+
"barbaz",
41+
],
42+
env={"AWS_DEFAULT_REGION": "us-east-1"},
43+
)
44+
45+
assert result2.exit_code == 1
46+
assert result2.stdout == ""
47+
assert "✖️ Install Incomplete. See messages above for details." in result2.stderr
48+
49+
50+
@mock_lambda
51+
def test_subscriptions_uninstall(aws_credentials, cli_runner):
52+
"""
53+
Assert that 'newrelic-lambda subscriptions uninstall' attempts to uninstall the
54+
New Relic log subscription on a function.
55+
"""
56+
register_groups(cli)
57+
58+
result = cli_runner.invoke(
59+
cli,
60+
[
61+
"subscriptions",
62+
"uninstall",
63+
"--no-aws-permissions-check",
64+
"--function",
65+
"foobar",
66+
],
67+
env={"AWS_DEFAULT_REGION": "us-east-1"},
68+
)
69+
70+
assert result.exit_code == 1
71+
assert result.stdout == ""
72+
assert "✖️ Uninstall Incomplete. See messages above for details." in result.stderr
73+
74+
result2 = cli_runner.invoke(
75+
cli,
76+
[
77+
"subscriptions",
78+
"uninstall",
79+
"--no-aws-permissions-check",
80+
"--function",
81+
"foobar",
82+
"--function",
83+
"barbaz",
84+
],
85+
env={"AWS_DEFAULT_REGION": "us-east-1"},
86+
)
87+
88+
assert result2.exit_code == 1
89+
assert result2.stdout == ""
90+
assert "✖️ Uninstall Incomplete. See messages above for details." in result2.stderr

0 commit comments

Comments
 (0)