package com.sequenceiq.cloudbreak.cloud.openstack.nativ.network; import static com.sequenceiq.cloudbreak.cloud.openstack.common.OpenStackConstants.NETWORK_ID; import java.util.List; 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.State; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.common.type.ResourceType; @Service public class OpenStackNetworkResourceBuilder extends AbstractOpenStackNetworkResourceBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(OpenStackNetworkResourceBuilder.class); @Inject private OpenStackUtils utils; @Override public CloudResource build(OpenStackContext context, AuthenticatedContext auth, Network network, Security security, CloudResource buildableResource) throws Exception { OSClient osClient = createOSClient(auth); try { NeutronNetworkView neutronView = new NeutronNetworkView(network); String networkId = neutronView.isExistingNetwork() ? neutronView.getCustomNetworkId() : context.getParameter(NETWORK_ID, String.class); if (!neutronView.isExistingNetwork()) { org.openstack4j.model.network.Network osNetwork = Builders.network() .name(buildableResource.getName()) .tenantId(context.getStringParameter(OpenStackConstants.TENANT_ID)) .adminStateUp(true) .build(); networkId = osClient.networking().network().create(osNetwork).getId(); } context.putParameter(OpenStackConstants.NETWORK_ID, networkId); return createPersistedResource(buildableResource, networkId); } catch (OS4JException ex) { throw new OpenStackResourceException("Network creation failed", resourceType(), buildableResource.getName(), ex); } } @Override public CloudResource delete(OpenStackContext context, AuthenticatedContext auth, CloudResource resource, Network network) throws Exception { try { OSClient osClient = createOSClient(auth); deAllocateFloatingIps(context, osClient); NeutronNetworkView neutronView = new NeutronNetworkView(network); if (!neutronView.isExistingNetwork()) { ActionResponse response = osClient.networking().network().delete(resource.getReference()); return checkDeleteResponse(response, resourceType(), auth, resource, "Network deletion failed"); } return null; } catch (OS4JException ex) { throw new OpenStackResourceException("Network deletion failed", resourceType(), resource.getName(), ex); } } @Override public ResourceType resourceType() { return ResourceType.OPENSTACK_NETWORK; } @Override protected boolean checkStatus(OpenStackContext context, AuthenticatedContext auth, CloudResource resource) { CloudContext cloudContext = auth.getCloudContext(); OSClient osClient = createOSClient(auth); org.openstack4j.model.network.Network osNetwork = osClient.networking().network().get(resource.getReference()); if (osNetwork != null && context.isBuild()) { State networkStatus = osNetwork.getStatus(); if (State.ERROR == networkStatus) { throw new OpenStackResourceException("Network in failed state", resource.getType(), resource.getName(), cloudContext.getId(), networkStatus.name()); } return networkStatus == State.ACTIVE; } else if (osNetwork == null && !context.isBuild()) { return true; } return false; } @SuppressWarnings("unchecked") private void deAllocateFloatingIps(OpenStackContext context, OSClient osClient) { List<String> floatingIpIds = context.getParameter(OpenStackConstants.FLOATING_IP_IDS, List.class); for (String floatingIpId : floatingIpIds) { try { ActionResponse response = osClient.compute().floatingIps().deallocateIP(floatingIpId); if (!response.isSuccess()) { LOGGER.warn("FloatingIp {} cannot be deallocated: {}", floatingIpId, response.getFault()); } } catch (OS4JException ex) { LOGGER.warn("FloatingIp {} cannot be deallocated: {}", floatingIpId, ex.getMessage()); } } } }