package alien4cloud.rest.orchestrator; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.Authorization; import java.util.List; import javax.annotation.Resource; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import alien4cloud.audit.annotation.Audit; import alien4cloud.model.orchestrators.locations.LocationResourceTemplate; import alien4cloud.orchestrators.locations.services.ILocationResourceService; import alien4cloud.rest.model.RestResponse; import alien4cloud.rest.model.RestResponseBuilder; import alien4cloud.rest.orchestrator.model.CreateLocationResourceTemplateRequest; import alien4cloud.rest.orchestrator.model.UpdateLocationResourceTemplatePropertyRequest; import alien4cloud.rest.orchestrator.model.UpdateLocationResourceTemplateRequest; import alien4cloud.tosca.properties.constraints.ConstraintUtil; import alien4cloud.tosca.properties.constraints.ConstraintUtil.ConstraintInformation; import alien4cloud.tosca.properties.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; import alien4cloud.tosca.properties.constraints.exception.ConstraintViolationException; import alien4cloud.utils.RestConstraintValidator; /** * Controller that manages resources for orchestrator's locations. */ @Slf4j @RestController @RequestMapping(value = {"/rest/orchestrators/{orchestratorId}/locations/{locationId}/resources", "/rest/v1/orchestrators/{orchestratorId}/locations/{locationId}/resources", "/rest/latest/orchestrators/{orchestratorId}/locations/{locationId}/resources"}, produces = MediaType.APPLICATION_JSON_VALUE) @Api(value = "Orchestrator Location Resources", description = "Manages locations for a given orchestrator.", authorizations = { @Authorization("ADMIN") }, position = 4400) public class LocationResourcesController { @Inject @Lazy(true) private ILocationResourceService locationResourceService; @ApiOperation(value = "Add resource template to a location.", authorizations = { @Authorization("ADMIN") }) @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasAuthority('ADMIN')") @Audit public RestResponse<LocationResourceTemplate> addResourceTemplate( @ApiParam(value = "Id of the orchestrator for which to add resource template.", required = true) @PathVariable String orchestratorId, @ApiParam(value = "Id of the location of the orchestrator to add resource template.", required = true) @PathVariable String locationId, @RequestBody CreateLocationResourceTemplateRequest resourceTemplateRequest) { LocationResourceTemplate createdTemplate = locationResourceService.addResourceTemplate(locationId, resourceTemplateRequest.getResourceName(), resourceTemplateRequest.getResourceType()); return RestResponseBuilder.<LocationResourceTemplate> builder().data(createdTemplate).build(); } @ApiOperation(value = "Delete location's resource.", authorizations = { @Authorization("ADMIN") }) @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) @PreAuthorize("hasAuthority('ADMIN')") @Audit public RestResponse<Void> deleteResourceTemplate( @ApiParam(value = "Id of the orchestrator for which to delete resource template.", required = true) @PathVariable String orchestratorId, @ApiParam(value = "Id of the location of the orchestrator to delete resource template.", required = true) @PathVariable String locationId, @ApiParam(value = "Id of the location's resource.", required = true) @PathVariable String id) { locationResourceService.deleteResourceTemplate(id); return RestResponseBuilder.<Void> builder().build(); } @ApiOperation(value = "Update location's resource.", authorizations = { @Authorization("ADMIN") }) @RequestMapping(value = "/{id}", method = RequestMethod.PUT) @PreAuthorize("hasAuthority('ADMIN')") @Audit public RestResponse<Void> updateResourceTemplate( @ApiParam(value = "Id of the orchestrator for which to update resource template.", required = true) @PathVariable String orchestratorId, @ApiParam(value = "Id of the location of the orchestrator to update resource template.", required = true) @PathVariable String locationId, @ApiParam(value = "Id of the location's resource.", required = true) @PathVariable String id, @RequestBody UpdateLocationResourceTemplateRequest mergeRequest) { locationResourceService.merge(mergeRequest, id); return RestResponseBuilder.<Void> builder().build(); } @ApiOperation(value = "Update location's resource's template property.", authorizations = { @Authorization("ADMIN") }) @RequestMapping(value = "/{id}/template/properties", method = RequestMethod.POST) @PreAuthorize("hasAuthority('ADMIN')") @Audit public RestResponse<ConstraintUtil.ConstraintInformation> updateResourceTemplateProperty( @ApiParam(value = "Id of the orchestrator for which to update resource template property.", required = true) @PathVariable String orchestratorId, @ApiParam(value = "Id of the location of the orchestrator to update resource template property.", required = true) @PathVariable String locationId, @ApiParam(value = "Id of the location's resource.", required = true) @PathVariable String id, @RequestBody UpdateLocationResourceTemplatePropertyRequest updateRequest) { try { locationResourceService.setTemplateProperty(id, updateRequest.getPropertyName(), updateRequest.getPropertyValue()); return RestResponseBuilder.<ConstraintUtil.ConstraintInformation> builder().build(); } catch (ConstraintValueDoNotMatchPropertyTypeException | ConstraintViolationException e) { return RestConstraintValidator.fromException(e, updateRequest.getPropertyName(), updateRequest.getPropertyValue()); } } @ApiOperation(value = "Update location's resource's capability template capability property.", authorizations = { @Authorization("ADMIN") }) @RequestMapping(value = "/{id}/template/capabilities/{capabilityName}/properties", method = RequestMethod.POST) @PreAuthorize("hasAuthority('ADMIN')") @Audit public RestResponse<ConstraintInformation> updateResourceTemplateCapabilityProperty( @ApiParam(value = "Id of the orchestrator for which to update resource template capability property.", required = true) @PathVariable String orchestratorId, @ApiParam(value = "Id of the location of the orchestrator to update resource template capability property.", required = true) @PathVariable String locationId, @ApiParam(value = "Id of the location's resource.", required = true) @PathVariable String id, @ApiParam(value = "Id of the location's resource template capability.", required = true) @PathVariable String capabilityName, @RequestBody UpdateLocationResourceTemplatePropertyRequest updateRequest) { try { locationResourceService.setTemplateCapabilityProperty(id, capabilityName, updateRequest.getPropertyName(), updateRequest.getPropertyValue()); return RestResponseBuilder.<ConstraintUtil.ConstraintInformation> builder().build(); } catch (ConstraintViolationException | ConstraintValueDoNotMatchPropertyTypeException e) { return RestConstraintValidator.fromException(e, updateRequest.getPropertyName(), updateRequest.getPropertyValue()); } } @ApiOperation(value = "Auto configure the resources, if the location configurator plugin provides a way for.", authorizations = { @Authorization("ADMIN") }) @RequestMapping(value = "/auto-configure", method = RequestMethod.GET) @PreAuthorize("hasAuthority('ADMIN')") public RestResponse<List<LocationResourceTemplate>> autoConfigureResources( @ApiParam(value = "Id of the orchestrator for which to Auto configure the resources.", required = true) @PathVariable String orchestratorId, @ApiParam(value = "Id of the location of the orchestrator to Auto configure the resources.", required = true) @PathVariable String locationId) { locationResourceService.deleteGeneratedResources(locationId); List<LocationResourceTemplate> generatedResoucres = locationResourceService.autoConfigureResources(locationId); return RestResponseBuilder.<List<LocationResourceTemplate>> builder().data(generatedResoucres).build(); } }