| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| package com.cloud.network.resource.wrapper; |
| |
| import static com.cloud.network.resource.NiciraNvpResource.NAME_MAX_LEN; |
| import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| |
| import com.cloud.agent.api.Answer; |
| import com.cloud.agent.api.CreateLogicalRouterAnswer; |
| import com.cloud.agent.api.CreateLogicalRouterCommand; |
| import com.cloud.network.nicira.L3GatewayAttachment; |
| import com.cloud.network.nicira.LogicalRouter; |
| import com.cloud.network.nicira.LogicalRouterPort; |
| import com.cloud.network.nicira.LogicalSwitchPort; |
| import com.cloud.network.nicira.Match; |
| import com.cloud.network.nicira.NiciraNvpApi; |
| import com.cloud.network.nicira.NiciraNvpApiException; |
| import com.cloud.network.nicira.NiciraNvpTag; |
| import com.cloud.network.nicira.PatchAttachment; |
| import com.cloud.network.nicira.RouterNextHop; |
| import com.cloud.network.nicira.SingleDefaultRouteImplicitRoutingConfig; |
| import com.cloud.network.nicira.SourceNatRule; |
| import com.cloud.network.resource.NiciraNvpResource; |
| import com.cloud.network.utils.CommandRetryUtility; |
| import com.cloud.resource.CommandWrapper; |
| import com.cloud.resource.ResourceWrapper; |
| |
| @ResourceWrapper(handles = CreateLogicalRouterCommand.class) |
| public final class NiciraNvpCreateLogicalRouterCommandWrapper extends CommandWrapper<CreateLogicalRouterCommand, Answer, NiciraNvpResource> { |
| |
| |
| @Override |
| public Answer execute(final CreateLogicalRouterCommand command, final NiciraNvpResource niciraNvpResource) { |
| final String routerName = command.getName(); |
| final String gatewayServiceUuid = command.getGatewayServiceUuid(); |
| final String logicalSwitchUuid = command.getLogicalSwitchUuid(); |
| |
| final List<NiciraNvpTag> tags = new ArrayList<NiciraNvpTag>(); |
| tags.add(new NiciraNvpTag("cs_account", command.getOwnerName())); |
| |
| final String publicNetworkNextHopIp = command.getPublicNextHop(); |
| final String publicNetworkIpAddress = command.getPublicIpCidr(); |
| final String internalNetworkAddress = command.getInternalIpCidr(); |
| |
| logger.debug("Creating a logical router with external ip " + publicNetworkIpAddress + " and internal ip " + internalNetworkAddress + "on gateway service " + |
| gatewayServiceUuid); |
| |
| final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); |
| |
| try { |
| // Create the Router |
| LogicalRouter lrc = new LogicalRouter(); |
| lrc.setDisplayName(niciraNvpResource.truncate(routerName, NAME_MAX_LEN)); |
| lrc.setTags(tags); |
| lrc.setRoutingConfig(new SingleDefaultRouteImplicitRoutingConfig(new RouterNextHop(publicNetworkNextHopIp))); |
| lrc = niciraNvpApi.createLogicalRouter(lrc); |
| |
| // store the switchport for rollback |
| LogicalSwitchPort lsp = null; |
| |
| try { |
| // Create the outside port for the router |
| LogicalRouterPort lrpo = new LogicalRouterPort(); |
| lrpo.setAdminStatusEnabled(true); |
| lrpo.setDisplayName(niciraNvpResource.truncate(routerName + "-outside-port", NAME_MAX_LEN)); |
| lrpo.setTags(tags); |
| final List<String> outsideIpAddresses = new ArrayList<String>(); |
| outsideIpAddresses.add(publicNetworkIpAddress); |
| lrpo.setIpAddresses(outsideIpAddresses); |
| lrpo = niciraNvpApi.createLogicalRouterPort(lrc.getUuid(), lrpo); |
| |
| // Attach the outside port to the gateway service on the correct VLAN |
| final L3GatewayAttachment attachment = new L3GatewayAttachment(gatewayServiceUuid); |
| if (command.getVlanId() != 0) { |
| attachment.setVlanId(command.getVlanId()); |
| } |
| niciraNvpApi.updateLogicalRouterPortAttachment(lrc.getUuid(), lrpo.getUuid(), attachment); |
| |
| // Create the inside port for the router |
| LogicalRouterPort lrpi = new LogicalRouterPort(); |
| lrpi.setAdminStatusEnabled(true); |
| lrpi.setDisplayName(niciraNvpResource.truncate(routerName + "-inside-port", NAME_MAX_LEN)); |
| lrpi.setTags(tags); |
| final List<String> insideIpAddresses = new ArrayList<String>(); |
| insideIpAddresses.add(internalNetworkAddress); |
| lrpi.setIpAddresses(insideIpAddresses); |
| lrpi = niciraNvpApi.createLogicalRouterPort(lrc.getUuid(), lrpi); |
| |
| // Create the inside port on the lswitch |
| lsp = new LogicalSwitchPort(niciraNvpResource.truncate(routerName + "-inside-port", NAME_MAX_LEN), tags, true); |
| lsp = niciraNvpApi.createLogicalSwitchPort(logicalSwitchUuid, lsp); |
| |
| // Attach the inside router port to the lswitch port with a PatchAttachment |
| niciraNvpApi.updateLogicalRouterPortAttachment(lrc.getUuid(), lrpi.getUuid(), new PatchAttachment(lsp.getUuid())); |
| |
| // Attach the inside lswitch port to the router with a PatchAttachment |
| niciraNvpApi.updateLogicalSwitchPortAttachment(logicalSwitchUuid, lsp.getUuid(), new PatchAttachment(lrpi.getUuid())); |
| |
| // Setup the source nat rule |
| final SourceNatRule snr = new SourceNatRule(); |
| snr.setToSourceIpAddressMin(publicNetworkIpAddress.split("/")[0]); |
| snr.setToSourceIpAddressMax(publicNetworkIpAddress.split("/")[0]); |
| final Match match = new Match(); |
| match.setSourceIpAddresses(internalNetworkAddress); |
| snr.setMatch(match); |
| snr.setOrder(200); |
| niciraNvpApi.createLogicalRouterNatRule(lrc.getUuid(), snr); |
| } catch (final NiciraNvpApiException e) { |
| // We need to destroy the router if we already created it |
| // this will also take care of any router ports and rules |
| try { |
| niciraNvpApi.deleteLogicalRouter(lrc.getUuid()); |
| if (lsp != null) { |
| niciraNvpApi.deleteLogicalSwitchPort(logicalSwitchUuid, lsp.getUuid()); |
| } |
| } catch (final NiciraNvpApiException ex) { |
| } |
| |
| throw e; |
| } |
| |
| return new CreateLogicalRouterAnswer(command, true, "Logical Router created (uuid " + lrc.getUuid() + ")", lrc.getUuid()); |
| } catch (final NiciraNvpApiException e) { |
| final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); |
| retryUtility.addRetry(command, NUM_RETRIES); |
| return retryUtility.retry(command, CreateLogicalRouterAnswer.class, e); |
| } |
| } |
| } |