newrelic-lambda-cli 0.9.6__tar.gz → 0.9.8__tar.gz

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.
Files changed (46) hide show
  1. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/PKG-INFO +1 -1
  2. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cli/layers.py +6 -2
  3. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/layers.py +45 -4
  4. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/types.py +1 -0
  5. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/utils.py +6 -0
  6. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli.egg-info/PKG-INFO +1 -1
  7. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/setup.py +1 -1
  8. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_layers.py +69 -4
  9. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_utils.py +7 -0
  10. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/CODE_OF_CONDUCT.md +0 -0
  11. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/CONTRIBUTING.md +0 -0
  12. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/LICENSE +0 -0
  13. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/MANIFEST.in +0 -0
  14. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/README.md +0 -0
  15. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/THIRD_PARTY_NOTICES.md +0 -0
  16. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/__init__.py +0 -0
  17. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/api.py +0 -0
  18. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cli/__init__.py +0 -0
  19. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cli/decorators.py +0 -0
  20. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cli/functions.py +0 -0
  21. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cli/integrations.py +0 -0
  22. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cli/otel_ingestions.py +0 -0
  23. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cli/subscriptions.py +0 -0
  24. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/cliutils.py +0 -0
  25. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/functions.py +0 -0
  26. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/integrations.py +0 -0
  27. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/otel_ingestions.py +0 -0
  28. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/permissions.py +0 -0
  29. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/subscriptions.py +0 -0
  30. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/templates/import-template.yaml +0 -0
  31. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/templates/license-key-secret.yaml +0 -0
  32. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli/templates/nr-lambda-integration-role.yaml +0 -0
  33. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli.egg-info/SOURCES.txt +0 -0
  34. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli.egg-info/dependency_links.txt +0 -0
  35. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli.egg-info/entry_points.txt +0 -0
  36. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli.egg-info/not-zip-safe +0 -0
  37. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli.egg-info/requires.txt +0 -0
  38. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/newrelic_lambda_cli.egg-info/top_level.txt +0 -0
  39. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/pyproject.toml +0 -0
  40. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/setup.cfg +0 -0
  41. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_api.py +0 -0
  42. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_functions.py +0 -0
  43. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_integrations.py +0 -0
  44. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_new_relic_gql.py +0 -0
  45. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_permissions.py +0 -0
  46. {newrelic_lambda_cli-0.9.6 → newrelic_lambda_cli-0.9.8}/tests/test_subscriptions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: newrelic-lambda-cli
3
- Version: 0.9.6
3
+ Version: 0.9.8
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
@@ -81,6 +81,11 @@ def register(group):
81
81
  help="Permit upgrade of function layers to new version.",
82
82
  is_flag=True,
83
83
  )
84
+ @click.option(
85
+ "--apm",
86
+ help="Enable APM Lambda mode",
87
+ is_flag=True,
88
+ )
84
89
  @click.option(
85
90
  "--enable-extension/--disable-extension",
86
91
  "-x",
@@ -105,8 +110,7 @@ def register(group):
105
110
  )
106
111
  @click.option(
107
112
  "--esm",
108
- default=False,
109
- show_default=True,
113
+ is_flag=True,
110
114
  help="Nodejs runtimes only - nodejs implementation runtime handler to /opt/nodejs/node_modules/newrelic-esm-lambda-wrapper/index.handler",
111
115
  )
112
116
  @click.pass_context
@@ -104,7 +104,7 @@ def _add_new_relic(input, config, nr_license_key):
104
104
  prefix = (
105
105
  "/opt/nodejs/node_modules/newrelic-esm-lambda-wrapper/index"
106
106
  if input.esm
107
- else "newrelic_lambda_wrapper"
107
+ else "newrelic-lambda-wrapper"
108
108
  )
109
109
  runtime_handler = prefix + ".handler"
110
110
 
@@ -118,6 +118,7 @@ def _add_new_relic(input, config, nr_license_key):
118
118
  success(
119
119
  "Already installed on function '%s'. Pass --upgrade (or -u) to allow "
120
120
  "upgrade or reinstall to latest layer version."
121
+ "Additionally pass --apm to enable APM Lambda mode."
121
122
  % config["Configuration"]["FunctionArn"]
122
123
  )
123
124
  return True
@@ -172,7 +173,18 @@ def _add_new_relic(input, config, nr_license_key):
172
173
 
173
174
  # Update the NEW_RELIC_LAMBDA_HANDLER envvars only when it's a new install.
174
175
  if runtime_handler and handler != runtime_handler:
