Feature: AWSLambda Function URL Configs (#5420)
This commit is contained in:
parent
2e0022cb1d
commit
1ea0c74028
@ -3725,7 +3725,7 @@
|
|||||||
|
|
||||||
## lambda
|
## lambda
|
||||||
<details>
|
<details>
|
||||||
<summary>49% implemented</summary>
|
<summary>55% implemented</summary>
|
||||||
|
|
||||||
- [ ] add_layer_version_permission
|
- [ ] add_layer_version_permission
|
||||||
- [X] add_permission
|
- [X] add_permission
|
||||||
@ -3733,7 +3733,7 @@
|
|||||||
- [ ] create_code_signing_config
|
- [ ] create_code_signing_config
|
||||||
- [X] create_event_source_mapping
|
- [X] create_event_source_mapping
|
||||||
- [X] create_function
|
- [X] create_function
|
||||||
- [ ] create_function_url_config
|
- [X] create_function_url_config
|
||||||
- [X] delete_alias
|
- [X] delete_alias
|
||||||
- [ ] delete_code_signing_config
|
- [ ] delete_code_signing_config
|
||||||
- [X] delete_event_source_mapping
|
- [X] delete_event_source_mapping
|
||||||
@ -3741,7 +3741,7 @@
|
|||||||
- [ ] delete_function_code_signing_config
|
- [ ] delete_function_code_signing_config
|
||||||
- [X] delete_function_concurrency
|
- [X] delete_function_concurrency
|
||||||
- [ ] delete_function_event_invoke_config
|
- [ ] delete_function_event_invoke_config
|
||||||
- [ ] delete_function_url_config
|
- [X] delete_function_url_config
|
||||||
- [X] delete_layer_version
|
- [X] delete_layer_version
|
||||||
- [ ] delete_provisioned_concurrency_config
|
- [ ] delete_provisioned_concurrency_config
|
||||||
- [ ] get_account_settings
|
- [ ] get_account_settings
|
||||||
@ -3753,7 +3753,7 @@
|
|||||||
- [X] get_function_concurrency
|
- [X] get_function_concurrency
|
||||||
- [ ] get_function_configuration
|
- [ ] get_function_configuration
|
||||||
- [ ] get_function_event_invoke_config
|
- [ ] get_function_event_invoke_config
|
||||||
- [ ] get_function_url_config
|
- [X] get_function_url_config
|
||||||
- [X] get_layer_version
|
- [X] get_layer_version
|
||||||
- [ ] get_layer_version_by_arn
|
- [ ] get_layer_version_by_arn
|
||||||
- [ ] get_layer_version_policy
|
- [ ] get_layer_version_policy
|
||||||
@ -3789,7 +3789,7 @@
|
|||||||
- [X] update_function_code
|
- [X] update_function_code
|
||||||
- [X] update_function_configuration
|
- [X] update_function_configuration
|
||||||
- [ ] update_function_event_invoke_config
|
- [ ] update_function_event_invoke_config
|
||||||
- [ ] update_function_url_config
|
- [X] update_function_url_config
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## logs
|
## logs
|
||||||
|
@ -33,7 +33,12 @@ lambda
|
|||||||
- [ ] create_code_signing_config
|
- [ ] create_code_signing_config
|
||||||
- [X] create_event_source_mapping
|
- [X] create_event_source_mapping
|
||||||
- [X] create_function
|
- [X] create_function
|
||||||
- [ ] create_function_url_config
|
- [X] create_function_url_config
|
||||||
|
|
||||||
|
The Qualifier-parameter is not yet implemented.
|
||||||
|
Function URLs are not yet mocked, so invoking them will fail
|
||||||
|
|
||||||
|
|
||||||
- [X] delete_alias
|
- [X] delete_alias
|
||||||
- [ ] delete_code_signing_config
|
- [ ] delete_code_signing_config
|
||||||
- [X] delete_event_source_mapping
|
- [X] delete_event_source_mapping
|
||||||
@ -41,7 +46,11 @@ lambda
|
|||||||
- [ ] delete_function_code_signing_config
|
- [ ] delete_function_code_signing_config
|
||||||
- [X] delete_function_concurrency
|
- [X] delete_function_concurrency
|
||||||
- [ ] delete_function_event_invoke_config
|
- [ ] delete_function_event_invoke_config
|
||||||
- [ ] delete_function_url_config
|
- [X] delete_function_url_config
|
||||||
|
|
||||||
|
The Qualifier-parameter is not yet implemented
|
||||||
|
|
||||||
|
|
||||||
- [X] delete_layer_version
|
- [X] delete_layer_version
|
||||||
- [ ] delete_provisioned_concurrency_config
|
- [ ] delete_provisioned_concurrency_config
|
||||||
- [ ] get_account_settings
|
- [ ] get_account_settings
|
||||||
@ -53,7 +62,11 @@ lambda
|
|||||||
- [X] get_function_concurrency
|
- [X] get_function_concurrency
|
||||||
- [ ] get_function_configuration
|
- [ ] get_function_configuration
|
||||||
- [ ] get_function_event_invoke_config
|
- [ ] get_function_event_invoke_config
|
||||||
- [ ] get_function_url_config
|
- [X] get_function_url_config
|
||||||
|
|
||||||
|
The Qualifier-parameter is not yet implemented
|
||||||
|
|
||||||
|
|
||||||
- [X] get_layer_version
|
- [X] get_layer_version
|
||||||
- [ ] get_layer_version_by_arn
|
- [ ] get_layer_version_by_arn
|
||||||
- [ ] get_layer_version_policy
|
- [ ] get_layer_version_policy
|
||||||
@ -97,5 +110,9 @@ lambda
|
|||||||
- [X] update_function_code
|
- [X] update_function_code
|
||||||
- [X] update_function_configuration
|
- [X] update_function_configuration
|
||||||
- [ ] update_function_event_invoke_config
|
- [ ] update_function_event_invoke_config
|
||||||
- [ ] update_function_url_config
|
- [X] update_function_url_config
|
||||||
|
|
||||||
|
The Qualifier-parameter is not yet implemented
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,6 +49,15 @@ class UnknownFunctionException(LambdaClientError):
|
|||||||
super().__init__("ResourceNotFoundException", f"Function not found: {arn}")
|
super().__init__("ResourceNotFoundException", f"Function not found: {arn}")
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionUrlConfigNotFound(LambdaClientError):
|
||||||
|
code = 404
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(
|
||||||
|
"ResourceNotFoundException", "The resource you requested does not exist."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UnknownLayerException(LambdaClientError):
|
class UnknownLayerException(LambdaClientError):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ from moto.s3.exceptions import MissingBucket, MissingKey
|
|||||||
from moto import settings
|
from moto import settings
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
CrossAccountNotAllowed,
|
CrossAccountNotAllowed,
|
||||||
|
FunctionUrlConfigNotFound,
|
||||||
InvalidRoleFormat,
|
InvalidRoleFormat,
|
||||||
InvalidParameterValueException,
|
InvalidParameterValueException,
|
||||||
UnknownLayerException,
|
UnknownLayerException,
|
||||||
@ -404,6 +405,7 @@ class LambdaFunction(CloudFormationModel, DockerModel):
|
|||||||
self.logs_backend = logs_backends[account_id][self.region]
|
self.logs_backend = logs_backends[account_id][self.region]
|
||||||
self.environment_vars = spec.get("Environment", {}).get("Variables", {})
|
self.environment_vars = spec.get("Environment", {}).get("Variables", {})
|
||||||
self.policy = None
|
self.policy = None
|
||||||
|
self.url_config = None
|
||||||
self.state = "Active"
|
self.state = "Active"
|
||||||
self.reserved_concurrency = spec.get("ReservedConcurrentExecutions", None)
|
self.reserved_concurrency = spec.get("ReservedConcurrentExecutions", None)
|
||||||
|
|
||||||
@ -914,6 +916,48 @@ class LambdaFunction(CloudFormationModel, DockerModel):
|
|||||||
alias.update(description, function_version, routing_config)
|
alias.update(description, function_version, routing_config)
|
||||||
return alias
|
return alias
|
||||||
|
|
||||||
|
def create_url_config(self, config):
|
||||||
|
self.url_config = FunctionUrlConfig(function=self, config=config)
|
||||||
|
return self.url_config
|
||||||
|
|
||||||
|
def delete_url_config(self):
|
||||||
|
self.url_config = None
|
||||||
|
|
||||||
|
def get_url_config(self):
|
||||||
|
if not self.url_config:
|
||||||
|
raise FunctionUrlConfigNotFound()
|
||||||
|
return self.url_config
|
||||||
|
|
||||||
|
def update_url_config(self, config):
|
||||||
|
self.url_config.update(config)
|
||||||
|
return self.url_config
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionUrlConfig:
|
||||||
|
def __init__(self, function: LambdaFunction, config):
|
||||||
|
self.function = function
|
||||||
|
self.config = config
|
||||||
|
self.url = f"https://{uuid.uuid4().hex}.lambda-url.{function.region}.on.aws"
|
||||||
|
self.created = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")
|
||||||
|
self.last_modified = self.created
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
"FunctionUrl": self.url,
|
||||||
|
"FunctionArn": self.function.function_arn,
|
||||||
|
"AuthType": self.config.get("AuthType"),
|
||||||
|
"Cors": self.config.get("Cors"),
|
||||||
|
"CreationTime": self.created,
|
||||||
|
"LastModifiedTime": self.last_modified,
|
||||||
|
}
|
||||||
|
|
||||||
|
def update(self, new_config):
|
||||||
|
if new_config.get("Cors"):
|
||||||
|
self.config["Cors"] = new_config["Cors"]
|
||||||
|
if new_config.get("AuthType"):
|
||||||
|
self.config["AuthType"] = new_config["AuthType"]
|
||||||
|
self.last_modified = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")
|
||||||
|
|
||||||
|
|
||||||
class EventSourceMapping(CloudFormationModel):
|
class EventSourceMapping(CloudFormationModel):
|
||||||
def __init__(self, spec):
|
def __init__(self, spec):
|
||||||
@ -1138,7 +1182,9 @@ class LambdaStorage(object):
|
|||||||
arn = ":".join(arn.split(":")[0:-1])
|
arn = ":".join(arn.split(":")[0:-1])
|
||||||
return self._arns.get(arn, None)
|
return self._arns.get(arn, None)
|
||||||
|
|
||||||
def get_function_by_name_or_arn(self, name_or_arn, qualifier=None):
|
def get_function_by_name_or_arn(
|
||||||
|
self, name_or_arn, qualifier=None
|
||||||
|
) -> LambdaFunction:
|
||||||
fn = self.get_function_by_name(name_or_arn, qualifier) or self.get_arn(
|
fn = self.get_function_by_name(name_or_arn, qualifier) or self.get_arn(
|
||||||
name_or_arn
|
name_or_arn
|
||||||
)
|
)
|
||||||
@ -1409,6 +1455,37 @@ class LambdaBackend(BaseBackend):
|
|||||||
fn.version = ver.version
|
fn.version = ver.version
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
def create_function_url_config(self, name_or_arn, config):
|
||||||
|
"""
|
||||||
|
The Qualifier-parameter is not yet implemented.
|
||||||
|
Function URLs are not yet mocked, so invoking them will fail
|
||||||
|
"""
|
||||||
|
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||||
|
return function.create_url_config(config)
|
||||||
|
|
||||||
|
def delete_function_url_config(self, name_or_arn):
|
||||||
|
"""
|
||||||
|
The Qualifier-parameter is not yet implemented
|
||||||
|
"""
|
||||||
|
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||||
|
function.delete_url_config()
|
||||||
|
|
||||||
|
def get_function_url_config(self, name_or_arn):
|
||||||
|
"""
|
||||||
|
The Qualifier-parameter is not yet implemented
|
||||||
|
"""
|
||||||
|
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||||
|
if not function:
|
||||||
|
raise UnknownFunctionException(arn=name_or_arn)
|
||||||
|
return function.get_url_config()
|
||||||
|
|
||||||
|
def update_function_url_config(self, name_or_arn, config):
|
||||||
|
"""
|
||||||
|
The Qualifier-parameter is not yet implemented
|
||||||
|
"""
|
||||||
|
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||||
|
return function.update_url_config(config)
|
||||||
|
|
||||||
def create_event_source_mapping(self, spec):
|
def create_event_source_mapping(self, spec):
|
||||||
required = ["EventSourceArn", "FunctionName"]
|
required = ["EventSourceArn", "FunctionName"]
|
||||||
for param in required:
|
for param in required:
|
||||||
|
@ -188,6 +188,19 @@ class LambdaResponse(BaseResponse):
|
|||||||
else:
|
else:
|
||||||
raise ValueError("Cannot handle request")
|
raise ValueError("Cannot handle request")
|
||||||
|
|
||||||
|
def function_url_config(self, request, full_url, headers):
|
||||||
|
http_method = request.method
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
|
if http_method == "DELETE":
|
||||||
|
return self._delete_function_url_config()
|
||||||
|
elif http_method == "GET":
|
||||||
|
return self._get_function_url_config()
|
||||||
|
elif http_method == "POST":
|
||||||
|
return self._create_function_url_config()
|
||||||
|
elif http_method == "PUT":
|
||||||
|
return self._update_function_url_config()
|
||||||
|
|
||||||
def _add_policy(self, request):
|
def _add_policy(self, request):
|
||||||
path = request.path if hasattr(request, "path") else path_url(request.url)
|
path = request.path if hasattr(request, "path") else path_url(request.url)
|
||||||
function_name = unquote(path.split("/")[-2])
|
function_name = unquote(path.split("/")[-2])
|
||||||
@ -284,6 +297,26 @@ class LambdaResponse(BaseResponse):
|
|||||||
config = fn.get_configuration(on_create=True)
|
config = fn.get_configuration(on_create=True)
|
||||||
return 201, {}, json.dumps(config)
|
return 201, {}, json.dumps(config)
|
||||||
|
|
||||||
|
def _create_function_url_config(self):
|
||||||
|
function_name = unquote(self.path.split("/")[-2])
|
||||||
|
config = self.backend.create_function_url_config(function_name, self.json_body)
|
||||||
|
return 201, {}, json.dumps(config.to_dict())
|
||||||
|
|
||||||
|
def _delete_function_url_config(self):
|
||||||
|
function_name = unquote(self.path.split("/")[-2])
|
||||||
|
self.backend.delete_function_url_config(function_name)
|
||||||
|
return 204, {}, "{}"
|
||||||
|
|
||||||
|
def _get_function_url_config(self):
|
||||||
|
function_name = unquote(self.path.split("/")[-2])
|
||||||
|
config = self.backend.get_function_url_config(function_name)
|
||||||
|
return 201, {}, json.dumps(config.to_dict())
|
||||||
|
|
||||||
|
def _update_function_url_config(self):
|
||||||
|
function_name = unquote(self.path.split("/")[-2])
|
||||||
|
config = self.backend.update_function_url_config(function_name, self.json_body)
|
||||||
|
return 200, {}, json.dumps(config.to_dict())
|
||||||
|
|
||||||
def _create_event_source_mapping(self):
|
def _create_event_source_mapping(self):
|
||||||
fn = self.backend.create_event_source_mapping(self.json_body)
|
fn = self.backend.create_event_source_mapping(self.json_body)
|
||||||
config = fn.get_configuration()
|
config = fn.get_configuration()
|
||||||
|
@ -22,6 +22,7 @@ url_paths = {
|
|||||||
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code/?$": response.code,
|
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code/?$": response.code,
|
||||||
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code-signing-config$": response.code_signing_config,
|
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code-signing-config$": response.code_signing_config,
|
||||||
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/concurrency/?$": response.function_concurrency,
|
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/concurrency/?$": response.function_concurrency,
|
||||||
|
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/url/?$": response.function_url_config,
|
||||||
r"{0}/(?P<api_version>[^/]+)/layers/?$": response.list_layers,
|
r"{0}/(?P<api_version>[^/]+)/layers/?$": response.list_layers,
|
||||||
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>[\w_-]+)/versions/?$": response.layers_versions,
|
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>[\w_-]+)/versions/?$": response.layers_versions,
|
||||||
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>[\w_-]+)/versions/(?P<layer_version>[\w_-]+)$": response.layers_version,
|
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>[\w_-]+)/versions/(?P<layer_version>[\w_-]+)$": response.layers_version,
|
||||||
|
@ -140,6 +140,7 @@ kms:
|
|||||||
lambda:
|
lambda:
|
||||||
- TestAccLambdaAlias_
|
- TestAccLambdaAlias_
|
||||||
- TestAccLambdaLayerVersion_
|
- TestAccLambdaLayerVersion_
|
||||||
|
- TestAccLambdaFunctionURL
|
||||||
meta:
|
meta:
|
||||||
- TestAccMetaBillingServiceAccountDataSource
|
- TestAccMetaBillingServiceAccountDataSource
|
||||||
mq:
|
mq:
|
||||||
|
125
tests/test_awslambda/test_lambda_function_urls.py
Normal file
125
tests/test_awslambda/test_lambda_function_urls.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import boto3
|
||||||
|
import pytest
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
from moto import mock_lambda
|
||||||
|
from uuid import uuid4
|
||||||
|
from .utilities import get_test_zip_file1, get_role_name
|
||||||
|
|
||||||
|
|
||||||
|
@mock_lambda
|
||||||
|
@pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"])
|
||||||
|
def test_create_function_url_config(key):
|
||||||
|
client = boto3.client("lambda", "us-east-2")
|
||||||
|
function_name = str(uuid4())[0:6]
|
||||||
|
fxn = client.create_function(
|
||||||
|
FunctionName=function_name,
|
||||||
|
Runtime="python3.7",
|
||||||
|
Role=get_role_name(),
|
||||||
|
Handler="lambda_function.lambda_handler",
|
||||||
|
Code={"ZipFile": get_test_zip_file1()},
|
||||||
|
)
|
||||||
|
name_or_arn = fxn[key]
|
||||||
|
|
||||||
|
resp = client.create_function_url_config(
|
||||||
|
AuthType="AWS_IAM", FunctionName=name_or_arn
|
||||||
|
)
|
||||||
|
resp.should.have.key("FunctionArn").equals(fxn["FunctionArn"])
|
||||||
|
resp.should.have.key("AuthType").equals("AWS_IAM")
|
||||||
|
resp.should.have.key("FunctionUrl")
|
||||||
|
|
||||||
|
resp = client.get_function_url_config(FunctionName=name_or_arn)
|
||||||
|
resp.should.have.key("FunctionArn").equals(fxn["FunctionArn"])
|
||||||
|
resp.should.have.key("AuthType").equals("AWS_IAM")
|
||||||
|
resp.should.have.key("FunctionUrl")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_lambda
|
||||||
|
def test_create_function_url_config_with_cors():
|
||||||
|
client = boto3.client("lambda", "us-east-2")
|
||||||
|
function_name = str(uuid4())[0:6]
|
||||||
|
fxn = client.create_function(
|
||||||
|
FunctionName=function_name,
|
||||||
|
Runtime="python3.7",
|
||||||
|
Role=get_role_name(),
|
||||||
|
Handler="lambda_function.lambda_handler",
|
||||||
|
Code={"ZipFile": get_test_zip_file1()},
|
||||||
|
)
|
||||||
|
name_or_arn = fxn["FunctionName"]
|
||||||
|
|
||||||
|
resp = client.create_function_url_config(
|
||||||
|
AuthType="AWS_IAM",
|
||||||
|
FunctionName=name_or_arn,
|
||||||
|
Cors={
|
||||||
|
"AllowCredentials": True,
|
||||||
|
"AllowHeaders": ["date", "keep-alive"],
|
||||||
|
"AllowMethods": ["*"],
|
||||||
|
"AllowOrigins": ["*"],
|
||||||
|
"ExposeHeaders": ["date", "keep-alive"],
|
||||||
|
"MaxAge": 86400,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
resp.should.have.key("Cors").equals(
|
||||||
|
{
|
||||||
|
"AllowCredentials": True,
|
||||||
|
"AllowHeaders": ["date", "keep-alive"],
|
||||||
|
"AllowMethods": ["*"],
|
||||||
|
"AllowOrigins": ["*"],
|
||||||
|
"ExposeHeaders": ["date", "keep-alive"],
|
||||||
|
"MaxAge": 86400,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_lambda
|
||||||
|
def test_update_function_url_config_with_cors():
|
||||||
|
client = boto3.client("lambda", "us-east-2")
|
||||||
|
function_name = str(uuid4())[0:6]
|
||||||
|
fxn = client.create_function(
|
||||||
|
FunctionName=function_name,
|
||||||
|
Runtime="python3.7",
|
||||||
|
Role=get_role_name(),
|
||||||
|
Handler="lambda_function.lambda_handler",
|
||||||
|
Code={"ZipFile": get_test_zip_file1()},
|
||||||
|
)
|
||||||
|
name_or_arn = fxn["FunctionName"]
|
||||||
|
|
||||||
|
resp = client.create_function_url_config(
|
||||||
|
AuthType="AWS_IAM",
|
||||||
|
FunctionName=name_or_arn,
|
||||||
|
Cors={
|
||||||
|
"AllowCredentials": True,
|
||||||
|
"AllowHeaders": ["date", "keep-alive"],
|
||||||
|
"AllowMethods": ["*"],
|
||||||
|
"AllowOrigins": ["*"],
|
||||||
|
"ExposeHeaders": ["date", "keep-alive"],
|
||||||
|
"MaxAge": 86400,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = client.update_function_url_config(
|
||||||
|
FunctionName=name_or_arn, AuthType="NONE", Cors={"AllowCredentials": False}
|
||||||
|
)
|
||||||
|
resp.should.have.key("Cors").equals({"AllowCredentials": False})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_lambda
|
||||||
|
@pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"])
|
||||||
|
def test_delete_function_url_config(key):
|
||||||
|
client = boto3.client("lambda", "us-east-2")
|
||||||
|
function_name = str(uuid4())[0:6]
|
||||||
|
fxn = client.create_function(
|
||||||
|
FunctionName=function_name,
|
||||||
|
Runtime="python3.7",
|
||||||
|
Role=get_role_name(),
|
||||||
|
Handler="lambda_function.lambda_handler",
|
||||||
|
Code={"ZipFile": get_test_zip_file1()},
|
||||||
|
)
|
||||||
|
name_or_arn = fxn[key]
|
||||||
|
|
||||||
|
client.create_function_url_config(AuthType="AWS_IAM", FunctionName=name_or_arn)
|
||||||
|
|
||||||
|
client.delete_function_url_config(FunctionName=name_or_arn)
|
||||||
|
|
||||||
|
# It no longer exists
|
||||||
|
with pytest.raises(ClientError):
|
||||||
|
client.get_function_url_config(FunctionName=name_or_arn)
|
Loading…
Reference in New Issue
Block a user