Add codepipeline.update_pipeline
This commit is contained in:
parent
c84e465e4c
commit
b2c44ce50d
@ -1263,7 +1263,7 @@
|
|||||||
- [ ] update_deployment_group
|
- [ ] update_deployment_group
|
||||||
|
|
||||||
## codepipeline
|
## codepipeline
|
||||||
5% implemented
|
8% implemented
|
||||||
- [ ] acknowledge_job
|
- [ ] acknowledge_job
|
||||||
- [ ] acknowledge_third_party_job
|
- [ ] acknowledge_third_party_job
|
||||||
- [ ] create_custom_action_type
|
- [ ] create_custom_action_type
|
||||||
@ -1299,7 +1299,7 @@
|
|||||||
- [ ] start_pipeline_execution
|
- [ ] start_pipeline_execution
|
||||||
- [ ] tag_resource
|
- [ ] tag_resource
|
||||||
- [ ] untag_resource
|
- [ ] untag_resource
|
||||||
- [ ] update_pipeline
|
- [X] update_pipeline
|
||||||
|
|
||||||
## codestar
|
## codestar
|
||||||
0% implemented
|
0% implemented
|
||||||
|
@ -17,3 +17,12 @@ class PipelineNotFoundException(JsonRESTError):
|
|||||||
super(PipelineNotFoundException, self).__init__(
|
super(PipelineNotFoundException, self).__init__(
|
||||||
"PipelineNotFoundException", message
|
"PipelineNotFoundException", message
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceNotFoundException(JsonRESTError):
|
||||||
|
code = 400
|
||||||
|
|
||||||
|
def __init__(self, message):
|
||||||
|
super(ResourceNotFoundException, self).__init__(
|
||||||
|
"ResourceNotFoundException", message
|
||||||
|
)
|
||||||
|
@ -11,6 +11,7 @@ from moto.iam import iam_backends
|
|||||||
from moto.codepipeline.exceptions import (
|
from moto.codepipeline.exceptions import (
|
||||||
InvalidStructureException,
|
InvalidStructureException,
|
||||||
PipelineNotFoundException,
|
PipelineNotFoundException,
|
||||||
|
ResourceNotFoundException,
|
||||||
)
|
)
|
||||||
from moto.core import BaseBackend, BaseModel
|
from moto.core import BaseBackend, BaseModel
|
||||||
|
|
||||||
@ -19,7 +20,10 @@ DEFAULT_ACCOUNT_ID = "123456789012"
|
|||||||
|
|
||||||
class CodePipeline(BaseModel):
|
class CodePipeline(BaseModel):
|
||||||
def __init__(self, region, pipeline):
|
def __init__(self, region, pipeline):
|
||||||
self.pipeline = self._add_default_values(pipeline)
|
# the version number for a new pipeline is always 1
|
||||||
|
pipeline["version"] = 1
|
||||||
|
|
||||||
|
self.pipeline = self.add_default_values(pipeline)
|
||||||
self.tags = {}
|
self.tags = {}
|
||||||
|
|
||||||
self._arn = "arn:aws:codepipeline:{0}:{1}:{2}".format(
|
self._arn = "arn:aws:codepipeline:{0}:{1}:{2}".format(
|
||||||
@ -36,7 +40,7 @@ class CodePipeline(BaseModel):
|
|||||||
"updated": iso_8601_datetime_with_milliseconds(self._updated),
|
"updated": iso_8601_datetime_with_milliseconds(self._updated),
|
||||||
}
|
}
|
||||||
|
|
||||||
def _add_default_values(self, pipeline):
|
def add_default_values(self, pipeline):
|
||||||
for stage in pipeline["stages"]:
|
for stage in pipeline["stages"]:
|
||||||
for action in stage["actions"]:
|
for action in stage["actions"]:
|
||||||
if "runOrder" not in action:
|
if "runOrder" not in action:
|
||||||
@ -106,6 +110,23 @@ class CodePipelineBackend(BaseBackend):
|
|||||||
|
|
||||||
return codepipeline.pipeline, codepipeline.metadata
|
return codepipeline.pipeline, codepipeline.metadata
|
||||||
|
|
||||||
|
def update_pipeline(self, pipeline):
|
||||||
|
codepipeline = self.pipelines.get(pipeline["name"])
|
||||||
|
|
||||||
|
if not codepipeline:
|
||||||
|
raise ResourceNotFoundException(
|
||||||
|
"The account with id '{0}' does not include a pipeline with the name '{1}'".format(
|
||||||
|
DEFAULT_ACCOUNT_ID, pipeline["name"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# version number is auto incremented
|
||||||
|
pipeline["version"] = codepipeline.pipeline["version"] + 1
|
||||||
|
codepipeline._updated = datetime.utcnow()
|
||||||
|
codepipeline.pipeline = codepipeline.add_default_values(pipeline)
|
||||||
|
|
||||||
|
return codepipeline.pipeline
|
||||||
|
|
||||||
|
|
||||||
codepipeline_backends = {}
|
codepipeline_backends = {}
|
||||||
for region in Session().get_available_regions("codepipeline"):
|
for region in Session().get_available_regions("codepipeline"):
|
||||||
|
@ -22,3 +22,10 @@ class CodePipelineResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return json.dumps({"pipeline": pipeline, "metadata": metadata})
|
return json.dumps({"pipeline": pipeline, "metadata": metadata})
|
||||||
|
|
||||||
|
def update_pipeline(self):
|
||||||
|
pipeline = self.codepipeline_backend.update_pipeline(
|
||||||
|
self._get_param("pipeline")
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.dumps({"pipeline": pipeline})
|
||||||
|
@ -110,6 +110,7 @@ def test_create_pipeline():
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"version": 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
response["tags"].should.equal([{"key": "key", "value": "value"}])
|
response["tags"].should.equal([{"key": "key", "value": "value"}])
|
||||||
@ -447,6 +448,7 @@ def test_get_pipeline():
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"version": 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
response["metadata"].should.equal(
|
response["metadata"].should.equal(
|
||||||
@ -463,7 +465,7 @@ def test_get_pipeline_errors():
|
|||||||
client = boto3.client("codepipeline", region_name="us-east-1")
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||||
|
|
||||||
with assert_raises(ClientError) as e:
|
with assert_raises(ClientError) as e:
|
||||||
response = client.get_pipeline(name="not-existing")
|
client.get_pipeline(name="not-existing")
|
||||||
ex = e.exception
|
ex = e.exception
|
||||||
ex.operation_name.should.equal("GetPipeline")
|
ex.operation_name.should.equal("GetPipeline")
|
||||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||||
@ -473,6 +475,229 @@ def test_get_pipeline_errors():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_codepipeline
|
||||||
|
def test_update_pipeline():
|
||||||
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||||
|
role_arn = get_role_arn()
|
||||||
|
with freeze_time("2019-01-01 12:00:00"):
|
||||||
|
created_time = datetime.now(timezone.utc)
|
||||||
|
client.create_pipeline(
|
||||||
|
pipeline={
|
||||||
|
"name": "test-pipeline",
|
||||||
|
"roleArn": role_arn,
|
||||||
|
"artifactStore": {
|
||||||
|
"type": "S3",
|
||||||
|
"location": "codepipeline-us-east-1-123456789012",
|
||||||
|
},
|
||||||
|
"stages": [
|
||||||
|
{
|
||||||
|
"name": "Stage-1",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Source",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "S3",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
"configuration": {
|
||||||
|
"S3Bucket": "test-bucket",
|
||||||
|
"S3ObjectKey": "test-object",
|
||||||
|
},
|
||||||
|
"outputArtifacts": [{"name": "artifact"},],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stage-2",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Approval",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "Manual",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
tags=[{"key": "key", "value": "value"}],
|
||||||
|
)
|
||||||
|
|
||||||
|
with freeze_time("2019-01-02 12:00:00"):
|
||||||
|
updated_time = datetime.now(timezone.utc)
|
||||||
|
response = client.update_pipeline(
|
||||||
|
pipeline={
|
||||||
|
"name": "test-pipeline",
|
||||||
|
"roleArn": role_arn,
|
||||||
|
"artifactStore": {
|
||||||
|
"type": "S3",
|
||||||
|
"location": "codepipeline-us-east-1-123456789012",
|
||||||
|
},
|
||||||
|
"stages": [
|
||||||
|
{
|
||||||
|
"name": "Stage-1",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Source",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "S3",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
"configuration": {
|
||||||
|
"S3Bucket": "different-bucket",
|
||||||
|
"S3ObjectKey": "test-object",
|
||||||
|
},
|
||||||
|
"outputArtifacts": [{"name": "artifact"},],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stage-2",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Approval",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "Manual",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
response["pipeline"].should.equal(
|
||||||
|
{
|
||||||
|
"name": "test-pipeline",
|
||||||
|
"roleArn": "arn:aws:iam::123456789012:role/test-role",
|
||||||
|
"artifactStore": {
|
||||||
|
"type": "S3",
|
||||||
|
"location": "codepipeline-us-east-1-123456789012",
|
||||||
|
},
|
||||||
|
"stages": [
|
||||||
|
{
|
||||||
|
"name": "Stage-1",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Source",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "S3",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
"runOrder": 1,
|
||||||
|
"configuration": {
|
||||||
|
"S3Bucket": "different-bucket",
|
||||||
|
"S3ObjectKey": "test-object",
|
||||||
|
},
|
||||||
|
"outputArtifacts": [{"name": "artifact"}],
|
||||||
|
"inputArtifacts": [],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stage-2",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Approval",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "Manual",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
"runOrder": 1,
|
||||||
|
"configuration": {},
|
||||||
|
"outputArtifacts": [],
|
||||||
|
"inputArtifacts": [],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"version": 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_pipeline(name="test-pipeline")
|
||||||
|
response["metadata"].should.equal(
|
||||||
|
{
|
||||||
|
"pipelineArn": "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline",
|
||||||
|
"created": created_time,
|
||||||
|
"updated": updated_time,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_codepipeline
|
||||||
|
def test_update_pipeline_errors():
|
||||||
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
||||||
|
|
||||||
|
with assert_raises(ClientError) as e:
|
||||||
|
client.update_pipeline(
|
||||||
|
pipeline={
|
||||||
|
"name": "not-existing",
|
||||||
|
"roleArn": get_role_arn(),
|
||||||
|
"artifactStore": {
|
||||||
|
"type": "S3",
|
||||||
|
"location": "codepipeline-us-east-1-123456789012",
|
||||||
|
},
|
||||||
|
"stages": [
|
||||||
|
{
|
||||||
|
"name": "Stage-1",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Source",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "S3",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
"configuration": {
|
||||||
|
"S3Bucket": "test-bucket",
|
||||||
|
"S3ObjectKey": "test-object",
|
||||||
|
},
|
||||||
|
"outputArtifacts": [{"name": "artifact"},],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stage-2",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Action-1",
|
||||||
|
"actionTypeId": {
|
||||||
|
"category": "Approval",
|
||||||
|
"owner": "AWS",
|
||||||
|
"provider": "Manual",
|
||||||
|
"version": "1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ex = e.exception
|
||||||
|
ex.operation_name.should.equal("UpdatePipeline")
|
||||||
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||||
|
ex.response["Error"]["Code"].should.contain("ResourceNotFoundException")
|
||||||
|
ex.response["Error"]["Message"].should.equal(
|
||||||
|
"The account with id '123456789012' does not include a pipeline with the name 'not-existing'"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
def get_role_arn():
|
def get_role_arn():
|
||||||
iam = boto3.client("iam", region_name="us-east-1")
|
iam = boto3.client("iam", region_name="us-east-1")
|
||||||
|
Loading…
Reference in New Issue
Block a user