175
- update_kwargs["Environment"]["Variables"]["NEW_RELIC_LAMBDA_HANDLER"] = handler
176
+ if "nodejs" in runtime:
177
+ if handler not in [
178
+ "newrelic-lambda-wrapper.handler",
179
+ "/opt/nodejs/node_modules/newrelic-esm-lambda-wrapper/index.handler",
180
+ ]:
181
+ update_kwargs["Environment"]["Variables"][
182
+ "NEW_RELIC_LAMBDA_HANDLER"
183
+ ] = handler
184
+ else:
185
+ update_kwargs["Environment"]["Variables"][
186
+ "NEW_RELIC_LAMBDA_HANDLER"
187
+ ] = handler
176
188
 
177
189
  if input.enable_extension and not utils.supports_lambda_extension(runtime):
178
190
  warning(
@@ -221,6 +233,13 @@ def _add_new_relic(input, config, nr_license_key):
221
233
  "CORECLR_PROFILER_PATH"
222
234
  ] = "/opt/lib/newrelic-dotnet-agent/libNewRelicProfiler.so"
223
235
 
236
+ if input.apm:
237
+ success(
238
+ "Enabling APM Lambda mode for function '%s' "
239
+ % config["Configuration"]["FunctionArn"]
240
+ )
241
+ update_kwargs["Environment"]["Variables"]["NEW_RELIC_APM_LAMBDA_MODE"] = "True"
242
+
224
243
  return update_kwargs
225
244
 
226
245
 
@@ -302,7 +321,25 @@ def install(input, function_arn):
302
321
  if input.verbose:
303
322
  click.echo(json.dumps(res, indent=2))
304
323
 
305
- success("Successfully installed layer on %s" % function_arn)
324
+ old_layers = config["Configuration"].get("Layers", [])
325
+ old_layer_arn = old_layers[0]["Arn"].rsplit(":", 1)[0] if old_layers else "None"
326
+ old_layer_version = (
327
+ old_layers[0]["Arn"].split(":")[-1] if old_layers else "None"
328
+ )
329
+ new_layer = update_kwargs["Layers"][0]
330
+ new_layer_arn = update_kwargs["Layers"][0].rsplit(":", 1)[0]
331
+ new_layer_version = update_kwargs["Layers"][0].split(":")[-1]
332
+
333
+ if old_layer_arn == "None":
334
+ success(
335
+ "Successfully installed Layer ARN %s for the function: %s"
336
+ % (new_layer, function_arn)
337
+ )
338
+ else:
339
+ success(
340
+ "Successfully upgraded Layer ARN %s from version: %s to version: %s for the function: %s"
341
+ % (new_layer_arn, old_layer_version, new_layer_version, function_arn)
342
+ )
306
343
  return True
307
344
 
308
345
 
@@ -401,7 +438,11 @@ def uninstall(input, function_arn):
401
438
  if input.verbose:
402
439
  click.echo(json.dumps(res, indent=2))
403
440
 
404
- success("Successfully uninstalled layer on %s" % function_arn)
441
+ old_layers = config["Configuration"].get("Layers", [])
442
+ old_layer_arn = old_layers[0]["Arn"] if old_layers else "None"
443
+ success(
444
+ "Successfully uninstalled Layer %s from %s" % (old_layer_arn, function_arn)
445
+ )
405
446
  return True
406
447
 
407
448
 
