newrelic-lambda-cli 0.9.1__py2.py3-none-any.whl → 0.9.3__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- newrelic_lambda_cli/api.py +14 -1
- newrelic_lambda_cli/cli/__init__.py +8 -1
- newrelic_lambda_cli/cli/layers.py +10 -2
- newrelic_lambda_cli/cli/otel_ingestions.py +219 -0
- newrelic_lambda_cli/cli/subscriptions.py +82 -34
- newrelic_lambda_cli/integrations.py +34 -21
- newrelic_lambda_cli/layers.py +12 -0
- newrelic_lambda_cli/otel_ingestions.py +276 -0
- newrelic_lambda_cli/subscriptions.py +91 -2
- newrelic_lambda_cli/types.py +51 -1
- newrelic_lambda_cli/utils.py +2 -0
- {newrelic_lambda_cli-0.9.1.dist-info → newrelic_lambda_cli-0.9.3.dist-info}/METADATA +78 -6
- newrelic_lambda_cli-0.9.3.dist-info/RECORD +27 -0
- {newrelic_lambda_cli-0.9.1.dist-info → newrelic_lambda_cli-0.9.3.dist-info}/WHEEL +1 -1
- newrelic_lambda_cli-0.9.1.dist-info/RECORD +0 -25
- {newrelic_lambda_cli-0.9.1.dist-info → newrelic_lambda_cli-0.9.3.dist-info}/LICENSE +0 -0
- {newrelic_lambda_cli-0.9.1.dist-info → newrelic_lambda_cli-0.9.3.dist-info}/entry_points.txt +0 -0
- {newrelic_lambda_cli-0.9.1.dist-info → newrelic_lambda_cli-0.9.3.dist-info}/top_level.txt +0 -0
newrelic_lambda_cli/api.py
CHANGED
|
@@ -21,6 +21,9 @@ from newrelic_lambda_cli.types import (
|
|
|
21
21
|
IntegrationInstall,
|
|
22
22
|
IntegrationUpdate,
|
|
23
23
|
LayerInstall,
|
|
24
|
+
OtelIngestionInstall,
|
|
25
|
+
OtelIngestionUninstall,
|
|
26
|
+
OtelIngestionUpdate,
|
|
24
27
|
)
|
|
25
28
|
from newrelic_lambda_cli.utils import parse_arn
|
|
26
29
|
|
|
@@ -333,7 +336,17 @@ class NewRelicGQL(object):
|
|
|
333
336
|
|
|
334
337
|
|
|
335
338
|
def validate_gql_credentials(input):
|
|
336
|
-
|
|
339
|
+
|
|
340
|
+
assert isinstance(
|
|
341
|
+
input,
|
|
342
|
+
(
|
|
343
|
+
IntegrationInstall,
|
|
344
|
+
IntegrationUpdate,
|
|
345
|
+
LayerInstall,
|
|
346
|
+
OtelIngestionInstall,
|
|
347
|
+
OtelIngestionUpdate,
|
|
348
|
+
),
|
|
349
|
+
)
|
|
337
350
|
|
|
338
351
|
try:
|
|
339
352
|
return NewRelicGQL(input.nr_account_id, input.nr_api_key, input.nr_region)
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
4
|
|
|
5
|
-
from newrelic_lambda_cli.cli import
|
|
5
|
+
from newrelic_lambda_cli.cli import (
|
|
6
|
+
functions,
|
|
7
|
+
integrations,
|
|
8
|
+
layers,
|
|
9
|
+
otel_ingestions,
|
|
10
|
+
subscriptions,
|
|
11
|
+
)
|
|
6
12
|
|
|
7
13
|
|
|
8
14
|
@click.group()
|
|
@@ -17,6 +23,7 @@ def cli(ctx, verbose):
|
|
|
17
23
|
def register_groups(group):
|
|
18
24
|
functions.register(group)
|
|
19
25
|
integrations.register(group)
|
|
26
|
+
otel_ingestions.register(group)
|
|
20
27
|
layers.register(group)
|
|
21
28
|
subscriptions.register(group)
|
|
22
29
|
|
|
@@ -107,7 +107,11 @@ def register(group):
|
|
|
107
107
|
def install(ctx, **kwargs):
|
|
108
108
|
"""Install New Relic AWS Lambda Layers"""
|
|
109
109
|
input = LayerInstall(session=None, verbose=ctx.obj["VERBOSE"], **kwargs)
|
|
110
|
-
|
|
110
|
+
input = input._replace(
|
|
111
|
+
session=boto3.Session(
|
|
112
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
113
|
+
)
|
|
114
|
+
)
|
|
111
115
|
if input.aws_permissions_check:
|
|
112
116
|
permissions.ensure_layer_install_permissions(input)
|
|
113
117
|
|
|
@@ -181,7 +185,11 @@ def install(ctx, **kwargs):
|
|
|
181
185
|
def uninstall(ctx, **kwargs):
|
|
182
186
|
"""Uninstall New Relic AWS Lambda Layers"""
|
|
183
187
|
input = LayerUninstall(session=None, verbose=ctx.obj["VERBOSE"], **kwargs)
|
|
184
|
-
|
|
188
|
+
input = input._replace(
|
|
189
|
+
session=boto3.Session(
|
|
190
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
191
|
+
)
|
|
192
|
+
)
|
|
185
193
|
if input.aws_permissions_check:
|
|
186
194
|
permissions.ensure_layer_uninstall_permissions(input)
|
|
187
195
|
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import boto3
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from newrelic_lambda_cli import api, otel_ingestions, permissions, integrations
|
|
7
|
+
from newrelic_lambda_cli.types import (
|
|
8
|
+
OtelIngestionInstall,
|
|
9
|
+
OtelIngestionUninstall,
|
|
10
|
+
OtelIngestionUpdate,
|
|
11
|
+
)
|
|
12
|
+
from newrelic_lambda_cli.cli.decorators import add_options, AWS_OPTIONS, NR_OPTIONS
|
|
13
|
+
from newrelic_lambda_cli.cliutils import done, failure
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@click.group(name="otel-ingestions")
|
|
17
|
+
def ingestion_group():
|
|
18
|
+
"""Manage New Relic AWS Lambda Otel Log Ingestion lambda"""
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def register(group):
|
|
23
|
+
group.add_command(ingestion_group)
|
|
24
|
+
ingestion_group.add_command(install)
|
|
25
|
+
ingestion_group.add_command(uninstall)
|
|
26
|
+
ingestion_group.add_command(update)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@click.command(name="install")
|
|
30
|
+
@add_options(AWS_OPTIONS)
|
|
31
|
+
@click.option(
|
|
32
|
+
"--aws-role-policy",
|
|
33
|
+
help="Alternative AWS role policy to use for integration",
|
|
34
|
+
metavar="<arn>",
|
|
35
|
+
)
|
|
36
|
+
@click.option(
|
|
37
|
+
"--stackname",
|
|
38
|
+
default=otel_ingestions.OTEL_INGEST_STACK_NAME,
|
|
39
|
+
help=f"The AWS Cloudformation stack name which contains the {otel_ingestions.OTEL_INGEST_LAMBDA_NAME} lambda function",
|
|
40
|
+
metavar="<arn>",
|
|
41
|
+
show_default=False,
|
|
42
|
+
required=False,
|
|
43
|
+
)
|
|
44
|
+
@click.option(
|
|
45
|
+
"--memory-size",
|
|
46
|
+
"-m",
|
|
47
|
+
default=128,
|
|
48
|
+
help="Memory size (in MiB) for the log ingestion function",
|
|
49
|
+
metavar="<size>",
|
|
50
|
+
show_default=True,
|
|
51
|
+
type=click.INT,
|
|
52
|
+
)
|
|
53
|
+
@add_options(NR_OPTIONS)
|
|
54
|
+
@click.option(
|
|
55
|
+
"--timeout",
|
|
56
|
+
"-t",
|
|
57
|
+
default=30,
|
|
58
|
+
help="Timeout (in seconds) for the New Relic log ingestion function",
|
|
59
|
+
metavar="<secs>",
|
|
60
|
+
show_default=True,
|
|
61
|
+
type=click.INT,
|
|
62
|
+
)
|
|
63
|
+
@click.option(
|
|
64
|
+
"--role-name",
|
|
65
|
+
default=None,
|
|
66
|
+
help="The name of a pre-created execution role for the log ingest function",
|
|
67
|
+
metavar="<role_name>",
|
|
68
|
+
show_default=False,
|
|
69
|
+
)
|
|
70
|
+
@click.option(
|
|
71
|
+
"--tag",
|
|
72
|
+
"tags",
|
|
73
|
+
default=[],
|
|
74
|
+
help="A tag to be added to the CloudFormation Stack (can be used multiple times)",
|
|
75
|
+
metavar="<key> <value>",
|
|
76
|
+
multiple=True,
|
|
77
|
+
nargs=2,
|
|
78
|
+
)
|
|
79
|
+
@click.pass_context
|
|
80
|
+
def install(ctx, **kwargs):
|
|
81
|
+
"""Install New Relic AWS OTEL Ingestion Lambda"""
|
|
82
|
+
input = OtelIngestionInstall(session=None, verbose=ctx.obj["VERBOSE"], **kwargs)
|
|
83
|
+
|
|
84
|
+
input = input._replace(
|
|
85
|
+
session=boto3.Session(
|
|
86
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if input.aws_permissions_check:
|
|
91
|
+
permissions.ensure_integration_install_permissions(input)
|
|
92
|
+
|
|
93
|
+
click.echo("Validating New Relic credentials")
|
|
94
|
+
gql_client = api.validate_gql_credentials(input)
|
|
95
|
+
|
|
96
|
+
click.echo("Retrieving integration license key")
|
|
97
|
+
nr_license_key = api.retrieve_license_key(gql_client)
|
|
98
|
+
|
|
99
|
+
install_success = True
|
|
100
|
+
|
|
101
|
+
click.echo(
|
|
102
|
+
f"Creating {otel_ingestions.OTEL_INGEST_LAMBDA_NAME} Lambda function in AWS account"
|
|
103
|
+
)
|
|
104
|
+
res = otel_ingestions.install_otel_log_ingestion(input, nr_license_key)
|
|
105
|
+
install_success = res and install_success
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@click.command(name="uninstall")
|
|
109
|
+
@add_options(AWS_OPTIONS)
|
|
110
|
+
@click.option(
|
|
111
|
+
"--nr-account-id",
|
|
112
|
+
"-a",
|
|
113
|
+
envvar="NEW_RELIC_ACCOUNT_ID",
|
|
114
|
+
help="New Relic Account ID",
|
|
115
|
+
metavar="<id>",
|
|
116
|
+
required=False,
|
|
117
|
+
type=click.INT,
|
|
118
|
+
)
|
|
119
|
+
@click.option(
|
|
120
|
+
"--stackname",
|
|
121
|
+
default=otel_ingestions.OTEL_INGEST_STACK_NAME,
|
|
122
|
+
help=f"The AWS Cloudformation stack name which contains the {otel_ingestions.OTEL_INGEST_LAMBDA_NAME} lambda function",
|
|
123
|
+
metavar="<arn>",
|
|
124
|
+
show_default=False,
|
|
125
|
+
required=False,
|
|
126
|
+
)
|
|
127
|
+
@click.option("--force", "-f", help="Force uninstall non-interactively", is_flag=True)
|
|
128
|
+
def uninstall(**kwargs):
|
|
129
|
+
"""Uninstall New Relic AWS OTEL Ingestion Lambda"""
|
|
130
|
+
input = OtelIngestionUninstall(session=None, **kwargs)
|
|
131
|
+
|
|
132
|
+
input = input._replace(
|
|
133
|
+
session=boto3.Session(
|
|
134
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
if input.aws_permissions_check:
|
|
139
|
+
permissions.ensure_integration_uninstall_permissions(input)
|
|
140
|
+
|
|
141
|
+
integrations.remove_log_ingestion_function(input, otel=True)
|
|
142
|
+
|
|
143
|
+
done("Uninstall Complete")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@click.command(name="update")
|
|
147
|
+
@add_options(AWS_OPTIONS)
|
|
148
|
+
@click.option(
|
|
149
|
+
"--stackname",
|
|
150
|
+
default=otel_ingestions.OTEL_INGEST_STACK_NAME,
|
|
151
|
+
help=f"The AWS Cloudformation stack name which contains the {otel_ingestions.OTEL_INGEST_LAMBDA_NAME} lambda function",
|
|
152
|
+
metavar="<arn>",
|
|
153
|
+
show_default=False,
|
|
154
|
+
required=False,
|
|
155
|
+
)
|
|
156
|
+
@click.option(
|
|
157
|
+
"--memory-size",
|
|
158
|
+
"-m",
|
|
159
|
+
help="Memory size (in MiB) for the log ingestion function",
|
|
160
|
+
metavar="<size>",
|
|
161
|
+
type=click.INT,
|
|
162
|
+
)
|
|
163
|
+
@add_options(NR_OPTIONS)
|
|
164
|
+
@click.option(
|
|
165
|
+
"--timeout",
|
|
166
|
+
"-t",
|
|
167
|
+
help="Timeout (in seconds) for the New Relic log ingestion function",
|
|
168
|
+
metavar="<secs>",
|
|
169
|
+
type=click.INT,
|
|
170
|
+
)
|
|
171
|
+
@click.option(
|
|
172
|
+
"--role-name",
|
|
173
|
+
default=None,
|
|
174
|
+
help="The name of a new pre-created execution role for the log ingest function",
|
|
175
|
+
metavar="<role_name>",
|
|
176
|
+
show_default=False,
|
|
177
|
+
)
|
|
178
|
+
@click.option(
|
|
179
|
+
"--stackname",
|
|
180
|
+
default="NewRelicOtelLogIngestion",
|
|
181
|
+
help="The AWS Cloudformation stack name which contains the newrelic-log-ingestion lambda function",
|
|
182
|
+
metavar="<arn>",
|
|
183
|
+
show_default=False,
|
|
184
|
+
required=False,
|
|
185
|
+
)
|
|
186
|
+
@click.option(
|
|
187
|
+
"--tag",
|
|
188
|
+
"tags",
|
|
189
|
+
default=[],
|
|
190
|
+
help="A tag to be added to the CloudFormation Stack (can be used multiple times)",
|
|
191
|
+
metavar="<key> <value>",
|
|
192
|
+
multiple=True,
|
|
193
|
+
nargs=2,
|
|
194
|
+
)
|
|
195
|
+
def update(**kwargs):
|
|
196
|
+
"""UpdateNew New Relic AWS OTEL Ingestion Lambda"""
|
|
197
|
+
input = OtelIngestionUpdate(session=None, **kwargs)
|
|
198
|
+
|
|
199
|
+
input = input._replace(
|
|
200
|
+
session=boto3.Session(
|
|
201
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
if input.aws_permissions_check:
|
|
206
|
+
permissions.ensure_integration_install_permissions(input)
|
|
207
|
+
|
|
208
|
+
update_success = True
|
|
209
|
+
|
|
210
|
+
click.echo(
|
|
211
|
+
f"Updating {otel_ingestions.OTEL_INGEST_LAMBDA_NAME} Lambda function in AWS account"
|
|
212
|
+
)
|
|
213
|
+
res = otel_ingestions.update_otel_log_ingestion(input)
|
|
214
|
+
update_success = res and update_success
|
|
215
|
+
|
|
216
|
+
if update_success:
|
|
217
|
+
done("Update Complete")
|
|
218
|
+
else:
|
|
219
|
+
failure("Update Incomplete. See messages above for details.", exit=True)
|
|
@@ -61,28 +61,60 @@ def register(group):
|
|
|
61
61
|
metavar="<pattern>",
|
|
62
62
|
show_default=False,
|
|
63
63
|
)
|
|
64
|
+
@click.option(
|
|
65
|
+
"--otel",
|
|
66
|
+
"-o",
|
|
67
|
+
help="Subscribe to OTEL log ingestion function",
|
|
68
|
+
is_flag=True,
|
|
69
|
+
)
|
|
64
70
|
def install(**kwargs):
|
|
65
71
|
"""Install New Relic AWS Lambda Log Subscriptions"""
|
|
66
72
|
input = SubscriptionInstall(session=None, **kwargs)
|
|
67
|
-
|
|
73
|
+
if input.otel and input.filter_pattern == DEFAULT_FILTER_PATTERN:
|
|
74
|
+
input = input._replace(
|
|
75
|
+
filter_pattern="",
|
|
76
|
+
)
|
|
77
|
+
if input.otel and input.stackname == "NewRelicLogIngestion":
|
|
78
|
+
input = input._replace(
|
|
79
|
+
stackname="NewRelicOtelLogIngestion",
|
|
80
|
+
)
|
|
81
|
+
input = input._replace(
|
|
82
|
+
session=boto3.Session(
|
|
83
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
84
|
+
)
|
|
85
|
+
)
|
|
68
86
|
if input.aws_permissions_check:
|
|
69
87
|
permissions.ensure_subscription_install_permissions(input)
|
|
70
88
|
|
|
71
89
|
functions = get_aliased_functions(input)
|
|
72
90
|
|
|
73
91
|
with ThreadPoolExecutor() as executor:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
92
|
+
if input.otel:
|
|
93
|
+
futures = [
|
|
94
|
+
executor.submit(
|
|
95
|
+
subscriptions.create_otel_log_subscription,
|
|
96
|
+
input._replace(
|
|
97
|
+
session=boto3.Session(
|
|
98
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
99
|
+
)
|
|
100
|
+
),
|
|
101
|
+
function,
|
|
102
|
+
)
|
|
103
|
+
for function in functions
|
|
104
|
+
]
|
|
105
|
+
else:
|
|
106
|
+
futures = [
|
|
107
|
+
executor.submit(
|
|
108
|
+
subscriptions.create_log_subscription,
|
|
109
|
+
input._replace(
|
|
110
|
+
session=boto3.Session(
|
|
111
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
112
|
+
)
|
|
113
|
+
),
|
|
114
|
+
function,
|
|
115
|
+
)
|
|
116
|
+
for function in functions
|
|
117
|
+
]
|
|
86
118
|
install_success = all(future.result() for future in as_completed(futures))
|
|
87
119
|
|
|
88
120
|
if install_success:
|
|
@@ -102,14 +134,6 @@ def install(**kwargs):
|
|
|
102
134
|
multiple=True,
|
|
103
135
|
required=True,
|
|
104
136
|
)
|
|
105
|
-
@click.option(
|
|
106
|
-
"--stackname",
|
|
107
|
-
default="NewRelicLogIngestion",
|
|
108
|
-
help="The AWS Cloudformation stack name which contains the newrelic-log-ingestion lambda function",
|
|
109
|
-
metavar="<arn>",
|
|
110
|
-
show_default=False,
|
|
111
|
-
required=False,
|
|
112
|
-
)
|
|
113
137
|
@click.option(
|
|
114
138
|
"excludes",
|
|
115
139
|
"--exclude",
|
|
@@ -118,28 +142,52 @@ def install(**kwargs):
|
|
|
118
142
|
metavar="<name>",
|
|
119
143
|
multiple=True,
|
|
120
144
|
)
|
|
145
|
+
@click.option(
|
|
146
|
+
"--otel",
|
|
147
|
+
"-o",
|
|
148
|
+
help="Subscribe to OTEL log ingestion function",
|
|
149
|
+
is_flag=True,
|
|
150
|
+
)
|
|
121
151
|
def uninstall(**kwargs):
|
|
122
152
|
"""Uninstall New Relic AWS Lambda Log Subscriptions"""
|
|
123
153
|
input = SubscriptionUninstall(session=None, **kwargs)
|
|
124
|
-
|
|
154
|
+
input = input._replace(
|
|
155
|
+
session=boto3.Session(
|
|
156
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
157
|
+
)
|
|
158
|
+
)
|
|
125
159
|
if input.aws_permissions_check:
|
|
126
160
|
permissions.ensure_subscription_uninstall_permissions(input)
|
|
127
161
|
|
|
128
162
|
functions = get_aliased_functions(input)
|
|
129
163
|
|
|
130
164
|
with ThreadPoolExecutor() as executor:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
165
|
+
if input.otel:
|
|
166
|
+
futures = [
|
|
167
|
+
executor.submit(
|
|
168
|
+
subscriptions.remove_otel_log_subscription,
|
|
169
|
+
input._replace(
|
|
170
|
+
session=boto3.Session(
|
|
171
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
172
|
+
)
|
|
173
|
+
),
|
|
174
|
+
function,
|
|
175
|
+
)
|
|
176
|
+
for function in functions
|
|
177
|
+
]
|
|
178
|
+
else:
|
|
179
|
+
futures = [
|
|
180
|
+
executor.submit(
|
|
181
|
+
subscriptions.remove_log_subscription,
|
|
182
|
+
input._replace(
|
|
183
|
+
session=boto3.Session(
|
|
184
|
+
profile_name=input.aws_profile, region_name=input.aws_region
|
|
185
|
+
)
|
|
186
|
+
),
|
|
187
|
+
function,
|
|
188
|
+
)
|
|
189
|
+
for function in functions
|
|
190
|
+
]
|
|
143
191
|
uninstall_success = all(future.result() for future in as_completed(futures))
|
|
144
192
|
|
|
145
193
|
if uninstall_success:
|
|
@@ -14,6 +14,7 @@ from newrelic_lambda_cli.types import (
|
|
|
14
14
|
IntegrationInstall,
|
|
15
15
|
IntegrationUninstall,
|
|
16
16
|
IntegrationUpdate,
|
|
17
|
+
OtelIngestionUninstall,
|
|
17
18
|
)
|
|
18
19
|
from newrelic_lambda_cli.utils import catch_boto_errors, NR_DOCS_ACT_LINKING_URL
|
|
19
20
|
|
|
@@ -165,9 +166,11 @@ def _create_role(input):
|
|
|
165
166
|
{"ParameterKey": "PolicyName", "ParameterValue": role_policy_name},
|
|
166
167
|
],
|
|
167
168
|
Capabilities=["CAPABILITY_NAMED_IAM"],
|
|
168
|
-
Tags=
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
Tags=(
|
|
170
|
+
[{"Key": key, "Value": value} for key, value in input.tags]
|
|
171
|
+
if input.tags
|
|
172
|
+
else []
|
|
173
|
+
),
|
|
171
174
|
)
|
|
172
175
|
|
|
173
176
|
click.echo("Waiting for stack creation to complete... ", nl=False)
|
|
@@ -268,9 +271,11 @@ def _import_log_ingestion_function(input, nr_license_key):
|
|
|
268
271
|
TemplateBody=template.read(),
|
|
269
272
|
Parameters=parameters,
|
|
270
273
|
Capabilities=capabilities,
|
|
271
|
-
Tags=
|
|
272
|
-
|
|
273
|
-
|
|
274
|
+
Tags=(
|
|
275
|
+
[{"Key": key, "Value": value} for key, value in input.tags]
|
|
276
|
+
if input.tags
|
|
277
|
+
else []
|
|
278
|
+
),
|
|
274
279
|
ChangeSetType="IMPORT",
|
|
275
280
|
ChangeSetName=change_set_name,
|
|
276
281
|
ResourcesToImport=[
|
|
@@ -311,9 +316,11 @@ def _create_log_ingestion_function(
|
|
|
311
316
|
TemplateURL=template_url,
|
|
312
317
|
Parameters=parameters,
|
|
313
318
|
Capabilities=capabilities,
|
|
314
|
-
Tags=
|
|
315
|
-
|
|
316
|
-
|
|
319
|
+
Tags=(
|
|
320
|
+
[{"Key": key, "Value": value} for key, value in input.tags]
|
|
321
|
+
if input.tags
|
|
322
|
+
else []
|
|
323
|
+
),
|
|
317
324
|
ChangeSetType=mode,
|
|
318
325
|
ChangeSetName=change_set_name,
|
|
319
326
|
)
|
|
@@ -444,9 +451,11 @@ def update_log_ingestion_function(input):
|
|
|
444
451
|
TemplateBody=json.dumps(template_body),
|
|
445
452
|
Parameters=params,
|
|
446
453
|
Capabilities=["CAPABILITY_IAM"],
|
|
447
|
-
Tags=
|
|
448
|
-
|
|
449
|
-
|
|
454
|
+
Tags=(
|
|
455
|
+
[{"Key": key, "Value": value} for key, value in input.tags]
|
|
456
|
+
if input.tags
|
|
457
|
+
else []
|
|
458
|
+
),
|
|
450
459
|
)
|
|
451
460
|
|
|
452
461
|
try:
|
|
@@ -496,18 +505,20 @@ def update_log_ingestion_function(input):
|
|
|
496
505
|
|
|
497
506
|
|
|
498
507
|
@catch_boto_errors
|
|
499
|
-
def remove_log_ingestion_function(input):
|
|
500
|
-
assert isinstance(input, IntegrationUninstall)
|
|
501
|
-
|
|
508
|
+
def remove_log_ingestion_function(input, otel: bool = False):
|
|
509
|
+
assert isinstance(input, (IntegrationUninstall, OtelIngestionUninstall))
|
|
510
|
+
log_ingestion_lambda = "log ingestion" if not otel else "OTEL log ingestion"
|
|
502
511
|
client = input.session.client("cloudformation")
|
|
503
512
|
stack_status = _check_for_ingest_stack(input.session, input.stackname)
|
|
504
513
|
if stack_status is None:
|
|
505
514
|
click.echo(
|
|
506
|
-
"No New Relic AWS Lambda
|
|
507
|
-
% input.session.region_name
|
|
515
|
+
"No New Relic AWS Lambda %s found in region %s, skipping"
|
|
516
|
+
% (log_ingestion_lambda, input.session.region_name)
|
|
508
517
|
)
|
|
509
518
|
return
|
|
510
|
-
click.echo(
|
|
519
|
+
click.echo(
|
|
520
|
+
"Deleting New Relic %s stack '%s'" % (log_ingestion_lambda, input.stackname)
|
|
521
|
+
)
|
|
511
522
|
client.delete_stack(StackName=input.stackname)
|
|
512
523
|
click.echo(
|
|
513
524
|
"Waiting for stack deletion to complete, this may take a minute... ", nl=False
|
|
@@ -755,9 +766,11 @@ def install_license_key(input, nr_license_key, policy_name=None):
|
|
|
755
766
|
TemplateBody=template.read(),
|
|
756
767
|
Parameters=parameters,
|
|
757
768
|
Capabilities=["CAPABILITY_NAMED_IAM"],
|
|
758
|
-
Tags=
|
|
759
|
-
|
|
760
|
-
|
|
769
|
+
Tags=(
|
|
770
|
+
[{"Key": key, "Value": value} for key, value in input.tags]
|
|
771
|
+
if input.tags
|
|
772
|
+
else []
|
|
773
|
+
),
|
|
761
774
|
ChangeSetType=mode,
|
|
762
775
|
ChangeSetName=change_set_name,
|
|
763
776
|
)
|
newrelic_lambda_cli/layers.py
CHANGED
|
@@ -202,6 +202,18 @@ def _add_new_relic(input, config, nr_license_key):
|
|
|
202
202
|
"NEW_RELIC_LAMBDA_EXTENSION_ENABLED"
|
|
203
203
|
] = "false"
|
|
204
204
|
|
|
205
|
+
if "dotnet" in runtime:
|
|
206
|
+
update_kwargs["Environment"]["Variables"]["CORECLR_ENABLE_PROFILING"] = "1"
|
|
207
|
+
update_kwargs["Environment"]["Variables"][
|
|
208
|
+
"CORECLR_PROFILER"
|
|
209
|
+
] = "{36032161-FFC0-4B61-B559-F6C5D41BAE5A}"
|
|
210
|
+
update_kwargs["Environment"]["Variables"][
|
|
211
|
+
"CORECLR_NEWRELIC_HOME"
|
|
212
|
+
] = "/opt/lib/newrelic-dotnet-agent"
|
|
213
|
+
update_kwargs["Environment"]["Variables"][
|
|
214
|
+
"CORECLR_PROFILER_PATH"
|
|
215
|
+
] = "/opt/lib/newrelic-dotnet-agent/libNewRelicProfiler.so"
|
|
216
|
+
|
|
205
217
|
return update_kwargs
|
|
206
218
|
|
|
207
219
|
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
import botocore
|
|
8
|
+
import click
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
from newrelic_lambda_cli.cliutils import failure, success, warning
|
|
12
|
+
from newrelic_lambda_cli.functions import get_function
|
|
13
|
+
from newrelic_lambda_cli.integrations import _exec_change_set
|
|
14
|
+
from newrelic_lambda_cli.types import (
|
|
15
|
+
OtelIngestionInstall,
|
|
16
|
+
OtelIngestionUpdate,
|
|
17
|
+
)
|
|
18
|
+
from newrelic_lambda_cli.utils import catch_boto_errors, NR_DOCS_ACT_LINKING_URL
|
|
19
|
+
|
|
20
|
+
OTEL_INGEST_STACK_NAME = "NewRelicOtelLogIngestion"
|
|
21
|
+
OTEL_INGEST_LAMBDA_NAME = "newrelic-aws-otel-log-ingestion"
|
|
22
|
+
OTEL_SAR_APP_ID = (
|
|
23
|
+
"arn:aws:serverlessrepo:us-east-1:451483290750:applications/"
|
|
24
|
+
+ OTEL_INGEST_LAMBDA_NAME
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _check_for_ingest_stack(session, stack_name):
|
|
29
|
+
return _get_cf_stack_status(session, stack_name)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _get_cf_stack_status(session, stack_name, nr_account_id=None):
|
|
33
|
+
"""Returns the status of the CloudFormation stack if it exists"""
|
|
34
|
+
try:
|
|
35
|
+
res = session.client("cloudformation").describe_stacks(StackName=stack_name)
|
|
36
|
+
except botocore.exceptions.ClientError as e:
|
|
37
|
+
if (
|
|
38
|
+
e.response
|
|
39
|
+
and "ResponseMetadata" in e.response
|
|
40
|
+
and "HTTPStatusCode" in e.response["ResponseMetadata"]
|
|
41
|
+
and e.response["ResponseMetadata"]["HTTPStatusCode"] in (400, 404)
|
|
42
|
+
):
|
|
43
|
+
return None
|
|
44
|
+
raise click.UsageError(str(e))
|
|
45
|
+
else:
|
|
46
|
+
return res["Stacks"][0]["StackStatus"]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_unique_newrelic_otel_log_ingestion_name(session, stackname=None):
|
|
50
|
+
if not stackname:
|
|
51
|
+
stackname = OTEL_INGEST_STACK_NAME
|
|
52
|
+
stack_id = _get_otel_cf_stack_id(session, stack_name=stackname)
|
|
53
|
+
if stack_id:
|
|
54
|
+
return "%s-%s" % (OTEL_INGEST_LAMBDA_NAME, stack_id.split("/")[2].split("-")[4])
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_newrelic_otel_log_ingestion_function(session, stackname=None):
|
|
58
|
+
unique_log_ingestion_name = get_unique_newrelic_otel_log_ingestion_name(
|
|
59
|
+
session, stackname
|
|
60
|
+
)
|
|
61
|
+
if unique_log_ingestion_name:
|
|
62
|
+
function = get_function(session, unique_log_ingestion_name)
|
|
63
|
+
return function
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _get_otel_cf_stack_id(session, stack_name, nr_account_id=None):
|
|
67
|
+
"""Returns the StackId of the CloudFormation stack if it exists"""
|
|
68
|
+
try:
|
|
69
|
+
res = session.client("cloudformation").describe_stacks(StackName=stack_name)
|
|
70
|
+
except botocore.exceptions.ClientError as e:
|
|
71
|
+
if (
|
|
72
|
+
e.response
|
|
73
|
+
and "ResponseMetadata" in e.response
|
|
74
|
+
and "HTTPStatusCode" in e.response["ResponseMetadata"]
|
|
75
|
+
and e.response["ResponseMetadata"]["HTTPStatusCode"] in (400, 404)
|
|
76
|
+
):
|
|
77
|
+
return None
|
|
78
|
+
raise click.UsageError(str(e))
|
|
79
|
+
else:
|
|
80
|
+
return res["Stacks"][0]["StackId"]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _get_otel_sar_template_url(session):
|
|
84
|
+
sar_client = session.client("serverlessrepo")
|
|
85
|
+
template_details = sar_client.create_cloud_formation_template(
|
|
86
|
+
ApplicationId=OTEL_SAR_APP_ID
|
|
87
|
+
)
|
|
88
|
+
return template_details["TemplateUrl"]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _create_otel_log_ingest_parameters(input, nr_license_key, mode="CREATE"):
|
|
92
|
+
assert isinstance(input, (OtelIngestionInstall, OtelIngestionUpdate))
|
|
93
|
+
|
|
94
|
+
update_mode = mode == "UPDATE"
|
|
95
|
+
parameters = []
|
|
96
|
+
|
|
97
|
+
if input.memory_size is not None:
|
|
98
|
+
parameters.append(
|
|
99
|
+
{"ParameterKey": "MemorySize", "ParameterValue": str(input.memory_size)}
|
|
100
|
+
)
|
|
101
|
+
elif update_mode:
|
|
102
|
+
parameters.append({"ParameterKey": "MemorySize", "UsePreviousValue": True})
|
|
103
|
+
|
|
104
|
+
if nr_license_key is not None:
|
|
105
|
+
parameters.append(
|
|
106
|
+
{"ParameterKey": "NRLicenseKey", "ParameterValue": nr_license_key}
|
|
107
|
+
)
|
|
108
|
+
elif update_mode:
|
|
109
|
+
parameters.append({"ParameterKey": "NRLicenseKey", "UsePreviousValue": True})
|
|
110
|
+
|
|
111
|
+
if input.timeout is not None:
|
|
112
|
+
parameters.append(
|
|
113
|
+
{"ParameterKey": "Timeout", "ParameterValue": str(input.timeout)}
|
|
114
|
+
)
|
|
115
|
+
elif update_mode:
|
|
116
|
+
parameters.append({"ParameterKey": "Timeout", "UsePreviousValue": True})
|
|
117
|
+
|
|
118
|
+
capabilities = ["CAPABILITY_IAM"]
|
|
119
|
+
if input.role_name is not None:
|
|
120
|
+
parameters.append(
|
|
121
|
+
{"ParameterKey": "FunctionRole", "ParameterValue": input.role_name}
|
|
122
|
+
)
|
|
123
|
+
capabilities = []
|
|
124
|
+
elif mode != "CREATE":
|
|
125
|
+
parameters.append({"ParameterKey": "FunctionRole", "UsePreviousValue": True})
|
|
126
|
+
capabilities = []
|
|
127
|
+
|
|
128
|
+
return parameters, capabilities
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _create_otel_log_ingestion_function(
|
|
132
|
+
input,
|
|
133
|
+
nr_license_key,
|
|
134
|
+
mode="CREATE",
|
|
135
|
+
):
|
|
136
|
+
assert isinstance(input, (OtelIngestionInstall, OtelIngestionUpdate))
|
|
137
|
+
|
|
138
|
+
parameters, capabilities = _create_otel_log_ingest_parameters(
|
|
139
|
+
input, nr_license_key, mode
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
client = input.session.client("cloudformation")
|
|
143
|
+
|
|
144
|
+
click.echo("Fetching new CloudFormation template url for OTEL log ingestion")
|
|
145
|
+
template_url = _get_otel_sar_template_url(input.session)
|
|
146
|
+
change_set_name = "%s-%s-%d" % (input.stackname, mode, int(time.time()))
|
|
147
|
+
click.echo("Creating change set: %s" % change_set_name)
|
|
148
|
+
try:
|
|
149
|
+
change_set = client.create_change_set(
|
|
150
|
+
StackName=input.stackname,
|
|
151
|
+
TemplateURL=template_url,
|
|
152
|
+
Parameters=parameters,
|
|
153
|
+
Capabilities=capabilities,
|
|
154
|
+
Tags=(
|
|
155
|
+
[{"Key": key, "Value": value} for key, value in input.tags]
|
|
156
|
+
if input.tags
|
|
157
|
+
else []
|
|
158
|
+
),
|
|
159
|
+
ChangeSetType=mode,
|
|
160
|
+
ChangeSetName=change_set_name,
|
|
161
|
+
)
|
|
162
|
+
except Exception as e:
|
|
163
|
+
print(f"Error: {e}")
|
|
164
|
+
_exec_change_set(client, change_set, mode, input.stackname)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@catch_boto_errors
|
|
168
|
+
def update_otel_log_ingestion_function(input):
|
|
169
|
+
assert isinstance(input, OtelIngestionUpdate)
|
|
170
|
+
|
|
171
|
+
client = input.session.client("cloudformation")
|
|
172
|
+
|
|
173
|
+
_create_otel_log_ingestion_function(
|
|
174
|
+
input,
|
|
175
|
+
nr_license_key=None,
|
|
176
|
+
mode="UPDATE",
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@catch_boto_errors
|
|
181
|
+
def install_otel_log_ingestion(
|
|
182
|
+
input,
|
|
183
|
+
nr_license_key,
|
|
184
|
+
):
|
|
185
|
+
"""
|
|
186
|
+
Installs the New Relic AWS Lambda log ingestion function and role.
|
|
187
|
+
|
|
188
|
+
Returns True for success and False for failure.
|
|
189
|
+
"""
|
|
190
|
+
assert isinstance(input, OtelIngestionInstall)
|
|
191
|
+
function = get_function(input.session, OTEL_INGEST_LAMBDA_NAME)
|
|
192
|
+
if function:
|
|
193
|
+
warning(
|
|
194
|
+
"It looks like an old log ingestion function is present in this region. "
|
|
195
|
+
"Consider manually deleting this as it is no longer used and "
|
|
196
|
+
"has been replaced by a log ingestion function specific to the stack."
|
|
197
|
+
)
|
|
198
|
+
stack_status = _check_for_ingest_stack(input.session, input.stackname)
|
|
199
|
+
if stack_status is None:
|
|
200
|
+
click.echo(
|
|
201
|
+
"Setting up CloudFormation Stack %s in region: %s"
|
|
202
|
+
% (input.stackname, input.session.region_name)
|
|
203
|
+
)
|
|
204
|
+
try:
|
|
205
|
+
_create_otel_log_ingestion_function(
|
|
206
|
+
input,
|
|
207
|
+
nr_license_key,
|
|
208
|
+
)
|
|
209
|
+
return True
|
|
210
|
+
except Exception as e:
|
|
211
|
+
failure(
|
|
212
|
+
"CloudFormation Stack %s exists (status: %s).\n"
|
|
213
|
+
"Please manually delete the stack and re-run this command."
|
|
214
|
+
% (input.stackname, stack_status)
|
|
215
|
+
)
|
|
216
|
+
return False
|
|
217
|
+
else:
|
|
218
|
+
function = get_newrelic_otel_log_ingestion_function(
|
|
219
|
+
input.session, input.stackname
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
if function is None:
|
|
223
|
+
failure(
|
|
224
|
+
"CloudFormation Stack %s exists (status: %s), but "
|
|
225
|
+
"%s Lambda function does not.\n"
|
|
226
|
+
"Please manually delete the stack and re-run this command."
|
|
227
|
+
% (input.stackname, stack_status, OTEL_INGEST_LAMBDA_NAME)
|
|
228
|
+
)
|
|
229
|
+
return False
|
|
230
|
+
else:
|
|
231
|
+
success(
|
|
232
|
+
"The CloudFormation Stack %s and "
|
|
233
|
+
"%s function already exists in region %s, "
|
|
234
|
+
"skipping"
|
|
235
|
+
% (input.stackname, OTEL_INGEST_LAMBDA_NAME, input.session.region_name)
|
|
236
|
+
)
|
|
237
|
+
return True
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
@catch_boto_errors
|
|
241
|
+
def update_otel_log_ingestion(input):
|
|
242
|
+
"""
|
|
243
|
+
Updates the New Relic AWS Lambda log ingestion function and role.
|
|
244
|
+
|
|
245
|
+
Returns True for success and False for failure.
|
|
246
|
+
"""
|
|
247
|
+
assert isinstance(input, OtelIngestionUpdate)
|
|
248
|
+
|
|
249
|
+
stack_status = _check_for_ingest_stack(input.session, input.stackname)
|
|
250
|
+
if stack_status is None:
|
|
251
|
+
failure(
|
|
252
|
+
"No '%s' stack in region '%s'. "
|
|
253
|
+
"This likely means the New Relic otel log ingestion function was "
|
|
254
|
+
"installed manually. "
|
|
255
|
+
"In order to install via the CLI, please delete this function and "
|
|
256
|
+
"run 'newrelic-lambda otel-ingestion install'."
|
|
257
|
+
% (OTEL_INGEST_STACK_NAME, input.session.region_name)
|
|
258
|
+
)
|
|
259
|
+
return False
|
|
260
|
+
|
|
261
|
+
function = get_newrelic_otel_log_ingestion_function(input.session, input.stackname)
|
|
262
|
+
if function is None:
|
|
263
|
+
failure(
|
|
264
|
+
"No %s function in region '%s'. "
|
|
265
|
+
"Run 'newrelic-lambda otel-ingestion install' to install it."
|
|
266
|
+
% (OTEL_INGEST_LAMBDA_NAME, input.session.region_name)
|
|
267
|
+
)
|
|
268
|
+
return False
|
|
269
|
+
|
|
270
|
+
try:
|
|
271
|
+
update_otel_log_ingestion_function(input)
|
|
272
|
+
except Exception as e:
|
|
273
|
+
failure("Failed to update newrelic-log-ingestion function: %s" % e)
|
|
274
|
+
return False
|
|
275
|
+
else:
|
|
276
|
+
return True
|
|
@@ -7,6 +7,7 @@ from newrelic_lambda_cli.cliutils import failure, success, warning
|
|
|
7
7
|
from newrelic_lambda_cli.functions import get_function
|
|
8
8
|
from newrelic_lambda_cli.integrations import get_unique_newrelic_log_ingestion_name
|
|
9
9
|
from newrelic_lambda_cli.integrations import get_newrelic_log_ingestion_function
|
|
10
|
+
from newrelic_lambda_cli.otel_ingestions import get_newrelic_otel_log_ingestion_function
|
|
10
11
|
from newrelic_lambda_cli.types import (
|
|
11
12
|
LayerInstall,
|
|
12
13
|
SubscriptionInstall,
|
|
@@ -48,12 +49,16 @@ def _get_subscription_filters(session, function_name):
|
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
def _create_subscription_filter(
|
|
51
|
-
session,
|
|
52
|
+
session,
|
|
53
|
+
function_name,
|
|
54
|
+
destination_arn,
|
|
55
|
+
filter_pattern,
|
|
56
|
+
filter_name="NewRelicLogStreaming",
|
|
52
57
|
):
|
|
53
58
|
try:
|
|
54
59
|
session.client("logs").put_subscription_filter(
|
|
55
60
|
logGroupName=_get_log_group_name(function_name),
|
|
56
|
-
filterName=
|
|
61
|
+
filterName=filter_name,
|
|
57
62
|
filterPattern=filter_pattern,
|
|
58
63
|
destinationArn=destination_arn,
|
|
59
64
|
)
|
|
@@ -137,6 +142,66 @@ def create_log_subscription(input, function_name):
|
|
|
137
142
|
return True
|
|
138
143
|
|
|
139
144
|
|
|
145
|
+
@catch_boto_errors
|
|
146
|
+
def create_otel_log_subscription(input, function_name):
|
|
147
|
+
assert isinstance(input, SubscriptionInstall)
|
|
148
|
+
|
|
149
|
+
destination = get_newrelic_otel_log_ingestion_function(
|
|
150
|
+
input.session, input.stackname
|
|
151
|
+
)
|
|
152
|
+
if destination is None:
|
|
153
|
+
failure(
|
|
154
|
+
"Could not find newrelic-otel-log-ingestion function. Is the New Relic AWS "
|
|
155
|
+
"integration installed?"
|
|
156
|
+
)
|
|
157
|
+
return False
|
|
158
|
+
destination_arn = destination["Configuration"]["FunctionArn"]
|
|
159
|
+
|
|
160
|
+
subscription_filters = _get_subscription_filters(input.session, function_name)
|
|
161
|
+
if subscription_filters is None:
|
|
162
|
+
return False
|
|
163
|
+
newrelic_filters = [
|
|
164
|
+
filter
|
|
165
|
+
for filter in subscription_filters
|
|
166
|
+
if "NewRelicOtelLogStreaming" in filter["filterName"]
|
|
167
|
+
]
|
|
168
|
+
if len(subscription_filters) > len(newrelic_filters):
|
|
169
|
+
warning(
|
|
170
|
+
"WARNING: Found otel log subscription filter that was not installed by New "
|
|
171
|
+
"Relic. This may prevent the New Relic log subscription filter from being "
|
|
172
|
+
"installed. If you know you don't need this log subscription filter, you "
|
|
173
|
+
"should first remove it and rerun this command. If your organization "
|
|
174
|
+
"requires this log subscription filter, please contact New Relic at "
|
|
175
|
+
"serverless@newrelic.com for assistance with getting the AWS log "
|
|
176
|
+
"subscription filter limit increased."
|
|
177
|
+
)
|
|
178
|
+
if not newrelic_filters:
|
|
179
|
+
click.echo("Adding New Relic otel log subscription to '%s'" % function_name)
|
|
180
|
+
return _create_subscription_filter(
|
|
181
|
+
input.session,
|
|
182
|
+
function_name,
|
|
183
|
+
destination_arn,
|
|
184
|
+
input.filter_pattern,
|
|
185
|
+
"NewRelicOtelLogStreaming",
|
|
186
|
+
)
|
|
187
|
+
else:
|
|
188
|
+
click.echo(
|
|
189
|
+
"Found log subscription for '%s', verifying configuration" % function_name
|
|
190
|
+
)
|
|
191
|
+
newrelic_filter = newrelic_filters[0]
|
|
192
|
+
if newrelic_filter["filterPattern"] != input.filter_pattern:
|
|
193
|
+
return _remove_subscription_filter(
|
|
194
|
+
input.session, function_name, newrelic_filter["filterName"]
|
|
195
|
+
) and _create_subscription_filter(
|
|
196
|
+
input.session,
|
|
197
|
+
function_name,
|
|
198
|
+
destination_arn,
|
|
199
|
+
input.filter_pattern,
|
|
200
|
+
"NewRelicOtelLogStreaming",
|
|
201
|
+
)
|
|
202
|
+
return True
|
|
203
|
+
|
|
204
|
+
|
|
140
205
|
@catch_boto_errors
|
|
141
206
|
def remove_log_subscription(input, function_name):
|
|
142
207
|
assert isinstance(input, (LayerInstall, SubscriptionUninstall))
|
|
@@ -158,3 +223,27 @@ def remove_log_subscription(input, function_name):
|
|
|
158
223
|
return _remove_subscription_filter(
|
|
159
224
|
input.session, function_name, newrelic_filter["filterName"]
|
|
160
225
|
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@catch_boto_errors
|
|
229
|
+
def remove_otel_log_subscription(input, function_name):
|
|
230
|
+
assert isinstance(input, (SubscriptionUninstall))
|
|
231
|
+
subscription_filters = _get_subscription_filters(input.session, function_name)
|
|
232
|
+
if subscription_filters is None:
|
|
233
|
+
return False
|
|
234
|
+
newrelic_filters = [
|
|
235
|
+
filter
|
|
236
|
+
for filter in subscription_filters
|
|
237
|
+
if "NewRelicOtelLogStreaming" in filter["filterName"]
|
|
238
|
+
]
|
|
239
|
+
if not newrelic_filters:
|
|
240
|
+
click.echo(
|
|
241
|
+
"No New Relic otel subscription filters found for '%s', skipping"
|
|
242
|
+
% function_name
|
|
243
|
+
)
|
|
244
|
+
return True
|
|
245
|
+
newrelic_filter = newrelic_filters[0]
|
|
246
|
+
click.echo("Removing New Relic otel log subscription from '%s'" % function_name)
|
|
247
|
+
return _remove_subscription_filter(
|
|
248
|
+
input.session, function_name, newrelic_filter["filterName"]
|
|
249
|
+
)
|
newrelic_lambda_cli/types.py
CHANGED
|
@@ -49,6 +49,48 @@ INTEGRATION_UPDATE_KEYS = [
|
|
|
49
49
|
"tags",
|
|
50
50
|
]
|
|
51
51
|
|
|
52
|
+
OTEL_INGESTION_INSTALL_KEYS = [
|
|
53
|
+
"session",
|
|
54
|
+
"verbose",
|
|
55
|
+
"aws_profile",
|
|
56
|
+
"aws_region",
|
|
57
|
+
"aws_permissions_check",
|
|
58
|
+
"aws_role_policy",
|
|
59
|
+
"stackname",
|
|
60
|
+
"memory_size",
|
|
61
|
+
"nr_account_id",
|
|
62
|
+
"nr_api_key",
|
|
63
|
+
"nr_region",
|
|
64
|
+
"timeout",
|
|
65
|
+
"role_name",
|
|
66
|
+
"tags",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
OTEL_INGESTION_UNINSTALL_KEYS = [
|
|
70
|
+
"session",
|
|
71
|
+
"aws_profile",
|
|
72
|
+
"aws_region",
|
|
73
|
+
"aws_permissions_check",
|
|
74
|
+
"stackname",
|
|
75
|
+
"nr_account_id",
|
|
76
|
+
"force",
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
OTEL_INGESTION_UPDATE_KEYS = [
|
|
80
|
+
"session",
|
|
81
|
+
"aws_profile",
|
|
82
|
+
"aws_region",
|
|
83
|
+
"aws_permissions_check",
|
|
84
|
+
"stackname",
|
|
85
|
+
"memory_size",
|
|
86
|
+
"nr_account_id",
|
|
87
|
+
"nr_api_key",
|
|
88
|
+
"nr_region",
|
|
89
|
+
"timeout",
|
|
90
|
+
"role_name",
|
|
91
|
+
"tags",
|
|
92
|
+
]
|
|
93
|
+
|
|
52
94
|
LAYER_INSTALL_KEYS = [
|
|
53
95
|
"session",
|
|
54
96
|
"verbose",
|
|
@@ -86,6 +128,7 @@ SUBSCRIPTION_INSTALL_KEYS = [
|
|
|
86
128
|
"stackname",
|
|
87
129
|
"excludes",
|
|
88
130
|
"filter_pattern",
|
|
131
|
+
"otel",
|
|
89
132
|
]
|
|
90
133
|
|
|
91
134
|
SUBSCRIPTION_UNINSTALL_KEYS = [
|
|
@@ -94,8 +137,8 @@ SUBSCRIPTION_UNINSTALL_KEYS = [
|
|
|
94
137
|
"aws_region",
|
|
95
138
|
"aws_permissions_check",
|
|
96
139
|
"functions",
|
|
97
|
-
"stackname",
|
|
98
140
|
"excludes",
|
|
141
|
+
"otel",
|
|
99
142
|
]
|
|
100
143
|
|
|
101
144
|
|
|
@@ -103,6 +146,13 @@ IntegrationInstall = namedtuple("IntegrationInstall", INTEGRATION_INSTALL_KEYS)
|
|
|
103
146
|
IntegrationUninstall = namedtuple("IntegrationUninstall", INTEGRATION_UNINSTALL_KEYS)
|
|
104
147
|
IntegrationUpdate = namedtuple("IntegrationUpdate", INTEGRATION_UPDATE_KEYS)
|
|
105
148
|
|
|
149
|
+
OtelIngestionInstall = namedtuple("OtelIngestionInstall", OTEL_INGESTION_INSTALL_KEYS)
|
|
150
|
+
OtelIngestionUninstall = namedtuple(
|
|
151
|
+
"OtelIngestionUninstall", OTEL_INGESTION_UNINSTALL_KEYS
|
|
152
|
+
)
|
|
153
|
+
OtelIngestionUpdate = namedtuple("OtelIngestionUpdate", OTEL_INGESTION_UPDATE_KEYS)
|
|
154
|
+
|
|
155
|
+
|
|
106
156
|
LayerInstall = namedtuple("LayerInstall", LAYER_INSTALL_KEYS)
|
|
107
157
|
LayerUninstall = namedtuple("LayerUninstall", LAYER_UNINSTALL_KEYS)
|
|
108
158
|
|
newrelic_lambda_cli/utils.py
CHANGED
|
@@ -10,6 +10,8 @@ NR_DOCS_ACT_LINKING_URL = "https://docs.newrelic.com/docs/serverless-function-mo
|
|
|
10
10
|
NEW_RELIC_ARN_PREFIX_TEMPLATE = "arn:aws:lambda:%s:451483290750"
|
|
11
11
|
RUNTIME_CONFIG = {
|
|
12
12
|
"dotnetcore3.1": {"LambdaExtension": True},
|
|
13
|
+
"dotnet6": {"LambdaExtension": True},
|
|
14
|
+
"dotnet8": {"LambdaExtension": True},
|
|
13
15
|
"java21": {
|
|
14
16
|
"Handler": "com.newrelic.java.HandlerWrapper::",
|
|
15
17
|
"LambdaExtension": True,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: newrelic-lambda-cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.3
|
|
4
4
|
Summary: A CLI to install the New Relic AWS Lambda integration and layers.
|
|
5
5
|
Home-page: https://github.com/newrelic/newrelic-lambda-cli
|
|
6
6
|
Author: New Relic
|
|
@@ -8,12 +8,12 @@ Author-email: serverless-dev@newrelic.com
|
|
|
8
8
|
Requires-Python: >=3.3
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Requires-Dist: boto3
|
|
12
|
-
Requires-Dist: click
|
|
11
|
+
Requires-Dist: boto3<5
|
|
12
|
+
Requires-Dist: click>=7.1.2
|
|
13
13
|
Requires-Dist: colorama
|
|
14
|
-
Requires-Dist: emoji
|
|
15
|
-
Requires-Dist: gql
|
|
16
|
-
Requires-Dist: requests
|
|
14
|
+
Requires-Dist: emoji<3,>=2
|
|
15
|
+
Requires-Dist: gql<3,>=2
|
|
16
|
+
Requires-Dist: requests<3
|
|
17
17
|
Requires-Dist: tabulate
|
|
18
18
|
|
|
19
19
|
[](https://opensource.newrelic.com/oss-category/#community-plus)
|
|
@@ -34,6 +34,9 @@ A CLI to install the New Relic AWS Lambda integration and layers.
|
|
|
34
34
|
* [AWS Lambda Layers](#aws-lambda-layers)
|
|
35
35
|
* [AWS Lambda Functions](#aws-lambda-functions)
|
|
36
36
|
* [NewRelic Log Subscription](#newRelic-log-subscription)
|
|
37
|
+
* [NewRelic Otel Log Ingestions](#newRelic-otel-ingestions-install)
|
|
38
|
+
* [NewRelic Otel Log Subscription](#newRelic-otel-log-subscription)
|
|
39
|
+
|
|
37
40
|
* **[Docker](#docker)**
|
|
38
41
|
* **[Contributing](#contributing)**
|
|
39
42
|
* **[Code Style](#code-style)**
|
|
@@ -52,6 +55,8 @@ A CLI to install the New Relic AWS Lambda integration and layers.
|
|
|
52
55
|
## Runtimes Supported
|
|
53
56
|
|
|
54
57
|
* dotnetcore3.1
|
|
58
|
+
* dotnet6
|
|
59
|
+
* dotnet8
|
|
55
60
|
* java8.al2
|
|
56
61
|
* java11
|
|
57
62
|
* java17
|
|
@@ -61,6 +66,7 @@ A CLI to install the New Relic AWS Lambda integration and layers.
|
|
|
61
66
|
* nodejs20.x
|
|
62
67
|
* provided
|
|
63
68
|
* provided.al2
|
|
69
|
+
* provided.al2023
|
|
64
70
|
* python3.7
|
|
65
71
|
* python3.8
|
|
66
72
|
* python3.9
|
|
@@ -270,6 +276,72 @@ newrelic-lambda subscriptions uninstall --function <name or arn>
|
|
|
270
276
|
| `--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. |
|
|
271
277
|
| `--aws-region` or `-r` | No | The AWS region this function is located. Can use `AWS_DEFAULT_REGION` environment variable. Defaults to AWS session region. |
|
|
272
278
|
|
|
279
|
+
### NewRelic Otel Ingestions Install
|
|
280
|
+
|
|
281
|
+
#### Install Otel Log Ingestion
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
newrelic-lambda otel-ingestions install \
|
|
285
|
+
--nr-account-id <account id> \
|
|
286
|
+
--nr-api-key <api key>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
| Option | Required? | Description |
|
|
290
|
+
|--------|-----------|-------------|
|
|
291
|
+
| `--nr-account-id` or `-a` | Yes | The [New Relic Account ID](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id) for this integration. Can also use the `NEW_RELIC_ACCOUNT_ID` environment variable. |
|
|
292
|
+
| `--nr-api-key` or `-k` | Yes | Your [New Relic User API Key](https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#user-api-key). Can also use the `NEW_RELIC_API_KEY` environment variable. |
|
|
293
|
+
| `--memory-size` or `-m` | No | Memory size (in MiB) for the New Relic log ingestion function. Default to 128MB. |
|
|
294
|
+
| `--nr-region` | No | The New Relic region to use for the integration. Can use the `NEW_RELIC_REGION` environment variable. Can be either `eu` or `us`. Defaults to `us`. |
|
|
295
|
+
| `--timeout` or `-t` | No | Timeout (in seconds) for the New Relic log ingestion function. Defaults to 30 seconds. |
|
|
296
|
+
| `--role-name` | No | Role name for the ingestion function. If you prefer to create and manage an IAM role for the function to assume out of band, do so and specify that role's name here. This avoids needing CAPABILITY_IAM. |
|
|
297
|
+
| `--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. |
|
|
298
|
+
| `--aws-region` or `-r` | No | The AWS region for the integration. Can use `AWS_DEFAULT_REGION` environment variable. Defaults to AWS session region. |
|
|
299
|
+
| `--aws-role-policy` | No | Specify an alternative IAM role policy ARN for this integration. |
|
|
300
|
+
| `--tag <key> <value>` | No | Sets tags on the CloudFormation Stacks this CLI creates. Can be used multiple times, example: `--tag key1 value1 --tag key2 value2`. |
|
|
301
|
+
| `--stackname` | No | The AWS Cloudformation stack name which contains the newrelic-aws-otel-log-ingestion lambda function. If no value is provided, the command searches for the NewRelicOtelLogIngestion stack |
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
#### Uninstall Otel Log Ingestion
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
newrelic-lambda otel-ingestions uninstall
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
| Option | Required? | Description |
|
|
311
|
+
|--------|-----------|-------------|
|
|
312
|
+
| `--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. |
|
|
313
|
+
| `--aws-region` or `-r` | No | The AWS region for the integration. Can use `AWS_DEFAULT_REGION` environment variable. Defaults to AWS session region. |
|
|
314
|
+
| `--force` or `-f` | No | Forces uninstall non-interactively |
|
|
315
|
+
| `--nr-account-id` or `-a` | No | The [New Relic Account ID](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id) for the integration. Only required if also uninstalling the New Relic AWS Lambda integration. Can also use the `NEW_RELIC_ACCOUNT_ID` environment variable. |
|
|
316
|
+
| `--stackname` | No | The AWS Cloudformation stack name which contains the newrelic-aws-otel-log-ingestion lambda function. If no value is provided, the command searches for the NewRelicOtelLogIngestion stack |
|
|
317
|
+
|
|
318
|
+
### NewRelic Otel Log Subscription
|
|
319
|
+
|
|
320
|
+
#### Install Otel Log Subscription
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
newrelic-lambda subscriptions install --function <name or arn> --otel
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
| Option | Required? | Description |
|
|
327
|
+
|--------|-----------|-------------|
|
|
328
|
+
| `--function` or `-f` | Yes | The AWS Lambda function name or ARN in which to remove a log subscription. Can provide multiple `--function` arguments. Will also accept `all`, `installed` and `not-installed` similar to `newrelic-lambda functions list`. |
|
|
329
|
+
| `--otel` or `-o` | Yes | Use this flag to install subscription filters for Lambdas that are instrumented with OpenTelemetry (Otel) |
|
|
330
|
+
| `--stackname` | No | The AWS Cloudformation stack name which contains the newrelic-aws-otel-log-ingestion lambda function. If no value is provided, the command searches for the NewRelicOtelLogIngestion stack |
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
#### Uninstall Otel Log Subscription
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
newrelic-lambda subscriptions uninstall --function <name or arn> --otel
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
| Option | Required? | Description |
|
|
340
|
+
|--------|-----------|-------------|
|
|
341
|
+
| `--function` or `-f` | Yes | The AWS Lambda function name or ARN in which to remove a log subscription. Can provide multiple `--function` arguments. Will also accept `all`, `installed` and `not-installed` similar to `newrelic-lambda functions list`. |
|
|
342
|
+
| `--otel` or `-o` | Yes | Use this flag to install subscription filters for Lambdas that are instrumented with OpenTelemetry (Otel) |
|
|
343
|
+
| `--stackname` | No | The AWS Cloudformation stack name which contains the newrelic-aws-otel-log-ingestion lambda function. If no value is provided, the command searches for the NewRelicOtelLogIngestion stack |
|
|
344
|
+
|
|
273
345
|
## Docker
|
|
274
346
|
|
|
275
347
|
Now, you can run newrelic-lambda-cli as a container.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
newrelic_lambda_cli/__init__.py,sha256=u4cy7hwbrNjK3xtldGQD_51aoNgSqGQ3IzFYsuvaIM4,149
|
|
2
|
+
newrelic_lambda_cli/api.py,sha256=b75XwylRhW9pcA6aZ9EjBW1yIFOGHhhULDD5hNhMyes,15065
|
|
3
|
+
newrelic_lambda_cli/cliutils.py,sha256=x2pWlL3DJ9t98QNElp_rhawNQoIZ0vd55R2jpo3_oI0,902
|
|
4
|
+
newrelic_lambda_cli/functions.py,sha256=p57ZUw424BaSUA_Gw8DrYsJOYKROEHEaXgARadqwcP0,2800
|
|
5
|
+
newrelic_lambda_cli/integrations.py,sha256=r0gxfEqVHTGu3xbr4dOCDwm0-Yhoz3KntfeQRWvoWrQ,31266
|
|
6
|
+
newrelic_lambda_cli/layers.py,sha256=7ntl48RVEoRO4iiD3yzsxgqNkx013vXO5wQuoP6M0-I,14805
|
|
7
|
+
newrelic_lambda_cli/otel_ingestions.py,sha256=vi1Mlfc9nRvRWV7STwK7fDXZGozG8ufKohmpHcaWGic,9250
|
|
8
|
+
newrelic_lambda_cli/permissions.py,sha256=H7v5IMpKaJIWC4Dff2YcTis4BKAAFIJr9IHWUj1LnF4,9093
|
|
9
|
+
newrelic_lambda_cli/subscriptions.py,sha256=RDg5x_IajnZy2BzcONk1ZaLbb17XYLLNv6xJH1SBPcg,9533
|
|
10
|
+
newrelic_lambda_cli/types.py,sha256=z4K_ALDhF-iOKpyQUekbzETa586mr9bMpK9RCuffVQ8,3293
|
|
11
|
+
newrelic_lambda_cli/utils.py,sha256=dYcSFZj7Mpgr5f8YSaAjt80N1q9akcOj1_puL8iRHak,5324
|
|
12
|
+
newrelic_lambda_cli/cli/__init__.py,sha256=FciF2RVqQbpMKqEiN8qjO6qmdLB6Yv8LyyyPYcfJNrc,622
|
|
13
|
+
newrelic_lambda_cli/cli/decorators.py,sha256=a3agkVfy8omkUSL4aKblwSX95xtxYOGASULDYcJDPHk,1786
|
|
14
|
+
newrelic_lambda_cli/cli/functions.py,sha256=RSh2Cowe1_oQup8q5YRidp03z-BITo2uzvDh4zvLr4I,2601
|
|
15
|
+
newrelic_lambda_cli/cli/integrations.py,sha256=aQAWcCCU2kBmbF8fLKwKB9bzSY0uipvnojajjTkhqEs,10461
|
|
16
|
+
newrelic_lambda_cli/cli/layers.py,sha256=3CTukG79vM2Gzx3NFXsqUEjy5mNQ4rawIh53oQeCyCI,6180
|
|
17
|
+
newrelic_lambda_cli/cli/otel_ingestions.py,sha256=4rTm9iYUo2qdMeqxJSrYLCA6ZXHy5bJnjDn9x54pCYc,6096
|
|
18
|
+
newrelic_lambda_cli/cli/subscriptions.py,sha256=bUupv5iv3mUkC8t31nnI3BahoKxDnUJ8Rgq4QHJcFNU,5890
|
|
19
|
+
newrelic_lambda_cli/templates/import-template.yaml,sha256=0r1yeoqpnqtEMggWomALkPG10NiANPWWBqz03rChch8,3771
|
|
20
|
+
newrelic_lambda_cli/templates/license-key-secret.yaml,sha256=ZldQaLXsyF1K2I4X_AsLdH7kRmLkPUYI3talmhqQyHg,1849
|
|
21
|
+
newrelic_lambda_cli/templates/nr-lambda-integration-role.yaml,sha256=s7T73B_k-mAwgzJrD2xn8YGUNgn2E1V7Exifrl81ViU,2874
|
|
22
|
+
newrelic_lambda_cli-0.9.3.dist-info/LICENSE,sha256=uuxDzQm0yfq_tNZX0tQYzsZUVRIF0jm3dBLZUojSYzI,11345
|
|
23
|
+
newrelic_lambda_cli-0.9.3.dist-info/METADATA,sha256=izwIavIZMu-SUxSO7V8QRvihAmqwSn4OuQo4EMl1Qk4,26815
|
|
24
|
+
newrelic_lambda_cli-0.9.3.dist-info/WHEEL,sha256=M4n4zmFKzQZk4mLCcycNIzIXO7YPKE_b5Cw4PnhHEg8,109
|
|
25
|
+
newrelic_lambda_cli-0.9.3.dist-info/entry_points.txt,sha256=iks2k9Y4WNgIecsDzreIvMV9pGCjwwKTf33LKKvl2A8,65
|
|
26
|
+
newrelic_lambda_cli-0.9.3.dist-info/top_level.txt,sha256=dxX2w58VgSUFiPD8C_lFuY-T2C1kjfeY0xi8iTh0r44,20
|
|
27
|
+
newrelic_lambda_cli-0.9.3.dist-info/RECORD,,
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
newrelic_lambda_cli/__init__.py,sha256=u4cy7hwbrNjK3xtldGQD_51aoNgSqGQ3IzFYsuvaIM4,149
|
|
2
|
-
newrelic_lambda_cli/api.py,sha256=tkjuR_qkD2uZgXfXPFR6YKnmRiNYkrEmqQEeUgDtNn8,14848
|
|
3
|
-
newrelic_lambda_cli/cliutils.py,sha256=x2pWlL3DJ9t98QNElp_rhawNQoIZ0vd55R2jpo3_oI0,902
|
|
4
|
-
newrelic_lambda_cli/functions.py,sha256=p57ZUw424BaSUA_Gw8DrYsJOYKROEHEaXgARadqwcP0,2800
|
|
5
|
-
newrelic_lambda_cli/integrations.py,sha256=X9OuBK_sNfjb1cjbZ1dctd_YTVyEeCCGsPaJp0Bni1U,30864
|
|
6
|
-
newrelic_lambda_cli/layers.py,sha256=Gnt9pdG1Tfh79Y8ZWWJyMVXEB6xnW2UaSuo5zoYLa3U,14270
|
|
7
|
-
newrelic_lambda_cli/permissions.py,sha256=H7v5IMpKaJIWC4Dff2YcTis4BKAAFIJr9IHWUj1LnF4,9093
|
|
8
|
-
newrelic_lambda_cli/subscriptions.py,sha256=wh6vroU8RfSEwqAMObjPNVPb0TbBxUYYPO_c3mY7miA,6166
|
|
9
|
-
newrelic_lambda_cli/types.py,sha256=kzubT5cGiI-k6h_8b_iTaj3bnsNwolhjgSbpFJT9iBk,2304
|
|
10
|
-
newrelic_lambda_cli/utils.py,sha256=cwYX_zG72EjGT92l43mEAJRygrClUNseKDyssQ6D_2Q,5240
|
|
11
|
-
newrelic_lambda_cli/cli/__init__.py,sha256=n_QPd3oJqkFxryy-pJ-Y_AsqsmgbTb3dlQCjPJueaYQ,544
|
|
12
|
-
newrelic_lambda_cli/cli/decorators.py,sha256=a3agkVfy8omkUSL4aKblwSX95xtxYOGASULDYcJDPHk,1786
|
|
13
|
-
newrelic_lambda_cli/cli/functions.py,sha256=RSh2Cowe1_oQup8q5YRidp03z-BITo2uzvDh4zvLr4I,2601
|
|
14
|
-
newrelic_lambda_cli/cli/integrations.py,sha256=aQAWcCCU2kBmbF8fLKwKB9bzSY0uipvnojajjTkhqEs,10461
|
|
15
|
-
newrelic_lambda_cli/cli/layers.py,sha256=dVlBB0rnhnWEXl9EygEjSiJknNnIQgPbF8L5hsdkMfU,5886
|
|
16
|
-
newrelic_lambda_cli/cli/subscriptions.py,sha256=qwV4WUW9fbju0t4-aSfIrPdeEa4QvIJ8bfwTvMnm7zs,4251
|
|
17
|
-
newrelic_lambda_cli/templates/import-template.yaml,sha256=0r1yeoqpnqtEMggWomALkPG10NiANPWWBqz03rChch8,3771
|
|
18
|
-
newrelic_lambda_cli/templates/license-key-secret.yaml,sha256=ZldQaLXsyF1K2I4X_AsLdH7kRmLkPUYI3talmhqQyHg,1849
|
|
19
|
-
newrelic_lambda_cli/templates/nr-lambda-integration-role.yaml,sha256=s7T73B_k-mAwgzJrD2xn8YGUNgn2E1V7Exifrl81ViU,2874
|
|
20
|
-
newrelic_lambda_cli-0.9.1.dist-info/LICENSE,sha256=uuxDzQm0yfq_tNZX0tQYzsZUVRIF0jm3dBLZUojSYzI,11345
|
|
21
|
-
newrelic_lambda_cli-0.9.1.dist-info/METADATA,sha256=rKXVnaSVtnjbs_5xuj_CdvJh8fRMWEpB5_LAnrTACag,21703
|
|
22
|
-
newrelic_lambda_cli-0.9.1.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
23
|
-
newrelic_lambda_cli-0.9.1.dist-info/entry_points.txt,sha256=iks2k9Y4WNgIecsDzreIvMV9pGCjwwKTf33LKKvl2A8,65
|
|
24
|
-
newrelic_lambda_cli-0.9.1.dist-info/top_level.txt,sha256=dxX2w58VgSUFiPD8C_lFuY-T2C1kjfeY0xi8iTh0r44,20
|
|
25
|
-
newrelic_lambda_cli-0.9.1.dist-info/RECORD,,
|
|
File without changes
|
{newrelic_lambda_cli-0.9.1.dist-info → newrelic_lambda_cli-0.9.3.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|