-
Notifications
You must be signed in to change notification settings - Fork 47
[codegen] adding best practice to update tags #327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,9 +12,11 @@ | |
import software.amazon.cloudformation.proxy.ProgressEvent; | ||
import software.amazon.cloudformation.proxy.ProxyClient; | ||
import software.amazon.cloudformation.proxy.ResourceHandlerRequest; | ||
import software.amazon.cloudformation.proxy.HandlerErrorCode; | ||
|
||
public class UpdateHandler extends BaseHandlerStd { | ||
private Logger logger; | ||
private static final String ACCESS_DENIED_EXCEPTION_MESSAGE = "not authorized"; | ||
|
||
protected ProgressEvent<ResourceModel, CallbackContext> handleRequest( | ||
final AmazonWebServicesClientProxy proxy, | ||
|
@@ -25,6 +27,8 @@ protected ProgressEvent<ResourceModel, CallbackContext> handleRequest( | |
|
||
this.logger = logger; | ||
|
||
final ResourceModel previousModel = request.getPreviousResourceState(); | ||
|
||
// TODO: Adjust Progress Chain according to your implementation | ||
// https://github.com/aws-cloudformation/cloudformation-cli-java-plugin/blob/master/src/main/java/software/amazon/cloudformation/proxy/CallChain.java | ||
|
||
|
@@ -134,7 +138,84 @@ protected ProgressEvent<ResourceModel, CallbackContext> handleRequest( | |
}) | ||
.progress()) | ||
|
||
// STEP 4 [TODO: describe call/chain to return the resource model] | ||
// If your resource supports tags, then the following pattern is required to handle stack level tags via soft-failing pattern | ||
// STEP 4 [update stack level tags progress chain] | ||
.then(progress -> { | ||
|
||
// STEP 4.0 [initialize a proxy context] | ||
// Stack level tag update should not force user but rather be optional, as it is possible that stack execution role will not have | ||
// enough permissions to do so | ||
// step in a discrete call/stabilize chain to ensure the entire resource is provisioned as intended. | ||
ProgressEvent<ResourceModel, CallbackContext> event = proxy.initiate("{{ call_graph }}::{{ operation }}::stack-level-tags", proxyClient, progress.getResourceModel(), progress.getCallbackContext()) | ||
|
||
// STEP 4.1 [TODO: construct a body of a request] | ||
.translateToServiceRequest((model) -> Translator.translateToStackTagUpdateRequest(request.getPreviousResourceTags(), request.getDesiredResourceTags())) | ||
|
||
// STEP 4.2 [TODO: make an api call] | ||
.makeServiceCall((awsRequest, client) -> { | ||
AwsResponse awsResponse = null; | ||
try { | ||
|
||
// TODO: put your post update resource code here | ||
|
||
} catch (final AwsServiceException e) { | ||
/* | ||
* While the handler contract states that the handler must always return a progress event, | ||
* you may throw any instance of BaseHandlerException, as the wrapper map it to a progress event. | ||
* Each BaseHandlerException maps to a specific error code, and you should map service exceptions as closely as possible | ||
* to more specific error codes | ||
*/ | ||
throw new CfnGeneralServiceException(ResourceModel.TYPE_NAME, e); | ||
} | ||
|
||
logger.log(String.format("%s has successfully been updated.", ResourceModel.TYPE_NAME)); | ||
return awsResponse; | ||
}) | ||
.progress(); | ||
|
||
// STEP 4.3 [TODO: check if event 1) failed 2) error code is access denied] | ||
// if (event.isFailed() && ...) { | ||
// return progress; | ||
// } | ||
return event; | ||
}) | ||
|
||
// If your resource supports tags, then the following pattern is required to handle resource level tags | ||
// STEP 5 [update resource level tags progress chain] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused. Is the Step 4 and 5 are the same? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. step 4 has different translate request method - uses only stack tags: (model) -> Translator.translateToStackTagUpdateRequest(request.getPreviousResourceTags(), request.getDesiredResourceTags()) Step 5 has normal request translator - involves previous and current model .translateToServiceRequest((model) -> Translator.translateToResourceTagUpdateRequest(previousModel, model)) |
||
.then(progress -> | ||
|
||
// STEP 5.0 [initialize a proxy context] | ||
// Resource level tag update should force user to use right set of permissions | ||
// step in a discrete call/stabilize chain to ensure the entire resource is provisioned as intended. | ||
proxy.initiate("{{ call_graph }}::{{ operation }}::resource-level-tags", proxyClient, progress.getResourceModel(), progress.getCallbackContext()) | ||
|
||
// STEP 5.1 [TODO: construct a body of a request] | ||
.translateToServiceRequest((model) -> Translator.translateToResourceTagUpdateRequest(previousModel, model)) | ||
|
||
// STEP 5.2 [TODO: make an api call] | ||
.makeServiceCall((awsRequest, client) -> { | ||
AwsResponse awsResponse = null; | ||
try { | ||
|
||
// TODO: put your post update resource code here | ||
|
||
} catch (final AwsServiceException e) { | ||
/* | ||
* While the handler contract states that the handler must always return a progress event, | ||
* you may throw any instance of BaseHandlerException, as the wrapper map it to a progress event. | ||
* Each BaseHandlerException maps to a specific error code, and you should map service exceptions as closely as possible | ||
* to more specific error codes | ||
*/ | ||
throw new CfnGeneralServiceException(ResourceModel.TYPE_NAME, e); | ||
} | ||
|
||
logger.log(String.format("%s has successfully been updated.", ResourceModel.TYPE_NAME)); | ||
return awsResponse; | ||
}) | ||
.progress()) | ||
|
||
|
||
// STEP 6 [TODO: describe call/chain to return the resource model] | ||
.then(progress -> new ReadHandler().handleRequest(proxy, request, callbackContext, proxyClient, logger)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then why this is a soft-failing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stack level tags are not always intentional attachment by the customer so we dont really wanna enforce additional permissions when stack has not been changed on update