diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 067ddf73567..32b852fb4a3 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -382,6 +382,7 @@ public class ApiConstants { public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid"; public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid"; public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename"; + public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid"; public enum HostDetails { diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index e84a40379ad..9e6b36b780b 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -291,4 +291,9 @@ public class EventTypes { public static final String EVENT_TAGS_CREATE = "CREATE_TAGS"; public static final String EVENT_TAGS_DELETE = "DELETE_TAGS"; + // external network device events + public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD"; + public static final String EVENT_EXTERNAL_NVP_CONTROLLER_DELETE = "PHYSICAL.NVPCONTROLLER.DELETE"; + public static final String EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE = "PHYSICAL.NVPCONTROLLER.CONFIGURE"; + } diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 73465fc6df7..681f3cf845d 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -1521,3 +1521,10 @@ error.menu.select=Unable to perform action due to no items being selected. error.mgmt.server.inaccessible=The Management Server is unaccessible. Please try again later. error.session.expired=Your session has expired. error.unresolved.internet.name=Your internet name cannot be resolved. + +label.add.NiciraNvp.device=Add Nvp Controller +label.delete.NiciraNvp=Remove Nvp Controller +label.nicira.controller.address=Controller Address +label.nicira.transportzoneuuid=Transport Zone Uuid +label.nicira.l3gatewayserviceuuid=L3 Gateway Service Uuid + diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 5730b832075..2953eb781a6 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -179,6 +179,7 @@ under the License. + diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterAnswer.java new file mode 100644 index 00000000000..40bde6c6e74 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterAnswer.java @@ -0,0 +1,34 @@ +// 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.agent.api; + +/** + * + */ +public class ConfigurePortForwardingRulesOnLogicalRouterAnswer extends Answer { + + public ConfigurePortForwardingRulesOnLogicalRouterAnswer(Command command, + boolean success, String details) { + super(command, success, details); + } + + public ConfigurePortForwardingRulesOnLogicalRouterAnswer(Command command, + Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterCommand.java new file mode 100644 index 00000000000..5f0ea384af3 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterCommand.java @@ -0,0 +1,60 @@ +// 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.agent.api; + +import java.util.List; + +import com.cloud.agent.api.to.PortForwardingRuleTO; + +/** + * + */ +public class ConfigurePortForwardingRulesOnLogicalRouterCommand extends Command { + + private String logicalRouterUuid; + private List rules; + + public ConfigurePortForwardingRulesOnLogicalRouterCommand(String logicalRouterUuid, List rules) { + this.logicalRouterUuid = logicalRouterUuid; + this.rules = rules; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + /* (non-Javadoc) + * @see com.cloud.agent.api.Command#executeInSequence() + */ + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java new file mode 100644 index 00000000000..d0749eda398 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java @@ -0,0 +1,14 @@ +package com.cloud.agent.api; + +public class ConfigurePublicIpsOnLogicalRouterAnswer extends Answer { + + public ConfigurePublicIpsOnLogicalRouterAnswer(Command command, + boolean success, String details) { + super(command, success, details); + } + + public ConfigurePublicIpsOnLogicalRouterAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java new file mode 100644 index 00000000000..0da0b4ec9da --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java @@ -0,0 +1,49 @@ +package com.cloud.agent.api; + +import java.util.List; + +public class ConfigurePublicIpsOnLogicalRouterCommand extends Command { + + private String logicalRouterUuid; + private String l3GatewayServiceUuid; + private List publicCidrs; + + public ConfigurePublicIpsOnLogicalRouterCommand(String logicalRouterUuid, + String l3GatewayServiceUuid, + List publicCidrs) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + this.publicCidrs = publicCidrs; + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public String getL3GatewayServiceUuid() { + return l3GatewayServiceUuid; + } + + public void setL3GatewayServiceUuid(String l3GatewayServiceUuid) { + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } + + public List getPublicCidrs() { + return publicCidrs; + } + + public void setPublicCidrs(List publicCidrs) { + this.publicCidrs = publicCidrs; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterAnswer.java new file mode 100644 index 00000000000..463dd4628cf --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterAnswer.java @@ -0,0 +1,43 @@ +// 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.agent.api; + +/** + * + */ +public class ConfigureStaticNatRulesOnLogicalRouterAnswer extends Answer { + + /** + * @param command + * @param success + * @param details + */ + public ConfigureStaticNatRulesOnLogicalRouterAnswer(Command command, + boolean success, String details) { + super(command, success, details); + } + + /** + * @param command + * @param e + */ + public ConfigureStaticNatRulesOnLogicalRouterAnswer(Command command, + Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterCommand.java new file mode 100644 index 00000000000..960f609cb54 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterCommand.java @@ -0,0 +1,63 @@ +// 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.agent.api; + +import java.util.List; + +import com.cloud.agent.api.to.StaticNatRuleTO; + +/** + * + */ +public class ConfigureStaticNatRulesOnLogicalRouterCommand extends Command { + + private String logicalRouterUuid; + private List rules; + + public ConfigureStaticNatRulesOnLogicalRouterCommand( + String logicalRouterUuid, List rules) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + this.rules = rules; + + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + /* (non-Javadoc) + * @see com.cloud.agent.api.Command#executeInSequence() + */ + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java new file mode 100644 index 00000000000..4a09e449af8 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java @@ -0,0 +1,40 @@ +// 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.agent.api; + +/** + * + */ +public class CreateLogicalRouterAnswer extends Answer { + + private String _logicalRouterUuid; + + public CreateLogicalRouterAnswer(Command command, boolean success, + String details, String logicalRouterUuid) { + super(command, success, details); + this._logicalRouterUuid = logicalRouterUuid; + } + + public CreateLogicalRouterAnswer(Command command, Exception e) { + super(command, e); + } + + public String getLogicalRouterUuid() { + return _logicalRouterUuid; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java new file mode 100644 index 00000000000..57440dfc4b0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java @@ -0,0 +1,115 @@ +// 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.agent.api; + +/** + * + */ +public class CreateLogicalRouterCommand extends Command { + private String _gatewayServiceUuid; + private String _logicalSwitchUuid; + private long _vlanId; + private String _name; + private String _ownerName; + private String _publicIpCidr; + private String _publicNextHop; + private String _internalIpCidr; + + public CreateLogicalRouterCommand(String gatewayServiceUuid, long vlanId, + String logicalSwitchUuid, String name, + String publicIpCidr, String publicNextHop, + String internalIpCidr, String ownerName) { + super(); + this._gatewayServiceUuid = gatewayServiceUuid; + this._logicalSwitchUuid = logicalSwitchUuid; + this._vlanId = vlanId; + this._name = name; + this._ownerName = ownerName; + this._publicIpCidr = publicIpCidr; + this._publicNextHop = publicNextHop; + this._internalIpCidr = internalIpCidr; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getGatewayServiceUuid() { + return _gatewayServiceUuid; + } + + public void setGatewayServiceUuid(String gatewayServiceUuid) { + this._gatewayServiceUuid = gatewayServiceUuid; + } + + public String getLogicalSwitchUuid() { + return _logicalSwitchUuid; + } + + public void setLogicalSwitchUuid(String logicalSwitchUuid) { + _logicalSwitchUuid = logicalSwitchUuid; + } + + public long getVlanId() { + return _vlanId; + } + + public void setVlanId(long vlanId) { + this._vlanId = vlanId; + } + + public String getName() { + return _name; + } + + public void setName(String name) { + this._name = name; + } + + public String getOwnerName() { + return _ownerName; + } + + public void setOwnerName(String ownerName) { + this._ownerName = ownerName; + } + + public String getPublicIpCidr() { + return _publicIpCidr; + } + + public void setPublicIpCidr(String publicIpCidr) { + this._publicIpCidr = publicIpCidr; + } + + public String getInternalIpCidr() { + return _internalIpCidr; + } + + public void setInternalIpCidr(String internalIpCidr) { + this._internalIpCidr = internalIpCidr; + } + + public String getPublicNextHop() { + return _publicNextHop; + } + + public void setPublicNextHop(String publicNextHop) { + this._publicNextHop = publicNextHop; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterAnswer.java new file mode 100644 index 00000000000..8a6bb9f193a --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterAnswer.java @@ -0,0 +1,32 @@ +// 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.agent.api; + +/** + * + */ +public class DeleteLogicalRouterAnswer extends Answer { + + public DeleteLogicalRouterAnswer(Command command, boolean success, + String details) { + super(command, success, details); + } + + public DeleteLogicalRouterAnswer(Command command, Exception e) { + super(command, e); + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterCommand.java new file mode 100644 index 00000000000..4799f9e58fe --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterCommand.java @@ -0,0 +1,41 @@ +// 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.agent.api; + +/** + * + */ +public class DeleteLogicalRouterCommand extends Command { + + private String _logicalRouterUuid; + + public DeleteLogicalRouterCommand(String logicalRouterUuid) { + this._logicalRouterUuid = logicalRouterUuid; + } + + /* (non-Javadoc) + * @see com.cloud.agent.api.Command#executeInSequence() + */ + @Override + public boolean executeInSequence() { + return false; + } + + public String getLogicalRouterUuid() { + return _logicalRouterUuid; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java index 6eac21f7255..ef12bf62605 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java @@ -42,9 +42,9 @@ import com.cloud.user.UserContext; import com.cloud.utils.exception.CloudRuntimeException; @Implementation(responseObject=NiciraNvpDeviceResponse.class, description="Adds a Nicira NVP device") -public class AddNiciraNvpDeviceCmd extends BaseCmd { +public class AddNiciraNvpDeviceCmd extends BaseAsyncCmd { private static final Logger s_logger = Logger.getLogger(AddNiciraNvpDeviceCmd.class.getName()); - private static final String s_name = "addniciranvpdevice"; + private static final String s_name = "addniciranvpdeviceresponse"; @PlugService NiciraNvpElementService _niciraNvpElementService; ///////////////////////////////////////////////////// @@ -67,6 +67,9 @@ public class AddNiciraNvpDeviceCmd extends BaseCmd { @Parameter(name=ApiConstants.NICIRA_NVP_TRANSPORT_ZONE_UUID, type=CommandType.STRING, required = true, description="The Transportzone UUID configured on the Nicira Controller") private String transportzoneuuid; + @Parameter(name=ApiConstants.NICIRA_NVP_GATEWAYSERVICE_UUID, type=CommandType.STRING, required = false, description="The L3 Gateway Service UUID configured on the Nicira Controller") + private String l3gatewayserviceuuid; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -90,6 +93,10 @@ public class AddNiciraNvpDeviceCmd extends BaseCmd { public String getTransportzoneUuid() { return transportzoneuuid; } + + public String getL3GatewayServiceUuid() { + return l3gatewayserviceuuid; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -123,4 +130,14 @@ public class AddNiciraNvpDeviceCmd extends BaseCmd { public long getEntityOwnerId() { return UserContext.current().getCaller().getId(); } + + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_NVP_CONTROLLER_ADD; + } + + @Override + public String getEventDescription() { + return "Adding a Nicira Nvp Controller"; + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java index 01a39466fd3..9cc8d626bb5 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java @@ -19,6 +19,7 @@ package com.cloud.api.commands; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; import com.cloud.api.BaseCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; @@ -26,6 +27,7 @@ import com.cloud.api.Parameter; import com.cloud.api.PlugService; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; @@ -36,9 +38,9 @@ import com.cloud.user.UserContext; import com.cloud.utils.exception.CloudRuntimeException; @Implementation(responseObject=SuccessResponse.class, description=" delete a nicira nvp device") -public class DeleteNiciraNvpDeviceCmd extends BaseCmd { +public class DeleteNiciraNvpDeviceCmd extends BaseAsyncCmd { private static final Logger s_logger = Logger.getLogger(DeleteNiciraNvpDeviceCmd.class.getName()); - private static final String s_name = "addniciranvpdevice"; + private static final String s_name = "deleteniciranvpdeviceresponse"; @PlugService NiciraNvpElementService _niciraNvpElementService; ///////////////////////////////////////////////////// @@ -89,4 +91,14 @@ public class DeleteNiciraNvpDeviceCmd extends BaseCmd { return UserContext.current().getCaller().getId(); } + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_LB_DEVICE_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting Nicira Nvp Controller"; + } + } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java index f9c157d9feb..f38cb16c8e9 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java @@ -43,7 +43,7 @@ import com.cloud.utils.exception.CloudRuntimeException; @Implementation(responseObject=NiciraNvpDeviceResponse.class, description="Lists Nicira NVP devices") public class ListNiciraNvpDevicesCmd extends BaseListCmd { private static final Logger s_logger = Logger.getLogger(ListNiciraNvpDevicesCmd.class.getName()); - private static final String s_name = "listniciranvpdevices"; + private static final String s_name = "listniciranvpdeviceresponse"; @PlugService NiciraNvpElementService _niciraNvpElementService; ///////////////////////////////////////////////////// diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java index d5c82b34a87..e50be813879 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java @@ -33,7 +33,16 @@ public class NiciraNvpDeviceResponse extends BaseResponse { @SerializedName(ApiConstants.NICIRA_NVP_DEVICE_NAME) @Param(description="device name") private String deviceName; - + + @SerializedName(ApiConstants.HOST_NAME) @Param(description="the controller Ip address") + private String hostName; + + @SerializedName(ApiConstants.NICIRA_NVP_TRANSPORT_ZONE_UUID) @Param(description="the transport zone Uuid") + private String transportZoneUuid; + + @SerializedName(ApiConstants.NICIRA_NVP_GATEWAYSERVICE_UUID) @Param(description="this L3 gateway service Uuid") + private String l3GatewayServiceUuid; + public void setId(long nvpDeviceId) { this.id.setValue(nvpDeviceId); } @@ -48,6 +57,26 @@ public class NiciraNvpDeviceResponse extends BaseResponse { public void setDeviceName(String deviceName) { this.deviceName = deviceName; - } + } + + public void setId(IdentityProxy id) { + this.id = id; + } + + public void setPhysicalNetworkId(IdentityProxy physicalNetworkId) { + this.physicalNetworkId = physicalNetworkId; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public void setTransportZoneUuid(String transportZoneUuid) { + this.transportZoneUuid = transportZoneUuid; + } + + public void setL3GatewayServiceUuid(String l3GatewayServiceUuid) { + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/NiciraNvpRouterMappingVO.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/NiciraNvpRouterMappingVO.java new file mode 100644 index 00000000000..037ba699fc0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/NiciraNvpRouterMappingVO.java @@ -0,0 +1,79 @@ +// 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; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="nicira_nvp_router_map") +public class NiciraNvpRouterMappingVO { + //FIXME the ddl for this table should be in one of the upgrade scripts + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="logicalrouter_uuid") + private String logicalRouterUuid; + + @Column(name="network_id") + private long networkId; + + public NiciraNvpRouterMappingVO() { + } + + public NiciraNvpRouterMappingVO(String logicalRouterUuid, long networkId) { + this.logicalRouterUuid = logicalRouterUuid; + this.networkId = networkId; + } + + public NiciraNvpRouterMappingVO(long id, String logicalRouterUuid, long networkId) { + this.id = id; + this.logicalRouterUuid = logicalRouterUuid; + this.networkId = networkId; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public long getNetworkId() { + return networkId; + } + + public void setNetworkId(long networkId) { + this.networkId = networkId; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java new file mode 100644 index 00000000000..bb3454a3809 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java @@ -0,0 +1,9 @@ +package com.cloud.network.dao; + +import com.cloud.network.NiciraNvpRouterMappingVO; +import com.cloud.utils.db.GenericDao; + +public interface NiciraNvpRouterMappingDao extends GenericDao { + + public NiciraNvpRouterMappingVO findByNetworkId(long id); +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java new file mode 100644 index 00000000000..1edcc03a51c --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java @@ -0,0 +1,30 @@ +package com.cloud.network.dao; + +import javax.ejb.Local; + +import com.cloud.network.NiciraNvpRouterMappingVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Local(value=NiciraNvpRouterMappingDao.class) +public class NiciraNvpRouterMappingDaoImpl extends GenericDaoBase implements NiciraNvpRouterMappingDao { + + protected final SearchBuilder networkSearch; + + public NiciraNvpRouterMappingDaoImpl() { + networkSearch = createSearchBuilder(); + networkSearch.and("network_id", networkSearch.entity().getNetworkId(), Op.EQ); + networkSearch.done(); + } + + @Override + public NiciraNvpRouterMappingVO findByNetworkId(long id) { + SearchCriteria sc = networkSearch.create(); + sc.setParameters("network_id", id); + return findOneBy(sc); + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java index 1fcccdb1ee3..1c8b8fb1dd3 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java @@ -47,8 +47,18 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; +import com.cloud.agent.api.CreateLogicalRouterAnswer; +import com.cloud.agent.api.CreateLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalSwitchPortAnswer; import com.cloud.agent.api.CreateLogicalSwitchPortCommand; +import com.cloud.agent.api.DeleteLogicalRouterAnswer; +import com.cloud.agent.api.DeleteLogicalRouterCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer; import com.cloud.agent.api.DeleteLogicalSwitchPortCommand; import com.cloud.agent.api.FindLogicalSwitchPortAnswer; @@ -57,11 +67,16 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer; import com.cloud.agent.api.UpdateLogicalSwitchPortCommand; +import com.cloud.agent.api.to.PortForwardingRuleTO; +import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.api.commands.AddNiciraNvpDeviceCmd; import com.cloud.api.commands.DeleteNiciraNvpDeviceCmd; import com.cloud.api.commands.ListNiciraNvpDeviceNetworksCmd; import com.cloud.api.commands.ListNiciraNvpDevicesCmd; import com.cloud.api.response.NiciraNvpDeviceResponse; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.dc.Vlan; +import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -80,29 +95,43 @@ import com.cloud.network.Network.Service; import com.cloud.network.NetworkVO; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.IpAddress; +import com.cloud.network.NetworkManager; import com.cloud.network.NiciraNvpDeviceVO; import com.cloud.network.NiciraNvpNicMappingVO; +import com.cloud.network.NiciraNvpRouterMappingVO; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkVO; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.NiciraNvpDao; import com.cloud.network.dao.NiciraNvpNicMappingDao; +import com.cloud.network.dao.NiciraNvpRouterMappingDao; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.guru.NiciraNvpGuestNetworkGuru; import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.PortForwardingRule; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.rules.StaticNatRule; +import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.offering.NetworkOffering; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; +import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; @@ -111,433 +140,827 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; @Local(value = NetworkElement.class) -public class NiciraNvpElement extends AdapterBase implements ConnectivityProvider, NiciraNvpElementService, ResourceStateAdapter { - private static final Logger s_logger = Logger.getLogger(NiciraNvpElement.class); - - private static final Map> capabilities = setCapabilities(); - +public class NiciraNvpElement extends AdapterBase implements + ConnectivityProvider, SourceNatServiceProvider, + PortForwardingServiceProvider, StaticNatServiceProvider, + NiciraNvpElementService, ResourceStateAdapter, IpDeployer { + private static final Logger s_logger = Logger + .getLogger(NiciraNvpElement.class); - @Inject - NicDao _nicDao; - @Inject - ResourceManager _resourceMgr; - @Inject - PhysicalNetworkDao _physicalNetworkDao; - @Inject - PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; - @Inject - NiciraNvpDao _niciraNvpDao; - @Inject - HostDetailsDao _hostDetailsDao; - @Inject - HostDao _hostDao; - @Inject - AgentManager _agentMgr; - @Inject - NiciraNvpNicMappingDao _niciraNvpNicMappingDao; - @Inject - NetworkDao _networkDao; - - @Override - public Map> getCapabilities() { - return capabilities; - } + private static final Map> capabilities = setCapabilities(); - @Override - public Provider getProvider() { - return Provider.NiciraNvp; - } - - private boolean canHandle(Network network) { - if (network.getBroadcastDomainType() != BroadcastDomainType.Lswitch) { - return false; - } - - return true; - } - - @Override - public boolean configure(String name, Map params) - throws ConfigurationException { - super.configure(name, params); - _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); - return true; - } + @Inject + NicDao _nicDao; + @Inject + ResourceManager _resourceMgr; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; + @Inject + NiciraNvpDao _niciraNvpDao; + @Inject + HostDetailsDao _hostDetailsDao; + @Inject + HostDao _hostDao; + @Inject + AgentManager _agentMgr; + @Inject + NiciraNvpNicMappingDao _niciraNvpNicMappingDao; + @Inject + NiciraNvpRouterMappingDao _niciraNvpRouterMappingDao; + @Inject + NetworkDao _networkDao; + @Inject + NetworkManager _networkManager; + @Inject + ConfigurationManager _configMgr; + @Inject + NetworkServiceMapDao _ntwkSrvcDao; + @Inject + VlanDao _vlanDao; - @Override - public boolean implement(Network network, NetworkOffering offering, - DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - - if (!canHandle(network)) { - return false; - } - - return true; - } + @Override + public Map> getCapabilities() { + return capabilities; + } - @Override - public boolean prepare(Network network, NicProfile nic, - VirtualMachineProfile vm, - DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - - if (!canHandle(network)) { + @Override + public Provider getProvider() { + return Provider.NiciraNvp; + } + + private boolean canHandle(Network network, Service service) { + s_logger.debug("Checking if NiciraNvpElement can handle service " + + service.getName() + " on network " + network.getDisplayText()); + if (network.getBroadcastDomainType() != BroadcastDomainType.Lswitch) { + return false; + } + + if (!_networkManager.isProviderForNetwork(getProvider(), + network.getId())) { + s_logger.debug("NiciraNvpElement is not a provider for network " + + network.getDisplayText()); + return false; + } + + if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), + service, Network.Provider.NiciraNvp)) { + s_logger.debug("NiciraNvpElement can't provide the " + + service.getName() + " service on network " + + network.getDisplayText()); + return false; + } + + return true; + } + + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { + super.configure(name, params); + _resourceMgr.registerResourceStateAdapter(this.getClass() + .getSimpleName(), this); + return true; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + s_logger.debug("entering NiciraNvpElement implement function for network " + + network.getDisplayText() + + " (state " + + network.getState() + + ")"); + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); + return false; + } + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + _hostDao.loadDetails(niciraNvpHost); + + Account owner = context.getAccount(); + + /** + * Lock the network as we might need to do multiple operations that + * should be done only once. + */ + Network lock = _networkDao.acquireInLockTable(network.getId(), + _networkManager.getNetworkLockTimeout()); + if (lock == null) { + throw new ConcurrentOperationException("Unable to lock network " + + network.getId()); + } + try { + // Implement SourceNat immediately as we have al the info already + if (_networkManager.isProviderSupportServiceInNetwork( + network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + s_logger.debug("Apparently we are supposed to provide SourceNat on this network"); + + PublicIp sourceNatIp = _networkManager + .assignSourceNatIpAddressToGuestNetwork(owner, network); + String publicCidr = sourceNatIp.getAddress().addr() + "/" + + NetUtils.getCidrSize(sourceNatIp.getVlanNetmask()); + String internalCidr = network.getGateway() + "/" + + network.getCidr().split("/")[1]; + long vlanid = (Vlan.UNTAGGED.equals(sourceNatIp.getVlanTag())) ? 0 + : Long.parseLong(sourceNatIp.getVlanTag()); + + CreateLogicalRouterCommand cmd = new CreateLogicalRouterCommand( + niciraNvpHost.getDetail("l3gatewayserviceuuid"), vlanid, + network.getBroadcastUri().getSchemeSpecificPart(), + "router-" + network.getDisplayText(), publicCidr, + sourceNatIp.getGateway(), internalCidr, context + .getDomain().getName() + + "-" + + context.getAccount().getAccountName()); + CreateLogicalRouterAnswer answer = (CreateLogicalRouterAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to create Logical Router for network " + + network.getDisplayText()); + return false; + } + + // Store the uuid so we can easily find it during cleanup + NiciraNvpRouterMappingVO routermapping = + new NiciraNvpRouterMappingVO(answer.getLogicalRouterUuid(), network.getId()); + _niciraNvpRouterMappingDao.persist(routermapping); + } + } finally { + if (lock != null) { + _networkDao.releaseFromLockTable(lock.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Lock is released for network id " + + lock.getId() + " as a part of router startup in " + + dest); + } + } + } + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, + VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); + return false; + } + + NicVO nicVO = _nicDao.findById(nic.getId()); + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpNicMappingVO existingNicMap = _niciraNvpNicMappingDao + .findByNicUuid(nicVO.getUuid()); + if (existingNicMap != null) { + FindLogicalSwitchPortCommand findCmd = new FindLogicalSwitchPortCommand( + existingNicMap.getLogicalSwitchUuid(), + existingNicMap.getLogicalSwitchPortUuid()); + FindLogicalSwitchPortAnswer answer = (FindLogicalSwitchPortAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), findCmd); + + if (answer.getResult()) { + s_logger.warn("Existing Logical Switchport found for nic " + + nic.getName() + " with uuid " + + existingNicMap.getLogicalSwitchPortUuid()); + UpdateLogicalSwitchPortCommand cmd = new UpdateLogicalSwitchPortCommand( + existingNicMap.getLogicalSwitchPortUuid(), network + .getBroadcastUri().getSchemeSpecificPart(), + nicVO.getUuid(), context.getDomain().getName() + "-" + + context.getAccount().getAccountName(), + nic.getName()); + _agentMgr.easySend(niciraNvpHost.getId(), cmd); + return true; + } else { + s_logger.error("Stale entry found for nic " + nic.getName() + + " with logical switchport uuid " + + existingNicMap.getLogicalSwitchPortUuid()); + _niciraNvpNicMappingDao.remove(existingNicMap.getId()); + } + } + + CreateLogicalSwitchPortCommand cmd = new CreateLogicalSwitchPortCommand( + network.getBroadcastUri().getSchemeSpecificPart(), + nicVO.getUuid(), context.getDomain().getName() + "-" + + context.getAccount().getAccountName(), nic.getName()); + CreateLogicalSwitchPortAnswer answer = (CreateLogicalSwitchPortAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("CreateLogicalSwitchPortCommand failed"); + return false; + } + + NiciraNvpNicMappingVO nicMap = new NiciraNvpNicMappingVO(network + .getBroadcastUri().getSchemeSpecificPart(), + answer.getLogicalSwitchPortUuid(), nicVO.getUuid()); + _niciraNvpNicMappingDao.persist(nicMap); + + return true; + } + + @Override + public boolean release(Network network, NicProfile nic, + VirtualMachineProfile vm, + ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException { + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); + return false; + } + + NicVO nicVO = _nicDao.findById(nic.getId()); + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpNicMappingVO nicMap = _niciraNvpNicMappingDao + .findByNicUuid(nicVO.getUuid()); + if (nicMap == null) { + s_logger.error("No mapping for nic " + nic.getName()); + return false; + } + + DeleteLogicalSwitchPortCommand cmd = new DeleteLogicalSwitchPortCommand( + nicMap.getLogicalSwitchUuid(), + nicMap.getLogicalSwitchPortUuid()); + DeleteLogicalSwitchPortAnswer answer = (DeleteLogicalSwitchPortAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("DeleteLogicalSwitchPortCommand failed"); + return false; + } + + _niciraNvpNicMappingDao.remove(nicMap.getId()); + + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, + boolean cleanup) throws ConcurrentOperationException, + ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + if (_networkManager.isProviderSupportServiceInNetwork(network.getId(), + Service.SourceNat, Provider.NiciraNvp)) { + s_logger.debug("Apparently we were providing SourceNat on this network"); + + // Deleting the LogicalRouter will also take care of all provisioned + // nat rules. + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.warn("No logical router uuid found for network " + + network.getDisplayText()); + // This might be cause by a failed deployment, so don't make shutdown fail as well. + return true; + } + + DeleteLogicalRouterCommand cmd = new DeleteLogicalRouterCommand(routermapping.getLogicalRouterUuid()); + DeleteLogicalRouterAnswer answer = + (DeleteLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to delete LogicalRouter for network " + + network.getDisplayText()); + return false; + } + + _niciraNvpRouterMappingDao.remove(routermapping.getId()); + } + + return true; + } + + @Override + public boolean destroy(Network network) + throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + return true; + } + + @Override + public boolean shutdownProviderInstances( + PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { + // Nothing to do here. + return true; + } + + @Override + public boolean canEnableIndividualServices() { + return true; + } + + @Override + public boolean verifyServicesCombination(Set services) { + // This element can only function in a Nicra Nvp based + // SDN network, so Connectivity needs to be present here + if (!services.contains(Service.Connectivity)) { + s_logger.warn("Unable to provide services without Connectivity service enabled for this element"); + return false; + } + if ((services.contains(Service.PortForwarding) || services.contains(Service.StaticNat)) && !services.contains(Service.SourceNat)) { + s_logger.warn("Unable to provide StaticNat and/or PortForwarding without the SourceNat service"); + return false; + } + return true; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + // L2 Support : SDN provisioning + capabilities.put(Service.Connectivity, null); + + // L3 Support : Generic? + capabilities.put(Service.Gateway, null); + + // L3 Support : SourceNat + Map sourceNatCapabilities = new HashMap(); + sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, + "peraccount"); + sourceNatCapabilities.put(Capability.RedundantRouter, "false"); + capabilities.put(Service.SourceNat, sourceNatCapabilities); + + // L3 Support : Port Forwarding + capabilities.put(Service.PortForwarding, null); + + // L3 support : StaticNat + capabilities.put(Service.StaticNat, null); + + return capabilities; + } + + @Override + public String getPropertiesFile() { + return "nicira-nvp_commands.properties"; + } + + @Override + @DB + public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd) { + ServerResource resource = new NiciraNvpResource(); + String deviceName = Network.Provider.NiciraNvp.getName(); + NetworkDevice networkDevice = NetworkDevice + .getNetworkDevice(deviceName); + Long physicalNetworkId = cmd.getPhysicalNetworkId(); + NiciraNvpDeviceVO niciraNvpDevice = null; + + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException( + "Could not find phyical network with ID: " + + physicalNetworkId); + } + long zoneId = physicalNetwork.getDataCenterId(); + + PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao + .findByServiceProvider(physicalNetwork.getId(), + networkDevice.getNetworkServiceProvder()); + if (ntwkSvcProvider == null) { + throw new CloudRuntimeException("Network Service Provider: " + + networkDevice.getNetworkServiceProvder() + + " is not enabled in the physical network: " + + physicalNetworkId + "to add this device"); + } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) { + throw new CloudRuntimeException("Network Service Provider: " + + ntwkSvcProvider.getProviderName() + + " is in shutdown state in the physical network: " + + physicalNetworkId + "to add this device"); + } + + if (_niciraNvpDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) { + throw new CloudRuntimeException( + "A NiciraNvp device is already configured on this physical network"); + } + + Map params = new HashMap(); + params.put("guid", UUID.randomUUID().toString()); + params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId())); + params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId())); + params.put("name", "Nicira Controller - " + cmd.getHost()); + params.put("ip", cmd.getHost()); + params.put("adminuser", cmd.getUsername()); + params.put("adminpass", cmd.getPassword()); + params.put("transportzoneuuid", cmd.getTransportzoneUuid()); + // FIXME What to do with multiple isolation types + params.put("transportzoneisotype", + physicalNetwork.getIsolationMethods().get(0).toLowerCase()); + if (cmd.getL3GatewayServiceUuid() != null) { + params.put("l3gatewayserviceuuid", cmd.getL3GatewayServiceUuid()); + } + + Map hostdetails = new HashMap(); + hostdetails.putAll(params); + + Transaction txn = Transaction.currentTxn(); + try { + resource.configure(cmd.getHost(), hostdetails); + + Host host = _resourceMgr.addHost(zoneId, resource, + Host.Type.L2Networking, params); + if (host != null) { + txn.start(); + + niciraNvpDevice = new NiciraNvpDeviceVO(host.getId(), + physicalNetworkId, ntwkSvcProvider.getProviderName(), + deviceName); + _niciraNvpDao.persist(niciraNvpDevice); + + DetailVO detail = new DetailVO(host.getId(), + "niciranvpdeviceid", String.valueOf(niciraNvpDevice + .getId())); + _hostDetailsDao.persist(detail); + + txn.commit(); + return niciraNvpDevice; + } else { + throw new CloudRuntimeException( + "Failed to add Nicira Nvp Device due to internal error."); + } + } catch (ConfigurationException e) { + txn.rollback(); + throw new CloudRuntimeException(e.getMessage()); + } + } + + @Override + public NiciraNvpDeviceResponse createNiciraNvpDeviceResponse( + NiciraNvpDeviceVO niciraNvpDeviceVO) { + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDeviceVO.getHostId()); + _hostDao.loadDetails(niciraNvpHost); + + NiciraNvpDeviceResponse response = new NiciraNvpDeviceResponse(); + response.setDeviceName(niciraNvpDeviceVO.getDeviceName()); + response.setPhysicalNetworkId(niciraNvpDeviceVO.getPhysicalNetworkId()); + response.setId(niciraNvpDeviceVO.getId()); + response.setProviderName(niciraNvpDeviceVO.getProviderName()); + response.setHostName(niciraNvpHost.getDetail("ip")); + response.setTransportZoneUuid(niciraNvpHost.getDetail("transportzoneuuid")); + response.setL3GatewayServiceUuid(niciraNvpHost.getDetail("l3gatewayserviceuuid")); + response.setObjectName("niciranvpdevice"); + return response; + } + + @Override + public boolean deleteNiciraNvpDevice(DeleteNiciraNvpDeviceCmd cmd) { + Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); + NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao + .findById(niciraDeviceId); + if (niciraNvpDevice == null) { + throw new InvalidParameterValueException( + "Could not find a nicira device with id " + niciraDeviceId); + } + + // Find the physical network we work for + Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork != null) { + // Lets see if there are networks that use us + // Find the nicira networks on this physical network + List networkList = _networkDao + .listByPhysicalNetwork(physicalNetworkId); + + // Networks with broadcast type lswitch are ours + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { + if ((network.getState() != Network.State.Shutdown) + && (network.getState() != Network.State.Destroy)) { + throw new CloudRuntimeException( + "This Nicira Nvp device can not be deleted as there are one or more logical networks provisioned by cloudstack."); + } + } + } + } + + HostVO niciraHost = _hostDao.findById(niciraNvpDevice.getHostId()); + Long hostId = niciraHost.getId(); + + niciraHost.setResourceState(ResourceState.Maintenance); + _hostDao.update(hostId, niciraHost); + _resourceMgr.deleteHost(hostId, false, false); + + _niciraNvpDao.remove(niciraDeviceId); + return true; + } + + @Override + public List listNiciraNvpDevices( + ListNiciraNvpDevicesCmd cmd) { + Long physicalNetworkId = cmd.getPhysicalNetworkId(); + Long niciraNvpDeviceId = cmd.getNiciraNvpDeviceId(); + List responseList = new ArrayList(); + + if (physicalNetworkId == null && niciraNvpDeviceId == null) { + throw new InvalidParameterValueException( + "Either physical network Id or nicira device Id must be specified"); + } + + if (niciraNvpDeviceId != null) { + NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao + .findById(niciraNvpDeviceId); + if (niciraNvpDevice == null) { + throw new InvalidParameterValueException( + "Could not find Nicira Nvp device with id: " + + niciraNvpDevice); + } + responseList.add(niciraNvpDevice); + } else { + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException( + "Could not find a physical network with id: " + + physicalNetworkId); + } + responseList = _niciraNvpDao + .listByPhysicalNetwork(physicalNetworkId); + } + + return responseList; + } + + @Override + public List listNiciraNvpDeviceNetworks( + ListNiciraNvpDeviceNetworksCmd cmd) { + Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); + NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao + .findById(niciraDeviceId); + if (niciraNvpDevice == null) { + throw new InvalidParameterValueException( + "Could not find a nicira device with id " + niciraDeviceId); + } + + // Find the physical network we work for + Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork == null) { + // No such physical network, so no provisioned networks + return Collections.emptyList(); + } + + // Find the nicira networks on this physical network + List networkList = _networkDao + .listByPhysicalNetwork(physicalNetworkId); + + // Networks with broadcast type lswitch are ours + List responseList = new ArrayList(); + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { + responseList.add(network); + } + } + + return responseList; + } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, + StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, + StartupCommand[] startup, ServerResource resource, + Map details, List hostTags) { + if (!(startup[0] instanceof StartupNiciraNvpCommand)) { + return null; + } + host.setType(Host.Type.L2Networking); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, + boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (!(host.getType() == Host.Type.L2Networking)) { + return null; + } + return new DeleteHostAnswer(true); + } + + /** + * From interface SourceNatServiceProvider + */ + @Override + public IpDeployer getIpDeployer(Network network) { + return this; + } + + /** + * From interface IpDeployer + * + * @param network + * @param ipAddress + * @param services + * @return + * @throws ResourceUnavailableException + */ + @Override + public boolean applyIps(Network network, + List ipAddress, Set services) + throws ResourceUnavailableException { + if (services.contains(Service.SourceNat)) { + // Only if we need to provide SourceNat we need to configure the logical router + // SourceNat is required for StaticNat and PortForwarding + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + _hostDao.loadDetails(niciraNvpHost); + + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.error("No logical router uuid found for network " + + network.getDisplayText()); + return false; + } + + List cidrs = new ArrayList(); + for (PublicIpAddress ip : ipAddress) { + cidrs.add(ip.getAddress().addr() + "/" + NetUtils.getCidrSize(ip.getNetmask())); + } + ConfigurePublicIpsOnLogicalRouterCommand cmd = new ConfigurePublicIpsOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), + niciraNvpHost.getDetail("l3gatewayserviceuuid"), cidrs); + ConfigurePublicIpsOnLogicalRouterAnswer answer = (ConfigurePublicIpsOnLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); + return answer.getResult(); + } + else { + s_logger.debug("No need to provision ip addresses as we are not providing L3 services."); + } + + return true; + } + + /** + * From interface StaticNatServiceProvider + */ + @Override + public boolean applyStaticNats(Network network, + List rules) + throws ResourceUnavailableException { + if (!canHandle(network, Service.StaticNat)) { return false; } - if (network.getBroadcastUri() == null) { - s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); - return false; - } + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.error("No logical router uuid found for network " + + network.getDisplayText()); + return false; + } - NicVO nicVO = _nicDao.findById(nic.getId()); - - List devices = _niciraNvpDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); - if (devices.isEmpty()) { - s_logger.error("No NiciraNvp Controller on physical network " + network.getPhysicalNetworkId()); - return false; - } - NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); - HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); - - NiciraNvpNicMappingVO existingNicMap = _niciraNvpNicMappingDao.findByNicUuid(nicVO.getUuid()); - if (existingNicMap != null) { - FindLogicalSwitchPortCommand findCmd = new FindLogicalSwitchPortCommand(existingNicMap.getLogicalSwitchUuid(), - existingNicMap.getLogicalSwitchPortUuid()); - FindLogicalSwitchPortAnswer answer = (FindLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), findCmd); - - if (answer.getResult()) { - s_logger.warn("Existing Logical Switchport found for nic " + nic.getName() + " with uuid " + existingNicMap.getLogicalSwitchPortUuid()); - UpdateLogicalSwitchPortCommand cmd = new UpdateLogicalSwitchPortCommand(existingNicMap.getLogicalSwitchPortUuid(), - network.getBroadcastUri().getSchemeSpecificPart(), nicVO.getUuid(), - context.getDomain().getName() + "-" + context.getAccount().getAccountName(), nic.getName()); - _agentMgr.easySend(niciraNvpHost.getId(), cmd); - return true; - } - else { - s_logger.error("Stale entry found for nic " + nic.getName() + " with logical switchport uuid " + existingNicMap.getLogicalSwitchPortUuid()); - _niciraNvpNicMappingDao.remove(existingNicMap.getId()); - } + List staticNatRules = new ArrayList(); + for (StaticNat rule : rules) { + IpAddress sourceIp = _networkManager.getIp(rule.getSourceIpAddressId()); + // Force the nat rule into the StaticNatRuleTO, no use making a new TO object + // we only need the source and destination ip. Unfortunately no mention if a rule + // is new. + StaticNatRuleTO ruleTO = new StaticNatRuleTO(1, + sourceIp.getAddress().addr(), 0, 65535, + rule.getDestIpAddress(), 0, 65535, + "any", rule.isForRevoke(), false); + staticNatRules.add(ruleTO); } - CreateLogicalSwitchPortCommand cmd = new CreateLogicalSwitchPortCommand(network.getBroadcastUri().getSchemeSpecificPart(), nicVO.getUuid(), - context.getDomain().getName() + "-" + context.getAccount().getAccountName(), nic.getName()); - CreateLogicalSwitchPortAnswer answer = (CreateLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); + ConfigureStaticNatRulesOnLogicalRouterCommand cmd = + new ConfigureStaticNatRulesOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), staticNatRules); + ConfigureStaticNatRulesOnLogicalRouterAnswer answer = (ConfigureStaticNatRulesOnLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); - if (answer == null || !answer.getResult()) { - s_logger.error ("CreateLogicalSwitchPortCommand failed"); + return answer.getResult(); + } + + /** + * From interface PortForwardingServiceProvider + */ + @Override + public boolean applyPFRules(Network network, List rules) + throws ResourceUnavailableException { + if (!canHandle(network, Service.PortForwarding)) { return false; } - NiciraNvpNicMappingVO nicMap = new NiciraNvpNicMappingVO(network.getBroadcastUri().getSchemeSpecificPart(), answer.getLogicalSwitchPortUuid(), nicVO.getUuid()); - _niciraNvpNicMappingDao.persist(nicMap); - - return true; - } - - @Override - public boolean release(Network network, NicProfile nic, - VirtualMachineProfile vm, - ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { - - if (!canHandle(network)) { - return false; - } - - if (network.getBroadcastUri() == null) { - s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); - return false; + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.error("No logical router uuid found for network " + + network.getDisplayText()); + return false; + } + + List portForwardingRules = new ArrayList(); + for (PortForwardingRule rule : rules) { + IpAddress sourceIp = _networkManager.getIp(rule.getSourceIpAddressId()); + Vlan vlan = _vlanDao.findById(sourceIp.getVlanId()); + PortForwardingRuleTO ruleTO = new PortForwardingRuleTO((PortForwardingRule) rule, vlan.getVlanTag(), sourceIp.getAddress().addr()); + portForwardingRules.add(ruleTO); } - NicVO nicVO = _nicDao.findById(nic.getId()); - - List devices = _niciraNvpDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); - if (devices.isEmpty()) { - s_logger.error("No NiciraNvp Controller on physical network " + network.getPhysicalNetworkId()); - return false; - } - NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); - HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + ConfigurePortForwardingRulesOnLogicalRouterCommand cmd = + new ConfigurePortForwardingRulesOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), portForwardingRules); + ConfigurePortForwardingRulesOnLogicalRouterAnswer answer = (ConfigurePortForwardingRulesOnLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); - NiciraNvpNicMappingVO nicMap = _niciraNvpNicMappingDao.findByNicUuid(nicVO.getUuid()); - if (nicMap == null) { - s_logger.error("No mapping for nic " + nic.getName()); - return false; - } - - DeleteLogicalSwitchPortCommand cmd = new DeleteLogicalSwitchPortCommand(nicMap.getLogicalSwitchUuid(), nicMap.getLogicalSwitchPortUuid()); - DeleteLogicalSwitchPortAnswer answer = (DeleteLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); - - if (answer == null || !answer.getResult()) { - s_logger.error ("DeleteLogicalSwitchPortCommand failed"); - return false; - } - - _niciraNvpNicMappingDao.remove(nicMap.getId()); - - return true; - } - - @Override - public boolean shutdown(Network network, ReservationContext context, - boolean cleanup) throws ConcurrentOperationException, - ResourceUnavailableException { - if (!canHandle(network)) { - return false; - } - - return true; - } - - @Override - public boolean destroy(Network network) - throws ConcurrentOperationException, ResourceUnavailableException { - if (!canHandle(network)) { - return false; - } - - return true; - } - - @Override - public boolean isReady(PhysicalNetworkServiceProvider provider) { - return true; - } - - @Override - public boolean shutdownProviderInstances( - PhysicalNetworkServiceProvider provider, ReservationContext context) - throws ConcurrentOperationException, ResourceUnavailableException { - // Nothing to do here. - return true; - } - - @Override - public boolean canEnableIndividualServices() { - return false; - } - - @Override - public boolean verifyServicesCombination(Set services) { - return true; - } - - private static Map> setCapabilities() { - Map> capabilities = new HashMap>(); - - capabilities.put(Service.Connectivity, null); - return capabilities; - } - - @Override - public String getPropertiesFile() { - return "nicira-nvp_commands.properties"; - } - - @Override - @DB - public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd) { - ServerResource resource = new NiciraNvpResource(); - String deviceName = Network.Provider.NiciraNvp.getName(); - NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName); - Long physicalNetworkId = cmd.getPhysicalNetworkId(); - NiciraNvpDeviceVO niciraNvpDevice = null; - - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { - throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId); - } - long zoneId = physicalNetwork.getDataCenterId(); - - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), networkDevice.getNetworkServiceProvder()); - if (ntwkSvcProvider == null) { - throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() + - " is not enabled in the physical network: " + physicalNetworkId + "to add this device"); - } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) { - throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + - " is in shutdown state in the physical network: " + physicalNetworkId + "to add this device"); - } - - if (_niciraNvpDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) { - throw new CloudRuntimeException("A NiciraNvp device is already configured on this physical network"); - } - - Map params = new HashMap(); - params.put("guid", UUID.randomUUID().toString()); - params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId())); - params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId())); - params.put("name", "Nicira Controller - " + cmd.getHost()); - params.put("ip", cmd.getHost()); - params.put("adminuser", cmd.getUsername()); - params.put("adminpass", cmd.getPassword()); - params.put("transportzoneuuid", cmd.getTransportzoneUuid()); - params.put("transportzoneisotype", physicalNetwork.getIsolationMethods().get(0).toLowerCase()); // FIXME What to do with multiple isolation types - - Map hostdetails = new HashMap(); - hostdetails.putAll(params); - - - Transaction txn = Transaction.currentTxn(); - try { - resource.configure(cmd.getHost(), hostdetails); - - Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params); - if (host != null) { - txn.start(); - - niciraNvpDevice = new NiciraNvpDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName); - _niciraNvpDao.persist(niciraNvpDevice); - - DetailVO detail = new DetailVO(host.getId(), "niciranvpdeviceid", String.valueOf(niciraNvpDevice.getId())); - _hostDetailsDao.persist(detail); - - txn.commit(); - return niciraNvpDevice; - } else { - throw new CloudRuntimeException("Failed to add Nicira Nvp Device due to internal error."); - } - } catch (ConfigurationException e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } - } - - @Override - public NiciraNvpDeviceResponse createNiciraNvpDeviceResponse( - NiciraNvpDeviceVO niciraNvpDeviceVO) { - NiciraNvpDeviceResponse response = new NiciraNvpDeviceResponse(); - response.setDeviceName(niciraNvpDeviceVO.getDeviceName()); - response.setPhysicalNetworkId(niciraNvpDeviceVO.getPhysicalNetworkId()); - response.setId(niciraNvpDeviceVO.getId()); - response.setProviderName(niciraNvpDeviceVO.getProviderName()); - return response; - } - - @Override - public boolean deleteNiciraNvpDevice(DeleteNiciraNvpDeviceCmd cmd) { - Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); - NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraDeviceId); - if (niciraNvpDevice == null) { - throw new InvalidParameterValueException("Could not find a nicira device with id " + niciraDeviceId); - } - - // Find the physical network we work for - Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork != null) { - // Lets see if there are networks that use us - // Find the nicira networks on this physical network - List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); - - // Networks with broadcast type lswitch are ours - for (NetworkVO network : networkList) { - if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { - if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) { - throw new CloudRuntimeException("This Nicira Nvp device can not be deleted as there are one or more logical networks provisioned by cloudstack."); - } - } - } - } - - HostVO niciraHost = _hostDao.findById(niciraNvpDevice.getHostId()); - Long hostId = niciraHost.getId(); - - niciraHost.setResourceState(ResourceState.Maintenance); - _hostDao.update(hostId, niciraHost); - _resourceMgr.deleteHost(hostId, false, false); - - _niciraNvpDao.remove(niciraDeviceId); - - return true; - } - - @Override - public List listNiciraNvpDevices(ListNiciraNvpDevicesCmd cmd) { - Long physicalNetworkId = cmd.getPhysicalNetworkId(); - Long niciraNvpDeviceId = cmd.getNiciraNvpDeviceId(); - List responseList = new ArrayList(); - - if (physicalNetworkId == null && niciraNvpDeviceId == null) { - throw new InvalidParameterValueException("Either physical network Id or nicira device Id must be specified"); - } - - if (niciraNvpDeviceId != null) { - NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraNvpDeviceId); - if (niciraNvpDevice == null) { - throw new InvalidParameterValueException("Could not find Nicira Nvp device with id: " + niciraNvpDevice); - } - responseList.add(niciraNvpDevice); - } - else { - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { - throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId); - } - responseList = _niciraNvpDao.listByPhysicalNetwork(physicalNetworkId); - } - - return responseList; - } - - @Override - public List listNiciraNvpDeviceNetworks(ListNiciraNvpDeviceNetworksCmd cmd) { - Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); - NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraDeviceId); - if (niciraNvpDevice == null) { - throw new InvalidParameterValueException("Could not find a nicira device with id " + niciraDeviceId); - } - - // Find the physical network we work for - Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { - // No such physical network, so no provisioned networks - return Collections.emptyList(); - } - - // Find the nicira networks on this physical network - List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); - - // Networks with broadcast type lswitch are ours - List responseList = new ArrayList(); - for (NetworkVO network : networkList) { - if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { - responseList.add(network); - } - } - - return responseList; - } - - @Override - public HostVO createHostVOForConnectedAgent(HostVO host, - StartupCommand[] cmd) { - // TODO Auto-generated method stub - return null; - } - - @Override - public HostVO createHostVOForDirectConnectAgent(HostVO host, - StartupCommand[] startup, ServerResource resource, - Map details, List hostTags) { - if (!(startup[0] instanceof StartupNiciraNvpCommand)) { - return null; - } - host.setType(Host.Type.L2Networking); - return host; - } - - @Override - public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, - boolean isForceDeleteStorage) throws UnableDeleteHostException { - if (!(host.getType() == Host.Type.L2Networking)) { - return null; - } - return new DeleteHostAnswer(true); - } + return answer.getResult(); + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/DestinationNatRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/DestinationNatRule.java new file mode 100644 index 00000000000..b1ef12f03b2 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/DestinationNatRule.java @@ -0,0 +1,8 @@ +package com.cloud.network.nicira; + +public class DestinationNatRule extends NatRule { + { + type = "DestinationNatRule"; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java new file mode 100644 index 00000000000..8b807fd9e72 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java @@ -0,0 +1,52 @@ +// 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.nicira; + +/** + * + */ +public class L3GatewayAttachment extends Attachment { + private String l3_gateway_service_uuid; + private String type = "L3GatewayAttachment"; + private Long vlan_id; + + public L3GatewayAttachment(String l3_gateway_service_uuid) { + this.l3_gateway_service_uuid = l3_gateway_service_uuid; + } + + public L3GatewayAttachment(String l3_gateway_service_uuid, long vlan_id) { + this.l3_gateway_service_uuid = l3_gateway_service_uuid; + this.vlan_id = vlan_id; + } + + public String getL3GatewayServiceUuid() { + return l3_gateway_service_uuid; + } + + public void setL3GatewayServiceUuid(String l3_gateway_service_uuid) { + this.l3_gateway_service_uuid = l3_gateway_service_uuid; + } + + public long getVlanId() { + return vlan_id; + } + + public void setVlanId(long vlan_id) { + this.vlan_id = vlan_id; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterConfig.java new file mode 100644 index 00000000000..897ee06b844 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterConfig.java @@ -0,0 +1,64 @@ +// 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.nicira; + +import java.util.List; + +/** + * + */ +public class LogicalRouterConfig { + private String display_name; + private RoutingConfig routing_config; + private String type = "LogicalRouterConfig"; + private String uuid; + private List tags; + + public RoutingConfig getRoutingConfig() { + return routing_config; + } + + public void setRoutingConfig(RoutingConfig routing_config) { + this.routing_config = routing_config; + } + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterPort.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterPort.java new file mode 100644 index 00000000000..196106dbe40 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterPort.java @@ -0,0 +1,90 @@ +// 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.nicira; + +import java.util.List; + +/** + * + */ +public class LogicalRouterPort { + private String display_name; + private List tags; + private Integer portno; + private boolean admin_status_enabled; + private List ip_addresses; + private String mac_address; + private String type = "LogicalRouterPortConfig"; + private String uuid; + + public int getPortno() { + return portno; + } + + public void setPortno(int portno) { + this.portno = portno; + } + + public boolean isAdminStatusEnabled() { + return admin_status_enabled; + } + + public void setAdminStatusEnabled(boolean admin_status_enabled) { + this.admin_status_enabled = admin_status_enabled; + } + + public List getIpAddresses() { + return ip_addresses; + } + + public void setIpAddresses(List ip_addresses) { + this.ip_addresses = ip_addresses; + } + + public String getMacAddress() { + return mac_address; + } + + public void setMacAddress(String mac_address) { + this.mac_address = mac_address; + } + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Match.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Match.java new file mode 100644 index 00000000000..ce5205ba47f --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Match.java @@ -0,0 +1,133 @@ +// 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.nicira; + +/** + * + */ +public class Match { + private Integer protocol; + private String source_ip_addresses; + private Boolean source_ip_addresses_not; + private String destination_ip_addresses; + private Boolean destination_ip_addresses_not; + private Integer source_port_min; + private Integer source_port_max; + private Boolean source_port_not; + private Integer destination_port_min; + private Integer destination_port_max; + private Boolean destination_port_not; + private String ethertype = "IPv4"; + + public Integer getProtocol() { + return protocol; + } + + public void setProtocol(Integer protocol) { + this.protocol = protocol; + } + + public Integer getSource_port_min() { + return source_port_min; + } + + public void setSourcePortMin(Integer source_port_min) { + this.source_port_min = source_port_min; + } + + public Integer getSourcePortMax() { + return source_port_max; + } + + public void setSourcePortMax(Integer source_port_max) { + this.source_port_max = source_port_max; + } + + public Boolean isSourcePortNot() { + return source_port_not; + } + + public void setSourcePortNot(Boolean source_port_not) { + this.source_port_not = source_port_not; + } + + public Integer getDestinationPortMin() { + return destination_port_min; + } + + public void setDestinationPortMin(Integer destination_port_min) { + this.destination_port_min = destination_port_min; + } + + public Integer getDestinationPortMax() { + return destination_port_max; + } + + public void setDestinationPortMax(Integer destination_port_max) { + this.destination_port_max = destination_port_max; + } + + public Boolean isDestinationPortNot() { + return destination_port_not; + } + + public void setDestinationPortNot(Boolean destination_port_not) { + this.destination_port_not = destination_port_not; + } + + public String getEthertype() { + return ethertype; + } + + public void setEthertype(String ethertype) { + this.ethertype = ethertype; + } + + public String getSourceIpAddresses() { + return source_ip_addresses; + } + + public void setSourceIpAddresses(String source_ip_addresses) { + this.source_ip_addresses = source_ip_addresses; + } + + public boolean isSourceIpAddressesNot() { + return source_ip_addresses_not; + } + + public void setSourceIpAddresses_not(boolean source_ip_addresses_not) { + this.source_ip_addresses_not = source_ip_addresses_not; + } + + public String getDestinationIpAddresses() { + return destination_ip_addresses; + } + + public void setDestinationIpAddresses(String destination_ip_addresses) { + this.destination_ip_addresses = destination_ip_addresses; + } + + public Boolean isDestinationIpAddressesNot() { + return destination_ip_addresses_not; + } + + public void setDestinationIpAddressesNot(Boolean destination_ip_addresses_not) { + this.destination_ip_addresses_not = destination_ip_addresses_not; + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java new file mode 100644 index 00000000000..7255ab67d39 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java @@ -0,0 +1,113 @@ +// 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.nicira; + +/** + * + */ +public class NatRule { + protected Match match; + protected String to_source_ip_address_min; + protected String to_source_ip_address_max; + protected Integer to_source_port_min; + protected Integer to_source_port_max; + protected String uuid; + protected String type; + protected String to_destination_ip_address_min; + protected String to_destination_ip_address_max; + protected Integer to_destination_port; + + public NatRule() {} + + public Match getMatch() { + return match; + } + + public void setMatch(Match match) { + this.match = match; + } + + public String getToSourceIpAddressMin() { + return to_source_ip_address_min; + } + + public void setToSourceIpAddressMin(String to_source_ip_address_min) { + this.to_source_ip_address_min = to_source_ip_address_min; + } + + public String getToSourceIpAddressMax() { + return to_source_ip_address_max; + } + + public void setToSourceIpAddressMax(String to_source_ip_address_max) { + this.to_source_ip_address_max = to_source_ip_address_max; + } + + public Integer getToSourcePortMin() { + return to_source_port_min; + } + + public void setToSourcePortMin(Integer to_source_port_min) { + this.to_source_port_min = to_source_port_min; + } + + public Integer getToSourcePortMax() { + return to_source_port_max; + } + + public void setToSourcePortMax(Integer to_source_port_max) { + this.to_source_port_max = to_source_port_max; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getToDestinationIpAddressMin() { + return to_destination_ip_address_min; + } + + public void setToDestinationIpAddressMin( + String to_destination_ip_address_min) { + this.to_destination_ip_address_min = to_destination_ip_address_min; + } + + public String getToDestinationIpAddressMax() { + return to_destination_ip_address_max; + } + + public void setToDestinationIpAddressMax( + String to_destination_ip_address_max) { + this.to_destination_ip_address_max = to_destination_ip_address_max; + } + + public Integer getToDestinationPort() { + return to_destination_port; + } + + public void setToDestinationPort(Integer to_destination_port) { + this.to_destination_port = to_destination_port; + } + + public String getType() { + return type; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index 2c002abdbff..a714e57f614 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -78,6 +78,7 @@ import com.google.gson.reflect.TypeToken; public class NiciraNvpApi { private static final Logger s_logger = Logger.getLogger(NiciraNvpApi.class); + private final static String _protocol = "https"; private String _name; private String _host; @@ -117,7 +118,7 @@ public class NiciraNvpApi { String url; try { - url = new URL("https", _host, "/ws.v1/login").toString(); + url = new URL(_protocol, _host, "/ws.v1/login").toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); @@ -180,7 +181,7 @@ public class NiciraNvpApi { NiciraNvpList lspl = executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); - if (lspl == null || lspl.getResult_count() != 1) { + if (lspl == null || lspl.getResultCount() != 1) { throw new NiciraNvpApiException("Unexpected response from API"); } @@ -210,11 +211,112 @@ public class NiciraNvpApi { return lspl; } + public LogicalRouterConfig createLogicalRouter(LogicalRouterConfig logicalRouterConfig) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter"; + + LogicalRouterConfig lrc = executeCreateObject(logicalRouterConfig, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + + return lrc; + } + + public void deleteLogicalRouter(String logicalRouterUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid; + + executeDeleteObject(uri); + } + + public LogicalRouterPort createLogicalRouterPort(String logicalRouterUuid, LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport"; + + LogicalRouterPort lrp = executeCreateObject(logicalRouterPort, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + return lrp; + } + + public void deleteLogicalRouterPort(String logicalRouterUuid, String logicalRouterPortUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPortUuid; + + executeDeleteObject(uri); + } + + public void modifyLogicalRouterPort(String logicalRouterUuid, LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPort.getUuid(); + + executeUpdateObject(logicalRouterPort, uri, Collections.emptyMap()); + } + + public void modifyLogicalRouterPortAttachment(String logicalRouterUuid, String logicalRouterPortUuid, Attachment attachment) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPortUuid + "/attachment"; + executeUpdateObject(attachment, uri, Collections.emptyMap()); + } + + public NatRule createLogicalRouterNatRule(String logicalRouterUuid, NatRule natRule) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat"; + + if (natRule instanceof SourceNatRule) { + return executeCreateObject(natRule, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + } + else if (natRule instanceof DestinationNatRule) { + return executeCreateObject(natRule, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + } + + throw new NiciraNvpApiException("Unknown NatRule type"); + } + + public void modifyLogicalRouterNatRule(String logicalRouterUuid, NatRule natRule) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + natRule.getUuid(); + + executeUpdateObject(natRule, uri, Collections.emptyMap()); + } + + public void deleteLogicalRouterNatRule(String logicalRouterUuid, String natRuleUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + natRuleUuid; + + executeDeleteObject(uri); + } + + public NiciraNvpList findLogicalRouterPortByGatewayServiceAndVlanId(String logicalRouterUuid, String gatewayServiceUuid, long vlanId) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport"; + Map params = new HashMap(); + params.put("attachment_gwsvc_uuid", gatewayServiceUuid); + params.put("attachment_vlan", "0"); + params.put("fields","*"); + + return executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); + } + + public LogicalRouterConfig findOneLogicalRouterByUuid(String logicalRouterUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid; + + return executeRetrieveObject(new TypeToken(){}.getType(), uri, Collections.emptyMap()); + } + + public void updateLogicalRouterPortConfig(String logicalRouterUuid, LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport" + logicalRouterPort.getUuid(); + + executeUpdateObject(logicalRouterPort, uri, Collections.emptyMap()); + } + + public NiciraNvpList findNatRulesByLogicalRouterUuid(String logicalRouterUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat"; + Map params = new HashMap(); + params.put("fields","*"); + + return executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); + } + + public NiciraNvpList findLogicalRouterPortByGatewayServiceUuid(String logicalRouterUuid, String l3GatewayServiceUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport"; + Map params = new HashMap(); + params.put("fields", "*"); + params.put("attachment_gwsvc_uuid", l3GatewayServiceUuid); + + return executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); + } private void executeUpdateObject(T newObject, String uri, Map parameters) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Connection to NVP Failed"); @@ -244,7 +346,7 @@ public class NiciraNvpApi { private T executeCreateObject(T newObject, Type returnObjectType, String uri, Map parameters) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); @@ -282,7 +384,7 @@ public class NiciraNvpApi { private void executeDeleteObject(String uri) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); @@ -303,7 +405,7 @@ public class NiciraNvpApi { private T executeRetrieveObject(Type returnObjectType, String uri, Map parameters) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java index 13d352daba3..c97e40ecd81 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java @@ -30,12 +30,16 @@ public class NiciraNvpList { this.results = results; } - public int getResult_count() { + public int getResultCount() { return result_count; } - public void setResult_count(int result_count) { + public void setResultCount(int result_count) { this.result_count = result_count; - } + } + + public boolean isEmpty() { + return result_count == 0; + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java new file mode 100644 index 00000000000..e57c2493f1c --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java @@ -0,0 +1,39 @@ +// 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.nicira; + +/** + * + */ +public class PatchAttachment extends Attachment { + private final String type = "PatchAttachment"; + private String peer_port_uuid; + + public PatchAttachment(String peerPortUuid) { + this.peer_port_uuid = peerPortUuid; + } + + public String getPeerPortUuid() { + return peer_port_uuid; + } + + public void setPeerPortUuid(String peerPortUuid) { + this.peer_port_uuid = peerPortUuid; + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java new file mode 100644 index 00000000000..c018af37467 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java @@ -0,0 +1,38 @@ +// 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.nicira; + +/** + * + */ +public class RouterNextHop { + private String gateway_ip_address; + private String type = "RouterNextHop"; + + public RouterNextHop(String gatewayIpAddress) { + this.gateway_ip_address = gatewayIpAddress; + } + + public String getGatewayIpAddress() { + return gateway_ip_address; + } + + public void setGatewayIpAddress(String gateway_ip_address) { + this.gateway_ip_address = gateway_ip_address; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java new file mode 100644 index 00000000000..12b3227e2e2 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java @@ -0,0 +1,5 @@ +package com.cloud.network.nicira; + +public class RoutingConfig { + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java new file mode 100644 index 00000000000..b4eda447b13 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java @@ -0,0 +1,38 @@ +// 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.nicira; + +/** + * + */ +public class SingleDefaultRouteImplictRoutingConfig extends RoutingConfig { + public RouterNextHop default_route_next_hop; + public String type = "SingleDefaultRouteImplicitRoutingConfig"; + + public SingleDefaultRouteImplictRoutingConfig(RouterNextHop routerNextHop) { + default_route_next_hop = routerNextHop; + } + + public RouterNextHop getDefaultRouteNextHop() { + return default_route_next_hop; + } + + public void setDefaultRouteNextHop(RouterNextHop default_route_next_hop) { + this.default_route_next_hop = default_route_next_hop; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java new file mode 100644 index 00000000000..acbf21e18af --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java @@ -0,0 +1,27 @@ +// 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.nicira; + +/** + * + */ +public class SourceNatRule extends NatRule { + { + type = "SourceNatRule"; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java index 31cac6f000c..5f445fa70dc 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java @@ -27,10 +27,20 @@ import org.apache.log4j.Logger; import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; +import com.cloud.agent.api.CreateLogicalRouterAnswer; +import com.cloud.agent.api.CreateLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalSwitchAnswer; import com.cloud.agent.api.CreateLogicalSwitchCommand; import com.cloud.agent.api.CreateLogicalSwitchPortAnswer; import com.cloud.agent.api.CreateLogicalSwitchPortCommand; +import com.cloud.agent.api.DeleteLogicalRouterAnswer; +import com.cloud.agent.api.DeleteLogicalRouterCommand; import com.cloud.agent.api.DeleteLogicalSwitchAnswer; import com.cloud.agent.api.DeleteLogicalSwitchCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer; @@ -46,19 +56,34 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer; import com.cloud.agent.api.UpdateLogicalSwitchPortCommand; +import com.cloud.agent.api.to.PortForwardingRuleTO; +import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.host.Host; import com.cloud.host.Host.Type; +import com.cloud.network.nicira.Attachment; import com.cloud.network.nicira.ControlClusterStatus; +import com.cloud.network.nicira.DestinationNatRule; +import com.cloud.network.nicira.L3GatewayAttachment; +import com.cloud.network.nicira.LogicalRouterConfig; +import com.cloud.network.nicira.LogicalRouterPort; import com.cloud.network.nicira.LogicalSwitch; import com.cloud.network.nicira.LogicalSwitchPort; +import com.cloud.network.nicira.Match; +import com.cloud.network.nicira.NatRule; import com.cloud.network.nicira.NiciraNvpApi; import com.cloud.network.nicira.NiciraNvpApiException; import com.cloud.network.nicira.NiciraNvpList; import com.cloud.network.nicira.NiciraNvpTag; +import com.cloud.network.nicira.PatchAttachment; +import com.cloud.network.nicira.RouterNextHop; +import com.cloud.network.nicira.SingleDefaultRouteImplictRoutingConfig; +import com.cloud.network.nicira.SourceNatRule; import com.cloud.network.nicira.TransportZoneBinding; import com.cloud.network.nicira.VifAttachment; import com.cloud.resource.ServerResource; +import edu.emory.mathcs.backport.java.util.Arrays; + public class NiciraNvpResource implements ServerResource { private static final Logger s_logger = Logger.getLogger(NiciraNvpResource.class); @@ -197,6 +222,21 @@ public class NiciraNvpResource implements ServerResource { else if (cmd instanceof FindLogicalSwitchPortCommand) { return executeRequest((FindLogicalSwitchPortCommand) cmd, numRetries); } + else if (cmd instanceof CreateLogicalRouterCommand) { + return executeRequest((CreateLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof DeleteLogicalRouterCommand) { + return executeRequest((DeleteLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof ConfigureStaticNatRulesOnLogicalRouterCommand) { + return executeRequest((ConfigureStaticNatRulesOnLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof ConfigurePortForwardingRulesOnLogicalRouterCommand) { + return executeRequest((ConfigurePortForwardingRulesOnLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof ConfigurePublicIpsOnLogicalRouterCommand) { + return executeRequest((ConfigurePublicIpsOnLogicalRouterCommand) cmd, numRetries); + } s_logger.debug("Received unsupported command " + cmd.toString()); return Answer.createUnsupportedCommandAnswer(cmd); } @@ -324,7 +364,7 @@ public class NiciraNvpResource implements ServerResource { try { NiciraNvpList ports = _niciraNvpApi.findLogicalSwitchPortsByUuid(logicalSwitchUuid, logicalSwitchPortUuid); - if (ports.getResult_count() == 0) { + if (ports.getResultCount() == 0) { return new FindLogicalSwitchPortAnswer(cmd, false, "Logical switchport " + logicalSwitchPortUuid + " not found", null); } else { @@ -340,6 +380,411 @@ public class NiciraNvpResource implements ServerResource { } } + private Answer executeRequest(CreateLogicalRouterCommand cmd, int numRetries) { + String routerName = cmd.getName(); + String gatewayServiceUuid = cmd.getGatewayServiceUuid(); + String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); + + List tags = new ArrayList(); + tags.add(new NiciraNvpTag("cs_account",cmd.getOwnerName())); + + String publicNetworkNextHopIp = cmd.getPublicNextHop(); + String publicNetworkIpAddress = cmd.getPublicIpCidr(); + String internalNetworkAddress = cmd.getInternalIpCidr(); + + s_logger.debug("Creating a logical router with external ip " + + publicNetworkIpAddress + " and internal ip " + internalNetworkAddress + + "on gateway service " + gatewayServiceUuid); + + try { + // Create the Router + LogicalRouterConfig lrc = new LogicalRouterConfig(); + lrc.setDisplayName(routerName); + lrc.setTags(tags); + lrc.setRoutingConfig(new SingleDefaultRouteImplictRoutingConfig( + new RouterNextHop(publicNetworkNextHopIp))); + lrc = _niciraNvpApi.createLogicalRouter(lrc); + + try { + // Create the outside port for the router + LogicalRouterPort lrpo = new LogicalRouterPort(); + lrpo.setAdminStatusEnabled(true); + lrpo.setDisplayName(routerName + "-outside-port"); + lrpo.setTags(tags); + List outsideIpAddresses = new ArrayList(); + outsideIpAddresses.add(publicNetworkIpAddress); + lrpo.setIpAddresses(outsideIpAddresses); + lrpo = _niciraNvpApi.createLogicalRouterPort(lrc.getUuid(),lrpo); + + // Attach the outside port to the gateway service on the correct VLAN + L3GatewayAttachment attachment = new L3GatewayAttachment(gatewayServiceUuid); + if (cmd.getVlanId() != 0) { + attachment.setVlanId(cmd.getVlanId()); + } + _niciraNvpApi.modifyLogicalRouterPortAttachment(lrc.getUuid(), lrpo.getUuid(), attachment); + + // Create the inside port for the router + LogicalRouterPort lrpi = new LogicalRouterPort(); + lrpi.setAdminStatusEnabled(true); + lrpi.setDisplayName(routerName + "-inside-port"); + lrpi.setTags(tags); + List insideIpAddresses = new ArrayList(); + insideIpAddresses.add(internalNetworkAddress); + lrpi.setIpAddresses(insideIpAddresses); + lrpi = _niciraNvpApi.createLogicalRouterPort(lrc.getUuid(),lrpi); + + // Create the inside port on the lswitch + LogicalSwitchPort lsp = new LogicalSwitchPort(routerName + "-inside-port", tags, true); + lsp = _niciraNvpApi.createLogicalSwitchPort(logicalSwitchUuid, lsp); + + // Attach the inside router port to the lswitch port with a PatchAttachment + _niciraNvpApi.modifyLogicalRouterPortAttachment(lrc.getUuid(), lrpi.getUuid(), + new PatchAttachment(lsp.getUuid())); + + // Attach the inside lswitch port to the router with a PatchAttachment + _niciraNvpApi.modifyLogicalSwitchPortAttachment(logicalSwitchUuid, lsp.getUuid(), + new PatchAttachment(lrpi.getUuid())); + + // Setup the source nat rule + SourceNatRule snr = new SourceNatRule(); + snr.setToSourceIpAddressMin(publicNetworkIpAddress.split("/")[0]); + snr.setToSourceIpAddressMax(publicNetworkIpAddress.split("/")[0]); + Match match = new Match(); + match.setSourceIpAddresses(internalNetworkAddress); + snr.setMatch(match); + _niciraNvpApi.createLogicalRouterNatRule(lrc.getUuid(), snr); + } catch (NiciraNvpApiException e) { + // We need to destroy the router if we already created it + // this will also take care of any router ports + // TODO Clean up the switchport + try { + _niciraNvpApi.deleteLogicalRouter(lrc.getUuid()); + } catch (NiciraNvpApiException ex) {} + + throw e; + } + + return new CreateLogicalRouterAnswer(cmd, true, "Logical Router created (uuid " + lrc.getUuid() + ")", lrc.getUuid()); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new CreateLogicalRouterAnswer(cmd, e); + } + } + } + + private Answer executeRequest(DeleteLogicalRouterCommand cmd, int numRetries) { + try { + _niciraNvpApi.deleteLogicalRouter(cmd.getLogicalRouterUuid()); + return new DeleteLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new DeleteLogicalRouterAnswer(cmd, e); + } + } + } + + private Answer executeRequest(ConfigurePublicIpsOnLogicalRouterCommand cmd, int numRetries) { + try { + NiciraNvpList ports = _niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(cmd.getLogicalRouterUuid(), cmd.getL3GatewayServiceUuid()); + if (ports.getResultCount() != 1) { + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, false, "No logical router ports found, unable to set ip addresses"); + } + LogicalRouterPort lrp = ports.getResults().get(0); + lrp.setIpAddresses(cmd.getPublicCidrs()); + _niciraNvpApi.modifyLogicalRouterPort(cmd.getLogicalRouterUuid(), lrp); + + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(ConfigureStaticNatRulesOnLogicalRouterCommand cmd, int numRetries) { + try { + NiciraNvpList existingRules = _niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); + // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) + // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule + // Any other SourceNat rule should have a corresponding DestinationNat rule + + for (StaticNatRuleTO rule : cmd.getRules()) { + // Find if a DestinationNat rule exists for this rule + String insideIp = rule.getDstIp(); + String insideCidr = rule.getDstIp() + "/32"; + String outsideIp = rule.getSrcIp(); + String outsideCidr = rule.getSrcIp() + "/32"; + + NatRule incoming = null; + NatRule outgoing = null; + + for (NatRule storedRule : existingRules.getResults()) { + if (s_logger.isDebugEnabled()) { + StringBuilder natRuleStr = new StringBuilder(); + natRuleStr.append("Rule "); + natRuleStr.append(storedRule.getUuid()); + natRuleStr.append(" ("); + natRuleStr.append(storedRule.getType()); + natRuleStr.append(") :"); + Match m = storedRule.getMatch(); + natRuleStr.append("match ("); + natRuleStr.append(m.getProtocol()); + natRuleStr.append(" "); + natRuleStr.append(m.getSourceIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getSource_port_min()); + natRuleStr.append("-"); + natRuleStr.append(m.getSourcePortMax()); + natRuleStr.append(" ] -> "); + natRuleStr.append(m.getDestinationIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getDestinationPortMin()); + natRuleStr.append("-"); + natRuleStr.append(m.getDestinationPortMax()); + natRuleStr.append(" ]) -->"); + if ("SourceNatRule".equals(storedRule.getType())) { + natRuleStr.append(storedRule.getToSourceIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(storedRule.getToSourceIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(storedRule.getToSourcePortMin()); + natRuleStr.append("-"); + natRuleStr.append(storedRule.getToSourcePortMax()); + natRuleStr.append(" ])"); + } + else { + natRuleStr.append(storedRule.getToDestinationIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(storedRule.getToDestinationIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(storedRule.getToDestinationPort()); + natRuleStr.append(" ])"); + } + s_logger.debug(natRuleStr.toString()); + } + + if ("SourceNatRule".equals(storedRule.getType())) { + if (outsideIp.equals(storedRule.getToSourceIpAddressMin()) && + outsideIp.equals(storedRule.getToSourceIpAddressMax()) && + storedRule.getToSourcePortMin() == null) { + // The outgoing rule exists + outgoing = storedRule; + } + } + if ("DestinationNatRule".equals(storedRule.getType()) && + storedRule.getToDestinationPort() != null) { + // Skip PortForwarding rules + continue; + } + // Compare against Ip as it should be a /32 cidr and the /32 is omitted + if (outsideIp.equals(storedRule.getMatch().getDestinationIpAddresses())) { + // The incoming rule exists + incoming = storedRule; + } + } + if (incoming != null && outgoing != null) { + if (insideIp.equals(incoming.getToDestinationIpAddressMin())) { + if (rule.revoked()) { + s_logger.debug("Deleting incoming rule " + incoming.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming.getUuid()); + + s_logger.debug("Deleting outgoing rule " + outgoing.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing.getUuid()); + } + } + else { + s_logger.debug("Updating outgoing rule " + outgoing.getUuid()); + outgoing.setToDestinationIpAddressMin(insideIp); + outgoing.setToDestinationIpAddressMax(insideIp); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing); + + s_logger.debug("Updating incoming rule " + outgoing.getUuid()); + incoming.setToSourceIpAddressMin(insideIp); + incoming.setToSourceIpAddressMax(insideIp); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming); + break; + } + } + else { + if (rule.revoked()) { + s_logger.warn("Tried deleting a rule that does not exist, " + + rule.getSrcIp() + " -> " + rule.getDstIp()); + break; + } + + // api createLogicalRouterNatRule + // create the dnat rule + Match m = new Match(); + m.setDestinationIpAddresses(outsideCidr); + DestinationNatRule newDnatRule = new DestinationNatRule(); + newDnatRule.setMatch(m); + newDnatRule.setToDestinationIpAddressMin(insideIp); + newDnatRule.setToDestinationIpAddressMax(insideIp); + newDnatRule = (DestinationNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newDnatRule); + s_logger.debug("Created " + natRuleToString(newDnatRule)); + + // create matching snat rule + m = new Match(); + m.setSourceIpAddresses(insideIp + "/32"); + SourceNatRule newSnatRule = new SourceNatRule(); + newSnatRule.setMatch(m); + newSnatRule.setToSourceIpAddressMin(outsideIp); + newSnatRule.setToSourceIpAddressMax(outsideIp); + newSnatRule = (SourceNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newSnatRule); + s_logger.debug("Created " + natRuleToString(newSnatRule)); + + } + } + return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() +" StaticNat rules applied"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(ConfigurePortForwardingRulesOnLogicalRouterCommand cmd, int numRetries) { + try { + NiciraNvpList existingRules = _niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); + // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) + // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule + // Any other SourceNat rule should have a corresponding DestinationNat rule + + for (PortForwardingRuleTO rule : cmd.getRules()) { + if (rule.isAlreadyAdded()) { + // Don't need to do anything + continue; + } + + // Find if a DestinationNat rule exists for this rule + String insideIp = rule.getDstIp(); + String insideCidr = rule.getDstIp() + "/32"; + String outsideIp = rule.getSrcIp(); + String outsideCidr = rule.getSrcIp() + "/32"; + + NatRule incoming = null; + NatRule outgoing = null; + + for (NatRule storedRule : existingRules.getResults()) { + if ("SourceNatRule".equals(storedRule.getType())) { + if (outsideIp.equals(storedRule.getToSourceIpAddressMin()) && + outsideIp.equals(storedRule.getToSourceIpAddressMax()) && + storedRule.getToSourcePortMin() == rule.getSrcPortRange()[0] && + storedRule.getToSourcePortMax() == rule.getSrcPortRange()[1]) { + // The outgoing rule exists + outgoing = storedRule; + } + } + else if ("DestinationNatRule".equals(storedRule.getType())) { + if (insideIp.equals(storedRule.getToDestinationIpAddressMin()) && + insideIp.equals(storedRule.getToDestinationIpAddressMax()) && + storedRule.getToDestinationPort() == rule.getDstPortRange()[0]) { + // The incoming rule exists + incoming = storedRule; + } + } + } + if (incoming != null && outgoing != null) { + if (insideIp.equals(incoming.getToDestinationIpAddressMin())) { + if (rule.revoked()) { + s_logger.debug("Deleting incoming rule " + incoming.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming.getUuid()); + + s_logger.debug("Deleting outgoing rule " + outgoing.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing.getUuid()); + } + } + else { + s_logger.debug("Updating outgoing rule " + outgoing.getUuid()); + outgoing.setToDestinationIpAddressMin(insideIp); + outgoing.setToDestinationIpAddressMax(insideIp); + outgoing.setToDestinationPort(rule.getDstPortRange()[0]); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing); + + s_logger.debug("Updating incoming rule " + outgoing.getUuid()); + incoming.setToSourceIpAddressMin(insideIp); + incoming.setToSourceIpAddressMax(insideIp); + incoming.setToSourcePortMin(rule.getSrcPortRange()[0]); + incoming.setToSourcePortMax(rule.getSrcPortRange()[1]); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming); + break; + } + } + else { + if (rule.revoked()) { + s_logger.warn("Tried deleting a rule that does not exist, " + + rule.getSrcIp() + " -> " + rule.getDstIp()); + break; + } + + // api createLogicalRouterNatRule + // create the dnat rule + Match m = new Match(); + m.setDestinationIpAddresses(outsideCidr); + if ("tcp".equals(rule.getProtocol())) { + m.setProtocol(6); + } + else if ("udp".equals(rule.getProtocol())) { + m.setProtocol(17); + } + m.setDestinationPortMin(rule.getSrcPortRange()[0]); + m.setDestinationPortMax(rule.getSrcPortRange()[1]); + DestinationNatRule newDnatRule = new DestinationNatRule(); + newDnatRule.setMatch(m); + newDnatRule.setToDestinationIpAddressMin(insideIp); + newDnatRule.setToDestinationIpAddressMax(insideIp); + newDnatRule.setToDestinationPort(rule.getDstPortRange()[0]); + newDnatRule = (DestinationNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newDnatRule); + s_logger.debug("Created " + natRuleToString(newDnatRule)); + + // create matching snat rule + m = new Match(); + m.setSourceIpAddresses(insideIp + "/32"); + if ("tcp".equals(rule.getProtocol())) { + m.setProtocol(6); + } + else if ("udp".equals(rule.getProtocol())) { + m.setProtocol(17); + } + m.setSourcePortMin(rule.getDstPortRange()[0]); + m.setSourcePortMax(rule.getDstPortRange()[1]); + SourceNatRule newSnatRule = new SourceNatRule(); + newSnatRule.setMatch(m); + newSnatRule.setToSourceIpAddressMin(outsideIp); + newSnatRule.setToSourceIpAddressMax(outsideIp); + newSnatRule.setToSourcePortMin(rule.getSrcPortRange()[0]); + newSnatRule.setToSourcePortMax(rule.getSrcPortRange()[1]); + newSnatRule = (SourceNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newSnatRule); + s_logger.debug("Created " + natRuleToString(newSnatRule)); + + } + } + return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() +" PortForwarding rules applied"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, e); + } + } + + } + private Answer executeRequest(ReadyCommand cmd) { return new ReadyAnswer(cmd); } @@ -354,4 +799,49 @@ public class NiciraNvpResource implements ServerResource { return executeRequest(cmd, numRetriesRemaining); } + private String natRuleToString(NatRule rule) { + + StringBuilder natRuleStr = new StringBuilder(); + natRuleStr.append("Rule "); + natRuleStr.append(rule.getUuid()); + natRuleStr.append(" ("); + natRuleStr.append(rule.getType()); + natRuleStr.append(") :"); + Match m = rule.getMatch(); + natRuleStr.append("match ("); + natRuleStr.append(m.getProtocol()); + natRuleStr.append(" "); + natRuleStr.append(m.getSourceIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getSource_port_min()); + natRuleStr.append("-"); + natRuleStr.append(m.getSourcePortMax()); + natRuleStr.append(" ] -> "); + natRuleStr.append(m.getDestinationIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getDestinationPortMin()); + natRuleStr.append("-"); + natRuleStr.append(m.getDestinationPortMax()); + natRuleStr.append(" ]) -->"); + if ("SourceNatRule".equals(rule.getType())) { + natRuleStr.append(rule.getToSourceIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToSourceIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(rule.getToSourcePortMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToSourcePortMax()); + natRuleStr.append(" ])"); + } + else { + natRuleStr.append(rule.getToDestinationIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToDestinationIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(rule.getToDestinationPort()); + natRuleStr.append(" ])"); + } + return natRuleStr.toString(); + } + } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 302eadbd234..acbbc414813 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -146,6 +146,7 @@ DROP TABLE IF EXISTS `cloud`.`s2s_vpn_gateway`; DROP TABLE IF EXISTS `cloud`.`s2s_vpn_connection`; DROP TABLE IF EXISTS `cloud`,`external_nicira_nvp_devices`; DROP TABLE IF EXISTS `cloud`,`nicira_nvp_nic_map`; +DROP TABLE IF EXISTS `cloud`,`nicira_nvp_router_map`; CREATE TABLE `cloud`.`version` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', @@ -2371,4 +2372,12 @@ CREATE TABLE `cloud`.`nicira_nvp_nic_map` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`nicira_nvp_router_map` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `logicalrouter_uuid` varchar(255) NOT NULL UNIQUE COMMENT 'nicira uuid of logical router', + `network_id` bigint unsigned NOT NULL UNIQUE COMMENT 'cloudstack id of the network', + PRIMARY KEY (`id`), + CONSTRAINT `fk_nicira_nvp_router_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + SET foreign_key_checks = 1; diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index c62bf28884d..b043046acb2 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -1414,6 +1414,11 @@ dictionary = { 'label.add.network.ACL': '', 'label.private.Gateway': '', 'label.VPC.router.details': '', -'label.VMs.in.tier': '' +'label.VMs.in.tier': '', +'label.add.NiciraNvp.device': '', +'label.delete.NiciraNvp': '', +'label.nicira.controller.address': '', +'label.nicira.transportzoneuuid': '', +'label.nicira.l3gatewayserviceuuid': '' }; diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 96b6fb9ab83..c6bc649c2df 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -1331,6 +1331,7 @@ case 'PortForwarding': serviceDisplayName = 'Port Forwarding'; break; case 'SecurityGroup': serviceDisplayName = 'Security Groups'; break; case 'UserData': serviceDisplayName = 'User Data'; break; + case 'Connectivity': serviceDisplayName = 'Virtual Networking'; break; default: serviceDisplayName = serviceName; break; } diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 7b272a756c7..3088b314cc4 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -3791,7 +3791,213 @@ name: { label: 'label.name' }//, //state: { label: 'label.status' } //comment it for now, since dataProvider below doesn't get called by widget code after action is done } - } + }, + // Nicira Nvp provider detail view + niciraNvp: { + type: 'detailView', + id: 'niciraNvpProvider', + label: 'label.niciraNvp', + viewAll: { label: 'label.devices', path: '_zone.niciraNvpDevices' }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + state: { label: 'label.state' } + } + ], + dataProvider: function(args) { + refreshNspData("NiciraNvp"); + var providerObj; + $(nspHardcodingArray).each(function(){ + if(this.id == "niciraNvp") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('niciraNvp') + }); + } + } + }, + actions: { + add: { + label: 'label.add.NiciraNvp.device', + createForm: { + title: 'label.add.NiciraNvp.device', + preFilter: function(args) { }, // TODO What is this? + fields: { + host: { + label: 'label.ip.address' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + }, + numretries: { + label: 'label.numretries', + defaultValue: '2' + }, + transportzoneuuid: { + label: 'label.nicira.transportzoneuuid' + }, + l3gatewayserviceuuid: { + label: 'label.nicira.l3gatewayserviceuuid' + } + } + }, + action: function(args) { + if(nspMap["niciraNvp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NiciraNvp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNiciraNvpProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(addNiciraNvpProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["niciraNvp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + else { + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + }, + messages: { + notification: function(args) { + return 'label.add.NiciraNvp.device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["niciraNvp"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["niciraNvp"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["niciraNvp"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid + } + } + ); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + } + } + } } } }, @@ -6345,7 +6551,171 @@ } } }, - + // FIXME convert to nicira detailview + // NiciraNvp devices listView + niciraNvpDevices: { + id: 'niciraNvpDevices', + title: 'label.devices', + listView: { + id: 'niciraNvpDevices', + fields: { + hostname: { label: 'label.nicira.controller.address' }, + transportzoneuuid: { label: 'label.nicira.transportzoneuuid'}, + l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' } + }, + actions: { + add: { + label: 'label.add.NiciraNvp.device', + createForm: { + title: 'label.add.NiciraNvp.device', + preFilter: function(args) { }, // TODO What is this? + fields: { + host: { + label: 'label.ip.address' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + }, + numretries: { + label: 'label.numretries', + defaultValue: '2' + }, + transportzoneuuid: { + label: 'label.nicira.transportzoneuuid' + }, + l3gatewayserviceuuid: { + label: 'label.nicira.l3gatewayserviceuuid' + } + } + }, + action: function(args) { + if(nspMap["niciraNvp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NiciraNvp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNiciraNvpProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; // Job has not completed + } + else { + clearInterval(addNiciraNvpProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["niciraNvp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + else { + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + }, + + messages: { + notification: function(args) { + return 'Added new Nicira Nvp Controller'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + dataProvider: function(args) { + $.ajax({ + url: createURL("listNiciraNvpDevices&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + data: { page: args.page, pageSize: pageSize }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listniciranvpdeviceresponse.niciranvpdevice; + args.response.success({data: items}); + } + }); + }, + detailView: { + name: 'Nicira Nvp details', + actions: { + 'remove': { + label: 'label.delete.NiciaNvp', + messages: { + confirm: function(args) { + return 'message.confirm.delete.NiciraNvp'; + }, + notification: function(args) { + return 'label.delete.NiciraNvp'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteNiciraNvpDevice&nvpdeviceid=" + args.context.niciraNvpDevices[0].nvpdeviceid), + dataType: "json", + async: true, + success: function(json) { + var jid = json.deleteniciranvpdeviceresponse.jobid; + args.response.success( + {_custom: + {jobId: jid} + } + ); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + nvpdeviceid: { label: 'label.id' }, + hostname: { label: 'label.ip.address' }, + transportzoneuuid: { label: 'label.nicira.transportzoneuuid' }, + l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' } + } + ], + dataProvider: function(args) { + $.ajax({ + url: createURL("listNiciraNvpDevices&nvpdeviceid=" + args.context.niciraNvpDevices[0].nvpdeviceid), + dataType: "json", + async: true, + success: function(json) { + var item = json.listniciranvpdeviceresponse.niciranvpdevice[0]; + args.response.success({data: item}); + } + }); + } + } + } + } + } + }, pods: { title: 'label.pods', listView: { @@ -9360,6 +9730,40 @@ }); } + function addNiciraNvpDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { + var array1 = []; + array1.push("&physicalnetworkid=" + physicalNetworkObj.id); + array1.push("&username=" + todb(args.data.username)); + array1.push("&password=" + todb(args.data.password)); + array1.push("&hostname=" + todb(args.data.host)); + array1.push("&transportzoneuuid=" + todb(args.data.transportzoneuuid)); + + var l3GatewayServiceUuid = args.data.l3gatewayserviceuuid; + if(l3GatewayServiceUuid != null && l3GatewayServiceUuid.length > 0) { + array1.push("&l3gatewayserviceuuid=" + todb(args.data.l3gatewayserviceuuid)); + } + + $.ajax({ + url: createURL(apiCmd + array1.join("")), + dataType: "json", + success: function(json) { + var jid = json[apiCmdRes].jobid; + args.response.success( + {_custom: + {jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult[apiCmdObj]; + + return item; + } + } + } + ); + } + }); + } + + var afterCreateZonePhysicalNetworkTrafficTypes = function(args, newZoneObj, newPhysicalnetwork) { $.ajax({ url: createURL("updatePhysicalNetwork&state=Enabled&id=" + newPhysicalnetwork.id), @@ -9959,6 +10363,9 @@ case "SecurityGroupProvider": nspMap["securityGroups"] = items[i]; break; + case "NiciraNvp": + nspMap["niciraNvp"] = items[i]; + break; } } } @@ -9975,7 +10382,12 @@ id: 'virtualRouter', name: 'Virtual Router', state: nspMap.virtualRouter ? nspMap.virtualRouter.state : 'Disabled' - } + }, + { + id: 'niciraNvp', + name: 'Nicira Nvp', + state: nspMap.niciraNvp ? nspMap.niciraNvp.state : 'Disabled' + } ]; if(selectedZoneObj.networktype == "Basic") {