Merge pull request #2927 from apalumbo/master
Api gateway api get_usage_plan and get_usage_plan_key revised to handle missing values
This commit is contained in:
commit
9410daa28c
@ -112,6 +112,15 @@ class ApiKeyNotFoundException(RESTError):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UsagePlanNotFoundException(RESTError):
|
||||||
|
code = 404
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(UsagePlanNotFoundException, self).__init__(
|
||||||
|
"NotFoundException", "Invalid Usage Plan ID specified"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyAlreadyExists(RESTError):
|
class ApiKeyAlreadyExists(RESTError):
|
||||||
code = 409
|
code = 409
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ from moto.core.utils import path_url
|
|||||||
from moto.sts.models import ACCOUNT_ID
|
from moto.sts.models import ACCOUNT_ID
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
ApiKeyNotFoundException,
|
ApiKeyNotFoundException,
|
||||||
|
UsagePlanNotFoundException,
|
||||||
AwsProxyNotAllowed,
|
AwsProxyNotAllowed,
|
||||||
CrossAccountNotAllowed,
|
CrossAccountNotAllowed,
|
||||||
IntegrationMethodNotDefined,
|
IntegrationMethodNotDefined,
|
||||||
@ -1045,6 +1046,9 @@ class APIGatewayBackend(BaseBackend):
|
|||||||
return plans
|
return plans
|
||||||
|
|
||||||
def get_usage_plan(self, usage_plan_id):
|
def get_usage_plan(self, usage_plan_id):
|
||||||
|
if usage_plan_id not in self.usage_plans:
|
||||||
|
raise UsagePlanNotFoundException()
|
||||||
|
|
||||||
return self.usage_plans[usage_plan_id]
|
return self.usage_plans[usage_plan_id]
|
||||||
|
|
||||||
def delete_usage_plan(self, usage_plan_id):
|
def delete_usage_plan(self, usage_plan_id):
|
||||||
@ -1077,6 +1081,17 @@ class APIGatewayBackend(BaseBackend):
|
|||||||
return list(self.usage_plan_keys[usage_plan_id].values())
|
return list(self.usage_plan_keys[usage_plan_id].values())
|
||||||
|
|
||||||
def get_usage_plan_key(self, usage_plan_id, key_id):
|
def get_usage_plan_key(self, usage_plan_id, key_id):
|
||||||
|
# first check if is a valid api key
|
||||||
|
if key_id not in self.keys:
|
||||||
|
raise ApiKeyNotFoundException()
|
||||||
|
|
||||||
|
# then check if is a valid api key and that the key is in the plan
|
||||||
|
if (
|
||||||
|
usage_plan_id not in self.usage_plan_keys
|
||||||
|
or key_id not in self.usage_plan_keys[usage_plan_id]
|
||||||
|
):
|
||||||
|
raise UsagePlanNotFoundException()
|
||||||
|
|
||||||
return self.usage_plan_keys[usage_plan_id][key_id]
|
return self.usage_plan_keys[usage_plan_id][key_id]
|
||||||
|
|
||||||
def delete_usage_plan_key(self, usage_plan_id, key_id):
|
def delete_usage_plan_key(self, usage_plan_id, key_id):
|
||||||
|
@ -6,6 +6,7 @@ from moto.core.responses import BaseResponse
|
|||||||
from .models import apigateway_backends
|
from .models import apigateway_backends
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
ApiKeyNotFoundException,
|
ApiKeyNotFoundException,
|
||||||
|
UsagePlanNotFoundException,
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
CrossAccountNotAllowed,
|
CrossAccountNotAllowed,
|
||||||
AuthorizerNotFoundException,
|
AuthorizerNotFoundException,
|
||||||
@ -490,7 +491,16 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
usage_plan = url_path_parts[2]
|
usage_plan = url_path_parts[2]
|
||||||
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
usage_plan_response = self.backend.get_usage_plan(usage_plan)
|
try:
|
||||||
|
usage_plan_response = self.backend.get_usage_plan(usage_plan)
|
||||||
|
except (UsagePlanNotFoundException) as error:
|
||||||
|
return (
|
||||||
|
error.code,
|
||||||
|
{},
|
||||||
|
'{{"message":"{0}","code":"{1}"}}'.format(
|
||||||
|
error.message, error.error_type
|
||||||
|
),
|
||||||
|
)
|
||||||
elif self.method == "DELETE":
|
elif self.method == "DELETE":
|
||||||
usage_plan_response = self.backend.delete_usage_plan(usage_plan)
|
usage_plan_response = self.backend.delete_usage_plan(usage_plan)
|
||||||
return 200, {}, json.dumps(usage_plan_response)
|
return 200, {}, json.dumps(usage_plan_response)
|
||||||
@ -529,7 +539,18 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
key_id = url_path_parts[4]
|
key_id = url_path_parts[4]
|
||||||
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
usage_plan_response = self.backend.get_usage_plan_key(usage_plan_id, key_id)
|
try:
|
||||||
|
usage_plan_response = self.backend.get_usage_plan_key(
|
||||||
|
usage_plan_id, key_id
|
||||||
|
)
|
||||||
|
except (UsagePlanNotFoundException, ApiKeyNotFoundException) as error:
|
||||||
|
return (
|
||||||
|
error.code,
|
||||||
|
{},
|
||||||
|
'{{"message":"{0}","code":"{1}"}}'.format(
|
||||||
|
error.message, error.error_type
|
||||||
|
),
|
||||||
|
)
|
||||||
elif self.method == "DELETE":
|
elif self.method == "DELETE":
|
||||||
usage_plan_response = self.backend.delete_usage_plan_key(
|
usage_plan_response = self.backend.delete_usage_plan_key(
|
||||||
usage_plan_id, key_id
|
usage_plan_id, key_id
|
||||||
|
@ -1797,6 +1797,14 @@ def test_usage_plans():
|
|||||||
response = client.get_usage_plans()
|
response = client.get_usage_plans()
|
||||||
len(response["items"]).should.equal(0)
|
len(response["items"]).should.equal(0)
|
||||||
|
|
||||||
|
# # Try to get info about a non existing usage
|
||||||
|
with assert_raises(ClientError) as ex:
|
||||||
|
client.get_usage_plan(usagePlanId="not_existing")
|
||||||
|
ex.exception.response["Error"]["Code"].should.equal("NotFoundException")
|
||||||
|
ex.exception.response["Error"]["Message"].should.equal(
|
||||||
|
"Invalid Usage Plan ID specified"
|
||||||
|
)
|
||||||
|
|
||||||
usage_plan_name = "TEST-PLAN"
|
usage_plan_name = "TEST-PLAN"
|
||||||
payload = {"name": usage_plan_name}
|
payload = {"name": usage_plan_name}
|
||||||
response = client.create_usage_plan(**payload)
|
response = client.create_usage_plan(**payload)
|
||||||
@ -1879,6 +1887,30 @@ def test_usage_plan_keys():
|
|||||||
response = client.get_usage_plan_keys(usagePlanId=usage_plan_id)
|
response = client.get_usage_plan_keys(usagePlanId=usage_plan_id)
|
||||||
len(response["items"]).should.equal(0)
|
len(response["items"]).should.equal(0)
|
||||||
|
|
||||||
|
# Try to get info about a non existing api key
|
||||||
|
with assert_raises(ClientError) as ex:
|
||||||
|
client.get_usage_plan_key(usagePlanId=usage_plan_id, keyId="not_existing_key")
|
||||||
|
ex.exception.response["Error"]["Code"].should.equal("NotFoundException")
|
||||||
|
ex.exception.response["Error"]["Message"].should.equal(
|
||||||
|
"Invalid API Key identifier specified"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Try to get info about an existing api key that has not jet added to a valid usage plan
|
||||||
|
with assert_raises(ClientError) as ex:
|
||||||
|
client.get_usage_plan_key(usagePlanId=usage_plan_id, keyId=key_id)
|
||||||
|
ex.exception.response["Error"]["Code"].should.equal("NotFoundException")
|
||||||
|
ex.exception.response["Error"]["Message"].should.equal(
|
||||||
|
"Invalid Usage Plan ID specified"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Try to get info about an existing api key that has not jet added to a valid usage plan
|
||||||
|
with assert_raises(ClientError) as ex:
|
||||||
|
client.get_usage_plan_key(usagePlanId="not_existing_plan_id", keyId=key_id)
|
||||||
|
ex.exception.response["Error"]["Code"].should.equal("NotFoundException")
|
||||||
|
ex.exception.response["Error"]["Message"].should.equal(
|
||||||
|
"Invalid Usage Plan ID specified"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_apigateway
|
@mock_apigateway
|
||||||
def test_create_usage_plan_key_non_existent_api_key():
|
def test_create_usage_plan_key_non_existent_api_key():
|
||||||
|
@ -39,6 +39,10 @@ def test_usage_plans_apis():
|
|||||||
fetched_plan = json.loads(res.data)
|
fetched_plan = json.loads(res.data)
|
||||||
fetched_plan.should.equal(created_plan)
|
fetched_plan.should.equal(created_plan)
|
||||||
|
|
||||||
|
# Not existing usage plan
|
||||||
|
res = test_client.get("/usageplans/{0}".format("not_existing"))
|
||||||
|
res.status_code.should.equal(404)
|
||||||
|
|
||||||
# Delete usage plan
|
# Delete usage plan
|
||||||
res = test_client.delete("/usageplans/{0}".format(created_plan["id"]))
|
res = test_client.delete("/usageplans/{0}".format(created_plan["id"]))
|
||||||
res.data.should.equal(b"{}")
|
res.data.should.equal(b"{}")
|
||||||
@ -61,6 +65,24 @@ def test_usage_plans_keys():
|
|||||||
res = test_client.get("/usageplans/{0}/keys".format(usage_plan_id))
|
res = test_client.get("/usageplans/{0}/keys".format(usage_plan_id))
|
||||||
json.loads(res.data)["item"].should.have.length_of(0)
|
json.loads(res.data)["item"].should.have.length_of(0)
|
||||||
|
|
||||||
|
# Invalid api key (does not exists at all)
|
||||||
|
res = test_client.get(
|
||||||
|
"/usageplans/{0}/keys/{1}".format(usage_plan_id, "not_existing")
|
||||||
|
)
|
||||||
|
res.status_code.should.equal(404)
|
||||||
|
|
||||||
|
# not existing usage plan with existing api key
|
||||||
|
res = test_client.get(
|
||||||
|
"/usageplans/{0}/keys/{1}".format("not_existing", created_api_key["id"])
|
||||||
|
)
|
||||||
|
res.status_code.should.equal(404)
|
||||||
|
|
||||||
|
# not jet added api key
|
||||||
|
res = test_client.get(
|
||||||
|
"/usageplans/{0}/keys/{1}".format(usage_plan_id, created_api_key["id"])
|
||||||
|
)
|
||||||
|
res.status_code.should.equal(404)
|
||||||
|
|
||||||
# Create usage plan key
|
# Create usage plan key
|
||||||
res = test_client.post(
|
res = test_client.post(
|
||||||
"/usageplans/{0}/keys".format(usage_plan_id),
|
"/usageplans/{0}/keys".format(usage_plan_id),
|
||||||
|
Loading…
Reference in New Issue
Block a user