package com.sequenceiq.cloudbreak.cloud.openstack.nativ.network; import javax.inject.Inject; import org.openstack4j.api.Builders; import org.openstack4j.api.OSClient; import org.openstack4j.api.exceptions.OS4JException; import org.openstack4j.model.compute.ActionResponse; import org.openstack4j.model.network.AttachInterfaceType; import org.openstack4j.model.network.Router; import org.openstack4j.model.network.State; import org.springframework.stereotype.Service; import com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext; import com.sequenceiq.cloudbreak.cloud.context.CloudContext; import com.sequenceiq.cloudbreak.cloud.model.CloudResource; import com.sequenceiq.cloudbreak.cloud.model.Network; import com.sequenceiq.cloudbreak.cloud.model.Security; import com.sequenceiq.cloudbreak.cloud.openstack.common.OpenStackConstants; import com.sequenceiq.cloudbreak.cloud.openstack.common.OpenStackUtils; import com.sequenceiq.cloudbreak.cloud.openstack.nativ.OpenStackResourceException; import com.sequenceiq.cloudbreak.cloud.openstack.nativ.context.OpenStackContext; import com.sequenceiq.cloudbreak.cloud.openstack.view.NeutronNetworkView; import com.sequenceiq.cloudbreak.cloud.template.ResourceNotNeededException; import com.sequenceiq.cloudbreak.common.type.ResourceType; @Service public class OpenStackRouterResourceBuilder extends AbstractOpenStackNetworkResourceBuilder { @Inject private OpenStackUtils utils; @Override public CloudResource create(OpenStackContext context, AuthenticatedContext auth, Network network) { NeutronNetworkView neutronNetwork = new NeutronNetworkView(network); if (neutronNetwork.isExistingSubnet()) { throw new ResourceNotNeededException("Router isn't needed when a subnet is reused."); } return super.create(context, auth, network); } @Override public CloudResource build(OpenStackContext context, AuthenticatedContext auth, Network network, Security security, CloudResource resource) throws Exception { try { OSClient osClient = createOSClient(auth); NeutronNetworkView networkView = new NeutronNetworkView(network); String routerId = networkView.getCustomRouterId(); if (!networkView.isExistingNetwork()) { Router router = Builders.router() .name(resource.getName()) .adminStateUp(true) .tenantId(context.getStringParameter(OpenStackConstants.TENANT_ID)) .externalGateway(networkView.getPublicNetId()).build(); Router newRouter = osClient.networking().router().create(router); if (newRouter == null) { throw new OpenStackResourceException("Router creation failed, maybe network does not exists", resourceType(), resource.getName()); } routerId = newRouter.getId(); } if (!networkView.isExistingSubnet()) { osClient.networking().router().attachInterface(routerId, AttachInterfaceType.SUBNET, context.getStringParameter(OpenStackConstants.SUBNET_ID)); } return createPersistedResource(resource, routerId); } catch (OS4JException ex) { throw new OpenStackResourceException("Router creation failed", resourceType(), resource.getName(), ex); } } @Override public CloudResource delete(OpenStackContext context, AuthenticatedContext auth, CloudResource resource, Network network) throws Exception { try { OSClient osClient = createOSClient(auth); NeutronNetworkView networkView = new NeutronNetworkView(network); if (!networkView.isExistingSubnet()) { String subnetId = context.getStringParameter(OpenStackConstants.SUBNET_ID); osClient.networking().router().detachInterface(resource.getReference(), subnetId, null); } if (!networkView.isExistingNetwork()) { ActionResponse response = osClient.networking().router().delete(resource.getReference()); return checkDeleteResponse(response, resourceType(), auth, resource, "Router deletion failed"); } return null; } catch (OS4JException ex) { throw new OpenStackResourceException("Router deletion failed", resourceType(), resource.getName(), ex); } } @Override public ResourceType resourceType() { return ResourceType.OPENSTACK_ROUTER; } @Override protected boolean checkStatus(OpenStackContext context, AuthenticatedContext auth, CloudResource resource) { CloudContext cloudContext = auth.getCloudContext(); OSClient osClient = createOSClient(auth); Router osRouter = osClient.networking().router().get(resource.getReference()); if (osRouter != null && context.isBuild()) { State routerStatus = osRouter.getStatus(); if (State.ERROR == routerStatus) { throw new OpenStackResourceException("Router in failed state", resource.getType(), utils.getStackName(auth), cloudContext.getId(), resource.getName()); } return routerStatus == State.ACTIVE; } else if (osRouter == null && !context.isBuild()) { return true; } return false; } }