OrganizationUnitManager.java

  1. /*
  2.  * This file is part of the pl.wrzasq.lambda.
  3.  *
  4.  * @license http://mit-license.org/ The MIT license
  5.  * @copyright 2019 © by Rafał Wrzeszcz - Wrzasq.pl.
  6.  */

  7. package pl.wrzasq.lambda.cform.organization.unit.service;

  8. import com.amazonaws.services.organizations.AWSOrganizations;
  9. import com.amazonaws.services.organizations.model.ChildNotFoundException;
  10. import com.amazonaws.services.organizations.model.CreateOrganizationalUnitRequest;
  11. import com.amazonaws.services.organizations.model.DeleteOrganizationalUnitRequest;
  12. import com.amazonaws.services.organizations.model.ListParentsRequest;
  13. import com.amazonaws.services.organizations.model.OrganizationalUnit;
  14. import com.amazonaws.services.organizations.model.UpdateOrganizationalUnitRequest;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import pl.wrzasq.commons.aws.cloudformation.CustomResourceResponse;
  18. import pl.wrzasq.lambda.cform.organization.unit.model.OrganizationUnitRequest;

  19. /**
  20.  * Organizations API implementation.
  21.  */
  22. public class OrganizationUnitManager {
  23.     /**
  24.      * Logger.
  25.      */
  26.     private Logger logger = LoggerFactory.getLogger(OrganizationUnitManager.class);

  27.     /**
  28.      * AWS Organizations API client.
  29.      */
  30.     private AWSOrganizations organizations;

  31.     /**
  32.      * Initializes object with given Organizations client.
  33.      *
  34.      * @param organizations AWS Organizations client.
  35.      */
  36.     public OrganizationUnitManager(AWSOrganizations organizations) {
  37.         this.organizations = organizations;
  38.     }

  39.     /**
  40.      * Handles organization creation.
  41.      *
  42.      * @param input Resource creation request.
  43.      * @param physicalResourceId Physical ID of existing resource (if present).
  44.      * @return Data about published version.
  45.      */
  46.     public CustomResourceResponse<OrganizationalUnit> sync(OrganizationUnitRequest input, String physicalResourceId) {
  47.         // check if the parent ID got changed
  48.         if (physicalResourceId != null) {
  49.             try {
  50.                 var parent = this.organizations.listParents(
  51.                     new ListParentsRequest()
  52.                         .withChildId(physicalResourceId)
  53.                 )
  54.                     .getParents()
  55.                     .get(0);

  56.                 // organizational unit can only be renamed, change of parent will require creation of new unit
  57.                 if (!input.getParentId().equals(parent.getId())) {
  58.                     this.logger.info(
  59.                         "Organizational Unit with ID {} was requested to be placed in a different parent."
  60.                             + " This will cause it to be re-created."
  61.                             + " Old parent ID: {}, new parent ID: {}.",
  62.                         physicalResourceId,
  63.                         parent.getId(),
  64.                         input.getParentId()
  65.                     );

  66.                     physicalResourceId = null;
  67.                 }
  68.             } catch (ChildNotFoundException error) {
  69.                 // it's fine, we will just create new one
  70.                 this.logger.warn("Organizational Unit with ID {} not found, creating new one.", physicalResourceId);

  71.                 physicalResourceId = null;
  72.             }
  73.         }

  74.         var unit = physicalResourceId == null
  75.             ? this.organizations.createOrganizationalUnit(
  76.                 new CreateOrganizationalUnitRequest()
  77.                     .withName(input.getName())
  78.                     .withParentId(input.getParentId())
  79.             )
  80.                 .getOrganizationalUnit()
  81.             : this.organizations.updateOrganizationalUnit(
  82.                 new UpdateOrganizationalUnitRequest()
  83.                     .withOrganizationalUnitId(physicalResourceId)
  84.                     .withName(input.getName())
  85.             )
  86.                 .getOrganizationalUnit();

  87.         return new CustomResourceResponse<>(unit, unit.getId());
  88.     }

  89.     /**
  90.      * Handles organization unit deletion.
  91.      *
  92.      * @param input Resource delete request.
  93.      * @param physicalResourceId Physical ID of existing resource (if present).
  94.      * @return Empty response.
  95.      */
  96.     public CustomResourceResponse<OrganizationalUnit> delete(OrganizationUnitRequest input, String physicalResourceId) {
  97.         this.organizations.deleteOrganizationalUnit(
  98.             new DeleteOrganizationalUnitRequest()
  99.                 .withOrganizationalUnitId(physicalResourceId)
  100.         );

  101.         this.logger.info("Organizational unit {} deleted.", physicalResourceId);

  102.         return new CustomResourceResponse<>(null, physicalResourceId);
  103.     }
  104. }