@@ -104,6 +104,7 @@ LAYER_INSTALL_KEYS = [
104
104
  "excludes",
105
105
  "layer_arn",
106
106
  "upgrade",
107
+ "apm",
107
108
  "enable_extension",
108
109
  "enable_extension_function_logs",
109
110
  "java_handler_method",
@@ -131,6 +131,12 @@ def all_lambda_regions():
131
131
 
132
132
  def is_valid_handler(runtime, handler):
133
133
  runtime_handler = RUNTIME_CONFIG.get(runtime, {}).get("Handler", None)
134
+ if (
135
+ "nodejs" in runtime
136
+ and handler
137
+ == "/opt/nodejs/node_modules/newrelic-esm-lambda-wrapper/index.handler"
138
+ ):
139
+ return True
134
140
  if isinstance(runtime_handler, dict):
135
141
  for _, valid_handler in runtime_handler.items():
136
142
  if handler == valid_handler:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: newrelic-lambda-cli
3
- Version: 0.9.6
3
+ Version: 0.9.8
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
@@ -6,7 +6,7 @@ README = open(os.path.join(os.path.dirname(__file__), "README.md"), "r").read()
6
6
 
7
7
  setup(
8
8
  name="newrelic-lambda-cli",
9
- version="0.9.6",
9
+ version="0.9.8",
10
10
  python_requires=">=3.3",
11
11
  description="A CLI to install the New Relic AWS Lambda integration and layers.",
12
12
  long_description=README,
@@ -235,6 +235,34 @@ def test_add_new_relic(aws_credentials, mock_function_config):
235
235
  assert update_kwargs["Layers"][0] != get_arn_prefix("us-east-1")
236
236
 
237
237
 
238
+ @mock_aws
239
+ def test_add_new_relic_apm_lambda_mode(aws_credentials, mock_function_config):
240
+ session = boto3.Session(region_name="us-east-1")
241
+
242
+ config = mock_function_config("python3.12")
243
+
244
+ assert config["Configuration"]["Handler"] == "original_handler"
245
+
246
+ update_kwargs = _add_new_relic(
247
+ layer_install(
248
+ session=session,
249
+ aws_region="us-east-1",
250
+ nr_account_id=12345,
251
+ enable_extension=True,
252
+ enable_extension_function_logs=True,
253
+ apm=True,
254
+ ),
255
+ config,
256
+ nr_license_key=None,
257
+ )
258
+
259
+ assert update_kwargs["FunctionName"] == config["Configuration"]["FunctionArn"]
260
+ assert update_kwargs["Handler"] == "newrelic_lambda_wrapper.handler"
261
+ assert (
262
+ update_kwargs["Environment"]["Variables"]["NEW_RELIC_APM_LAMBDA_MODE"] == "True"
263
+ )
264
+
265
+
238
266
  @mock_aws
239
267
  def test_add_new_relic_dotnet(aws_credentials, mock_function_config):
240
268
  session = boto3.Session(region_name="us-east-1")
@@ -333,7 +361,7 @@ def test_add_new_relic_nodejs(aws_credentials, mock_function_config):
333
361
  assert (
334
362
  update_kwargs_std["FunctionName"] == config_std["Configuration"]["FunctionArn"]
335
363
  )
336
- assert update_kwargs_std["Handler"] == "newrelic_lambda_wrapper.handler"
364
+ assert update_kwargs_std["Handler"] == "newrelic-lambda-wrapper.handler"
337
365
  assert (
338
366
  update_kwargs_std["Environment"]["Variables"]["NEW_RELIC_LAMBDA_HANDLER"]
339
367
  == original_std_handler
@@ -633,7 +661,44 @@ def test_uninstall(aws_credentials, mock_function_config):
633
661
  )
634
662
 
635
663
 
636
- def test_layers_index():
637
- layers = index("ap-southeast-1", "nodejs20.x", "x86_64")
664
+ @mock_aws
665
+ def test_install_success_message_new_layer(aws_credentials, mock_function_config):
666
+ """Test that the correct success message is shown when installing a layer on a function with no existing layers"""
667
+
668
+ mock_session = MagicMock()
669
+ mock_session.region_name = "us-east-1"
670
+
671
+ with patch(
672
+ "newrelic_lambda_cli.layers._get_license_key_outputs"
673
+ ) as mock_get_license_key_outputs, patch(
674
+ "newrelic_lambda_cli.layers.success"
675
+ ) as mock_success:
676
+
677
+ mock_get_license_key_outputs.return_value = ("license_arn", "12345", "policy")
678
+ mock_client = mock_session.client.return_value
638
679
 
639
- assert len(layers) == 1
680
+ config = mock_function_config("python3.12")
681
+ config["Configuration"]["Layers"] = []
682
+ mock_client.get_function.return_value = config
683
+
684
+ new_layer_arn = (
685
+ "arn:aws:lambda:us-east-1:451483290750:layer:NewRelicPython39:35"
686
+ )
687
+
688
+ with patch("newrelic_lambda_cli.layers._add_new_relic") as mock_add_new_relic:
689
+ mock_add_new_relic.return_value = {
690
+ "FunctionName": "test-function-name",
691
+ "Layers": [new_layer_arn],
692
+ }
693
+
694
+ function_arn = "test-function-arn"
695
+ result = install(
696
+ layer_install(nr_account_id=12345, session=mock_session), function_arn
697
+ )
698
+
699
+ assert result is True
700
+
701
+ mock_success.assert_called_once_with(
702
+ "Successfully installed Layer ARN %s for the function: %s"
703
+ % (new_layer_arn, function_arn)
704
+ )
@@ -21,6 +21,13 @@ def test_error():
21
21
  def test_is_valid_handler():
22
22
  assert is_valid_handler("fakeruntime", "not.a.valid.handler") is False
23
23
  assert is_valid_handler("python3.9", "newrelic_lambda_wrapper.handler") is True
24
+ assert (
25
+ is_valid_handler(
26
+ "nodejs22",
27
+ "/opt/nodejs/node_modules/newrelic-esm-lambda-wrapper/index.handler",
28
+ )
29
+ is True
30
+ )
24
31
 
25
32
 
26
33
  def test_parse_arn():