From 880e475f4095908817048d5cfd113dac0732a2fb Mon Sep 17 00:00:00 2001 From: Sigert Goeminne Date: Thu, 6 Oct 2016 14:30:59 +0200 Subject: [PATCH] CLOUDSTACK-9806: Nuage domain template selection per VPC Co-Authored-By: Prashanth Manthena Co-Authored-By: Frank Maximus Bug: https://issues.apache.org/jira/browse/CLOUDSTACK-9806 Design Document: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Nuage+domain+template+selection+per+VPC --- .../api/guru/DeallocateVmVspCommand.java | 1 + .../manager/ListVspDomainTemplatesAnswer.java | 44 + .../ListVspDomainTemplatesCommand.java | 47 + .../AssociateNuageVspDomainTemplateCmd.java | 111 +++ .../ListNuageVspDomainTemplatesCmd.java | 120 +++ .../ListNuageVspGlobalDomainTemplateCmd.java | 79 ++ .../com/cloud/api/commands/VspConstants.java | 1 + .../NuageVspDomainTemplateResponse.java | 45 + .../network/element/NuageVspElement.java | 8 + .../guru/NuageVspGuestNetworkGuru.java | 15 + .../network/manager/NuageVspManager.java | 54 ++ .../network/manager/NuageVspManagerImpl.java | 271 ++++-- .../wrapper/NuageVspCommandWrapper.java | 5 + .../NuageVspEntityExistsCommandWrapper.java | 4 + ...eVspListDomainTemplatesCommandWrapper.java | 51 ++ .../com/cloud/util/NuageVspEntityBuilder.java | 5 +- .../src/com/cloud/util/NuageVspUtil.java | 22 - .../nuage-vsp/test/com/cloud/NuageTest.java | 25 +- .../guru/NuageVspGuestNetworkGuruTest.java | 7 - .../network/manager/NuageVspManagerTest.java | 114 ++- .../cloud/util/NuageVspEntityBuilderTest.java | 86 +- pom.xml | 36 +- .../plugins/nuagevsp/nuageTestCase.py | 15 +- .../test_nuage_vsp_domain_template.py | 831 ++++++++++++++++++ tools/apidoc/gen_toc.py | 2 + ui/l10n/en.js | 2 + ui/scripts/network.js | 426 ++++++--- ui/scripts/ui/dialog.js | 12 + 28 files changed, 2121 insertions(+), 318 deletions(-) create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDomainTemplateResponse.java create mode 100644 plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java create mode 100644 test/integration/plugins/nuagevsp/test_nuage_vsp_domain_template.py diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java index a122f039035..327c0b5151b 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java @@ -29,6 +29,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import com.cloud.agent.api.Command; + public class DeallocateVmVspCommand extends Command { private final VspNetwork _network; diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java new file mode 100644 index 00000000000..ec13d671857 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java @@ -0,0 +1,44 @@ +// +// 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.manager; + +import com.cloud.agent.api.Answer; +import net.nuage.vsp.acs.client.api.model.VspDomainTemplate; + +import java.util.List; + + +public class ListVspDomainTemplatesAnswer extends Answer { + private List domainTemplates; + + public ListVspDomainTemplatesAnswer(ListVspDomainTemplatesCommand command, List domainTemplates) { + super(command); + + this.domainTemplates = domainTemplates; + } + + public ListVspDomainTemplatesAnswer(ListVspDomainTemplatesCommand command, Exception e) { + super(command, e); + } + + public List getDomainTemplates() { + return domainTemplates; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java new file mode 100644 index 00000000000..e1740044cdf --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java @@ -0,0 +1,47 @@ +// +// 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.manager; + +import com.cloud.agent.api.Command; +import net.nuage.vsp.acs.client.api.model.VspDomain; + + +public class ListVspDomainTemplatesCommand extends Command { + private final VspDomain _domain; + private final String _name; + + public ListVspDomainTemplatesCommand(VspDomain domain, String name) { + this._domain = domain; + this._name = name; + } + + public VspDomain getDomain() { + return _domain; + } + + public String getName() { + return _name; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java new file mode 100644 index 00000000000..3eadf1013f9 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java @@ -0,0 +1,111 @@ +// +// 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.api.commands; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; + +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.context.CallContext; + +import javax.inject.Inject; + +@APICommand(name = AssociateNuageVspDomainTemplateCmd.APINAME, responseObject = SuccessResponse.class, description = "associate a vpc with a domain template", authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.User}) +public class AssociateNuageVspDomainTemplateCmd extends BaseCmd { + static final String APINAME = "associateNuageVspDomainTemplate"; + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, required = true, description = "VPC ID") + private Long vpcId; + + + @Parameter(name = VspConstants.NUAGE_VSP_API_DOMAIN_TEMPLATE, type = CommandType.STRING, required = true, description = "the name of the domain template") + private String domainTemplate; + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the physical network ID") + private Long physicalNetworkId; + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone ID") + private Long zoneId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getVpcId() { + return vpcId; + } + + public String getDomainTemplate() { return domainTemplate; } + + public Long getZoneId() { return zoneId; } + + public Long getPhysicalNetworkId() { return physicalNetworkId; } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + boolean result =_nuageVspManager.associateNuageVspDomainTemplate(this); + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setResponseName(getCommandName()); + response.setSuccess(result); + this.setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java new file mode 100644 index 00000000000..2fc7a89afdc --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java @@ -0,0 +1,120 @@ +// +// 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.api.commands; + +import com.cloud.api.response.NuageVspDomainTemplateResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.api.response.ZoneResponse; + +import javax.inject.Inject; +import java.util.List; + +@APICommand(name = ListNuageVspDomainTemplatesCmd.APINAME, responseObject = BaseResponse.class, description = "Lists Nuage VSP domain templates", since = "4.11", responseHasSensitiveInfo = false, authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.User}) +public class ListNuageVspDomainTemplatesCmd extends BaseCmd { + static final String APINAME = "listNuageVspDomainTemplates"; + + @Inject + private NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, + description = "the domain ID") + private Long domainId; + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, + description = "the physical network ID") + private Long physicalNetworkId; + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, + description = "the zone ID") + private Long zoneId; + + @Parameter(name = ApiConstants.KEYWORD, type = CommandType.STRING, + description = "filters the domain templates which contain the keyword") + private String keyword; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getKeyword() { + return keyword; + } + + public Long getDomainId() { + return domainId; + } + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public Long getZoneId() { return zoneId; } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + List responses = _nuageVspManager.listNuageVspDomainTemplates(this); + ListResponse response = new ListResponse<>(); + response.setResponses(responses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + @Override + public String getCommandName() { + return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX; + } + + @Override public long getEntityOwnerId() { + return 0; //not owned by anyone + } + +} + diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.java new file mode 100644 index 00000000000..a4dfd45ddf8 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.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.api.commands; + +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ListResponse; + +import javax.inject.Inject; + +import java.util.LinkedList; +import java.util.List; + +import com.cloud.api.response.NuageVspDomainTemplateResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.user.Account; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = ListNuageVspGlobalDomainTemplateCmd.APINAME, responseObject = BaseResponse.class, description = "Lists Nuage VSP domain templates", authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.User}) +public class ListNuageVspGlobalDomainTemplateCmd extends BaseCmd { + static final String APINAME = "listNuageVspGlobalDomainTemplate"; + + @Inject + private NuageVspManager _nuageVspManager; + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + try { + List responses = new LinkedList<>(); + NuageVspDomainTemplateResponse answer = new NuageVspDomainTemplateResponse(_nuageVspManager.NuageVspVpcDomainTemplateName.value(),_nuageVspManager.NuageVspVpcDomainTemplateName.value()); + responses.add(answer); + + ListResponse response = new ListResponse<>(); + response.setResponses(responses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + @Override + public String getCommandName() { + return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX; + } + + @Override public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java index 55e6b474cae..5b226afe591 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java @@ -34,4 +34,5 @@ public class VspConstants { public static final String NUAGE_VSP_API_RESOURCE_INFO = "resourceinfo"; public static final String NUAGE_VSP_CMS_ID = "cmsid"; public static final String NUAGE_VSP_API_UNDERLAY = "underlay"; + public static final String NUAGE_VSP_API_DOMAIN_TEMPLATE = "domaintemplate"; } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDomainTemplateResponse.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDomainTemplateResponse.java new file mode 100644 index 00000000000..ce36e8e8ed8 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDomainTemplateResponse.java @@ -0,0 +1,45 @@ +// +// 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.api.response; + +import com.cloud.serializer.Param; +import org.apache.cloudstack.api.BaseResponse; + +public class NuageVspDomainTemplateResponse extends BaseResponse { + @Param(description = "the name of the domain template") + private String name; + + @Param(description = "the description of the domain template") + private String description; + + public NuageVspDomainTemplateResponse(String name, String description) { + this.name = name; + this.description = description; + this.setObjectName("domaintemplates"); + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java index a7ce8c8d403..d7b422b9853 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java @@ -29,6 +29,7 @@ import javax.annotation.Nullable; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.lang3.StringUtils; import net.nuage.vsp.acs.client.api.model.VspAclRule; import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption; import net.nuage.vsp.acs.client.api.model.VspNetwork; @@ -121,6 +122,7 @@ import com.cloud.util.NuageVspEntityBuilder; import com.cloud.util.NuageVspUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; @@ -657,6 +659,12 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider } } + String globalDomainTemplate = _nuageVspManager.NuageVspVpcDomainTemplateName.value(); + if (StringUtils.isNotBlank(globalDomainTemplate) && !_nuageVspManager.checkIfDomainTemplateExist(vpc.getDomainId(),globalDomainTemplate,vpc.getZoneId(),null)) { + s_logger.warn("The global pre configured domain template does not exist on the VSD."); + throw new CloudRuntimeException("The global pre configured domain template does not exist on the VSD."); + } + return true; } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java index 0a4733be244..112d444c710 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java @@ -166,6 +166,21 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { throw new ConcurrentOperationException("Unable to acquire lock on network " + networkId); } + /* Check if an acl template is used in combination with a pre-configured DT. -> show an error if there is + Rollback of the network fails in core CS -> networkOrchestrator. */ + if(network.getVpcId() != null) { + VpcDetailVO detail = _vpcDetailsDao.findDetail(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName); + if (detail != null && network.getNetworkACLId() != null) { + s_logger.error("Pre-configured DT are used in combination with ACL lists. Which is not supported."); + throw new IllegalArgumentException("CloudStack ACLs are not supported with Nuage Preconfigured Domain Template"); + } + + if(detail != null && !_nuageVspManager.checkIfDomainTemplateExist(network.getDomainId(),detail.getValue(),network.getDataCenterId(),null)){ + s_logger.error("The provided domain template does not exist on the VSD."); + throw new IllegalArgumentException("The provided domain template does not exist on the VSD anymore."); + } + } + NetworkVO implemented = null; try { if (offering.getGuestType() == GuestType.Isolated && network.getState() != State.Implementing) { diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java index 429b11d5967..056b22eab41 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java @@ -19,19 +19,26 @@ package com.cloud.network.manager; +import com.cloud.agent.api.manager.EntityExistsCommand; import com.cloud.api.commands.AddNuageVspDeviceCmd; +import com.cloud.api.commands.AssociateNuageVspDomainTemplateCmd; import com.cloud.api.commands.DeleteNuageVspDeviceCmd; import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.api.commands.ListNuageVspDomainTemplatesCmd; import com.cloud.api.commands.UpdateNuageVspDeviceCmd; import com.cloud.api.response.NuageVlanIpRangeResponse; import com.cloud.api.response.NuageVspDeviceResponse; import com.cloud.dc.Vlan; +import com.cloud.api.response.NuageVspDomainTemplateResponse; import com.cloud.host.HostVO; +import com.cloud.network.Network; import com.cloud.network.NuageVspDeviceVO; import com.cloud.utils.component.PluggableService; + import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.ConfigKey.Scope; + import java.util.List; public interface NuageVspManager extends PluggableService { @@ -79,6 +86,10 @@ public interface NuageVspManager extends PluggableService { String NETWORK_METADATA_VSD_SUBNET_ID = "vsdSubnetId"; + String CMSID_CONFIG_KEY = "nuagevsp.cms.id"; + + String NUAGE_VSP_ISOLATION = "VSP"; + NuageVspDeviceVO addNuageVspDevice(AddNuageVspDeviceCmd cmd); NuageVspDeviceVO updateNuageVspDevice(UpdateNuageVspDeviceCmd cmd); @@ -99,4 +110,47 @@ public interface NuageVspManager extends PluggableService { List filterNuageVlanIpRanges(List vlanIpRanges, Boolean underlay); + List listNuageVspDomainTemplates(ListNuageVspDomainTemplatesCmd cmd); + + List listNuageVspDomainTemplates(long domainId, String keyword, Long zoneId, Long physicalNetworkId); + + /** + * Associates a Nuage Vsp domain template with a + * @param cmd + * @return + */ + boolean associateNuageVspDomainTemplate(AssociateNuageVspDomainTemplateCmd cmd); + + /** + * Queries the VSD to check if the entity provided in the entityCmd exists on the VSD + * @param cmd entityCommand which contains the ACS class of the entity and the UUID + * @param hostId the hostId of the VSD + * @return true if an entity exists with the UUI on the VSD, otherwise false. + */ + boolean entityExist(EntityExistsCommand cmd, Long hostId); + + /** + * Sets the preconfigured domain template for a given network + * @param network + * @param domainTemplateName + */ + void setPreConfiguredDomainTemplateName(Network network, String domainTemplateName); + + /** + * Returns the current pre configured domain template for a given network + * @param network + * @return + */ + String getPreConfiguredDomainTemplateName(Network network); + + /** + * Checks if a given domain template exists or not on the VSD. + * @param domainId + * @param domainTemplate The name of the domain template for which we need to query the VSD. + * @param zoneId zoneId OR PhysicalNetworkId needs to be provided. + * @param physicalNetworkId zoneId OR PhysicalNetworkId needs to be provided. + * @return true if the domain template exists on the VSD else false if it does not exist on the VSD + */ + public boolean checkIfDomainTemplateExist(Long domainId, String domainTemplate, Long zoneId, Long physicalNetworkId); + } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java index fb79f09b911..b25a235f2bf 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java @@ -19,32 +19,6 @@ package com.cloud.network.manager; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import javax.annotation.Nonnull; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader; -import net.nuage.vsp.acs.client.api.model.VspApiDefaults; -import net.nuage.vsp.acs.client.api.model.VspDomain; -import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp; -import net.nuage.vsp.acs.client.api.model.VspHost; -import net.nuage.vsp.acs.client.common.NuageVspApiVersion; -import net.nuage.vsp.acs.client.common.NuageVspConstants; - -import net.nuage.vsp.acs.client.exception.NuageVspException; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; - import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import com.google.common.collect.HashMultimap; @@ -53,14 +27,42 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; - +import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader; +import net.nuage.vsp.acs.client.api.model.VspApiDefaults; +import net.nuage.vsp.acs.client.api.model.VspDomain; +import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp; +import net.nuage.vsp.acs.client.api.model.VspDomainTemplate; +import net.nuage.vsp.acs.client.api.model.VspHost; +import net.nuage.vsp.acs.client.common.NuageVspApiVersion; +import net.nuage.vsp.acs.client.common.NuageVspConstants; +import net.nuage.vsp.acs.client.exception.NuageVspException; import org.apache.cloudstack.api.ResponseGenerator; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.framework.messagebus.MessageBus; import org.apache.cloudstack.network.ExternalNetworkDeviceManager; +import org.apache.cloudstack.resourcedetail.VpcDetailVO; +import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; + +import javax.annotation.Nonnull; +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -71,6 +73,8 @@ import com.cloud.agent.api.manager.CleanUpDomainCommand; import com.cloud.agent.api.manager.EntityExistsCommand; import com.cloud.agent.api.manager.GetApiDefaultsAnswer; import com.cloud.agent.api.manager.GetApiDefaultsCommand; +import com.cloud.agent.api.manager.ListVspDomainTemplatesAnswer; +import com.cloud.agent.api.manager.ListVspDomainTemplatesCommand; import com.cloud.agent.api.manager.SupportedApiVersionCommand; import com.cloud.agent.api.manager.UpdateNuageVspDeviceCommand; import com.cloud.agent.api.sync.SyncDomainCommand; @@ -78,14 +82,18 @@ import com.cloud.agent.api.sync.SyncNuageVspCmsIdAnswer; import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand; import com.cloud.api.ApiDBUtils; import com.cloud.api.commands.AddNuageVspDeviceCmd; +import com.cloud.api.commands.AssociateNuageVspDomainTemplateCmd; import com.cloud.api.commands.DeleteNuageVspDeviceCmd; import com.cloud.api.commands.DisableNuageUnderlayVlanIpRangeCmd; import com.cloud.api.commands.EnableNuageUnderlayVlanIpRangeCmd; import com.cloud.api.commands.ListNuageUnderlayVlanIpRangesCmd; import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.api.commands.ListNuageVspDomainTemplatesCmd; +import com.cloud.api.commands.ListNuageVspGlobalDomainTemplateCmd; import com.cloud.api.commands.UpdateNuageVspDeviceCmd; import com.cloud.api.response.NuageVlanIpRangeResponse; import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.api.response.NuageVspDomainTemplateResponse; import com.cloud.dc.DataCenterVO; import com.cloud.dc.Vlan; import com.cloud.dc.VlanDetailsVO; @@ -104,14 +112,13 @@ import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDetailsDao; import com.cloud.network.Network; -import com.cloud.network.NetworkModel; import com.cloud.network.Networks; import com.cloud.network.NuageVspDeviceVO; import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkDetailVO; +import com.cloud.network.dao.NetworkDetailsDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NuageVspDao; import com.cloud.network.dao.PhysicalNetworkDao; @@ -120,14 +127,13 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.resource.NuageVspResource; import com.cloud.network.resource.NuageVspResourceConfiguration; -import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.VpcOffering; import com.cloud.network.vpc.VpcOfferingServiceMapVO; import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcOfferingDao; import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao; -import com.cloud.network.vpc.dao.VpcServiceMapDao; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingServiceMapVO; import com.cloud.offerings.NetworkOfferingVO; @@ -135,7 +141,6 @@ import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; -import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; import com.cloud.util.NuageVspEntityBuilder; import com.cloud.util.NuageVspUtil; @@ -158,7 +163,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, public static final Multimap NUAGE_VSP_VPC_SERVICE_MAP; private static final ConfigKey[] NUAGE_VSP_CONFIG_KEYS = new ConfigKey[] { NuageVspConfigDns, NuageVspDnsExternal, NuageVspConfigGateway, NuageVspSharedNetworkDomainTemplateName, NuageVspVpcDomainTemplateName, NuageVspIsolatedNetworkDomainTemplateName }; - public static final String CMSID_CONFIG_KEY = "nuagevsp.cms.id"; + @Inject ResourceManager _resourceMgr; @@ -173,13 +178,15 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, @Inject NetworkDao _networkDao; @Inject + NetworkDetailsDao _networkDetailsDao; + @Inject VpcOfferingDao _vpcOffDao; @Inject VpcOfferingServiceMapDao _vpcOffSvcMapDao; @Inject VpcDao _vpcDao; @Inject - VpcManager _vpcManager; + private VpcDetailsDao _vpcDetailsDao; @Inject NuageVspDao _nuageVspDao; @Inject @@ -187,16 +194,6 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, @Inject ConfigurationDao _configDao; @Inject - NetworkModel _ntwkModel; - @Inject - AccountManager _accountMgr; - @Inject - IPAddressDao _ipAddressDao; - @Inject - FirewallRulesDao _firewallDao; - @Inject - VpcServiceMapDao _vpcSrvcDao; - @Inject AgentManager _agentMgr; @Inject private DomainDao _domainDao; @@ -212,7 +209,6 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, VlanDetailsDao _vlanDetailsDao; @Inject ResponseGenerator _responseGenerator; - @Inject MessageBus _messageBus; @@ -240,11 +236,16 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, return Lists.>newArrayList( AddNuageVspDeviceCmd.class, DeleteNuageVspDeviceCmd.class, - ListNuageVspDevicesCmd.class, UpdateNuageVspDeviceCmd.class, - EnableNuageUnderlayVlanIpRangeCmd.class, + ListNuageVspDevicesCmd.class, + DisableNuageUnderlayVlanIpRangeCmd.class, - ListNuageUnderlayVlanIpRangesCmd.class + EnableNuageUnderlayVlanIpRangeCmd.class, + ListNuageUnderlayVlanIpRangesCmd.class, + + ListNuageVspDomainTemplatesCmd.class, + ListNuageVspGlobalDomainTemplateCmd.class, + AssociateNuageVspDomainTemplateCmd.class ); } @@ -821,6 +822,166 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, return Lists.newArrayList(); } + + @Override + public List listNuageVspDomainTemplates(ListNuageVspDomainTemplatesCmd cmd){ + long domainId; + + if (cmd.getDomainId() != null) { + domainId = cmd.getDomainId(); + } else { + domainId = CallContext.current().getCallingAccount().getDomainId(); + } + + return listNuageVspDomainTemplates(domainId, cmd.getKeyword(), cmd.getZoneId(), cmd.getPhysicalNetworkId()); + } + + @Override + public List listNuageVspDomainTemplates(long domainId, String keyword, Long zoneId, Long passedPhysicalNetworkId) { + Optional physicalNetworkId; + Domain domain = _domainDao.findById(domainId); + VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(domain); + + if (passedPhysicalNetworkId != null) { + physicalNetworkId = Optional.of(passedPhysicalNetworkId); + } else if (zoneId != null) { + physicalNetworkId = Optional.of(getPhysicalNetworkBasedOnZone(zoneId)); + } else { + throw new InvalidParameterValueException("No zoneid or physicalnetworkid specified."); + } + + List domainTemplates; + + ListVspDomainTemplatesCommand agentCmd = new ListVspDomainTemplatesCommand(vspDomain, keyword); + Long hostId = getNuageVspHostId(physicalNetworkId.get()); + + ListVspDomainTemplatesAnswer answer = (ListVspDomainTemplatesAnswer) _agentMgr.easySend(hostId, agentCmd); + domainTemplates = answer.getDomainTemplates(); + + return domainTemplates.stream() + .map(NuageVspManagerImpl::createDomainTemplateResponse) + .collect(Collectors.toList()); + } + + private static NuageVspDomainTemplateResponse createDomainTemplateResponse(VspDomainTemplate dt) { + return new NuageVspDomainTemplateResponse(dt.getName(), dt.getDescription()); + } + + /** + * Returns the PhysicalNetworkId based on a zoneId + * @param zoneId != null, the zone id for which we need to retrieve the PhysicalNetworkId + * @return the physical network id if it's found otherwise null + */ + private Long getPhysicalNetworkBasedOnZone(Long zoneId){ + + Long physicalNetworkId = null; + List physicalNetworkVOs = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, Networks.TrafficType.Guest); + for (PhysicalNetworkVO physicalNetwok : physicalNetworkVOs) { + if (physicalNetwok.getIsolationMethods().contains(NUAGE_VSP_ISOLATION)) { + physicalNetworkId = physicalNetwok.getId(); + break; + } + } + return physicalNetworkId; + } + + @Override + public boolean associateNuageVspDomainTemplate(AssociateNuageVspDomainTemplateCmd cmd){ + VpcVO vpc = _vpcDao.findById(cmd.getVpcId()); + Long physicalNetworkId; + if (cmd.getPhysicalNetworkId() != null) { + physicalNetworkId = cmd.getPhysicalNetworkId(); + } else if (cmd.getZoneId() != null) { + physicalNetworkId = getPhysicalNetworkBasedOnZone(cmd.getZoneId()); + } else { + throw new InvalidParameterValueException("No zoneid or physicalnetworkid specified."); + } + + EntityExistsCommand entityCmd = new EntityExistsCommand(VpcVO.class, vpc.getUuid()); + boolean exists = entityExist(entityCmd, physicalNetworkId); + if (exists) { + throw new CloudRuntimeException("Failed to associate domain template, VPC is already pushed to the Nuage VSP device."); + } + + if (!checkIfDomainTemplateExist(vpc.getDomainId(), cmd.getDomainTemplate(), cmd.getZoneId(), cmd.getPhysicalNetworkId())) { + throw new InvalidParameterValueException("Could not find a Domain Template with name: " + cmd.getDomainTemplate()); + } + setPreConfiguredDomainTemplateName(cmd.getVpcId(), cmd.getDomainTemplate()); + return true; + } + + @Override + public boolean checkIfDomainTemplateExist(Long domainId, String domainTemplate, Long zoneId, Long physicalNetworkId){ + List domainTemplateList = listNuageVspDomainTemplates(domainId, domainTemplate, zoneId, physicalNetworkId); + if (domainTemplateList != null) { + for (NuageVspDomainTemplateResponse val : domainTemplateList) { + if (val.getName().equals(domainTemplate)) { + return true; + } + } + } + return false; + } + + @Override + public boolean entityExist(EntityExistsCommand cmd, Long physicalNetworkId){ + Long hostId = getNuageVspHostId(physicalNetworkId); + Answer answer = _agentMgr.easySend(hostId, cmd); + if (answer != null) { + return answer.getResult(); + } + throw new CloudRuntimeException("No answer received from the client"); + } + + /** + * Sets the preconfigured domain template of a vpc to the given value. + * @param vpcId + * @param domainTemplateName + */ + private void setPreConfiguredDomainTemplateName(long vpcId, String domainTemplateName) { + //remove the previous nuageDomainTemplate if it is present. + if (_vpcDetailsDao.findDetail(vpcId, NuageVspManager.nuageDomainTemplateDetailName) != null) { + _vpcDetailsDao.removeDetail(vpcId, NuageVspManager.nuageDomainTemplateDetailName); + } + VpcDetailVO vpcDetail = new VpcDetailVO(vpcId, NuageVspManager.nuageDomainTemplateDetailName, domainTemplateName, false); + _vpcDetailsDao.persist(vpcDetail); + } + + @Override + public void setPreConfiguredDomainTemplateName(Network network, String domainTemplateName) { + + if (network.getVpcId() != null) { + setPreConfiguredDomainTemplateName(network.getVpcId(), domainTemplateName); + } else { + NetworkDetailVO networkDetail = new NetworkDetailVO(network.getId(), NuageVspManager.nuageDomainTemplateDetailName, domainTemplateName, false); + _networkDetailsDao.persist(networkDetail); + } + } + + @Override + public String getPreConfiguredDomainTemplateName(Network network) { + + if (network.getVpcId() != null) { + VpcDetailVO domainTemplateNetworkDetail = _vpcDetailsDao.findDetail(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName); + if (domainTemplateNetworkDetail != null) { + return domainTemplateNetworkDetail.getValue(); + } + + return NuageVspVpcDomainTemplateName.value(); + } else { + NetworkDetailVO domainTemplateNetworkDetail = _networkDetailsDao.findDetail(network.getId(), NuageVspManager.nuageDomainTemplateDetailName); + if (domainTemplateNetworkDetail != null) { + return domainTemplateNetworkDetail.getValue(); + } + + if (network.getGuestType() == Network.GuestType.Shared) { + return NuageVspSharedNetworkDomainTemplateName.value(); + } + + return NuageVspIsolatedNetworkDomainTemplateName.value(); + } + } + @Override public HostVO getNuageVspHost(long physicalNetworkId) { HostVO nuageVspHost; @@ -830,7 +991,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); List physicalNetworksInZone = _physicalNetworkDao.listByZone(physicalNetwork.getDataCenterId()); for (PhysicalNetworkVO physicalNetworkInZone : physicalNetworksInZone) { - if (physicalNetworkInZone.getIsolationMethods().contains("VSP")) { + if (physicalNetworkInZone.getIsolationMethods().contains(NUAGE_VSP_ISOLATION)) { nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkInZone.getId()); break; } @@ -999,6 +1160,16 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, }); } + private Long getNuageVspHostId(long physicalNetworkId) { + List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + return config.getHostId(); + } + + throw new CloudRuntimeException("There is no Nuage VSP device configured on physical network " + physicalNetworkId); + } + @DB private void initNuageVspVpcOffering() { //configure default Nuage VSP vpc offering diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java index ee3f5c58c83..879ba812a1b 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java @@ -23,10 +23,12 @@ import javax.naming.ConfigurationException; import net.nuage.vsp.acs.client.exception.NuageVspException; +import net.nuage.vsp.acs.client.exception.NuageVspUnsupportedRequestException; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.UnsupportedAnswer; import com.cloud.network.resource.NuageVspResource; import com.cloud.resource.CommandWrapper; @@ -40,6 +42,9 @@ public abstract class NuageVspCommandWrapper extends CommandW boolean success = executeNuageVspCommand(command, nuageVspResource); String detail = fillDetail(new StringBuilder(), command).append(" on ").append(nuageVspResource.getName()).toString(); return new Answer(command, success, detail); + } catch (NuageVspUnsupportedRequestException e) { + s_logger.error("Failure during " + command + " on " + nuageVspResource.getName(), e); + return new UnsupportedAnswer(command, e.getMessage()); //New Exception so there is no stacktrace showed in the UI when changing ACL lists. } catch (NuageVspException | ConfigurationException e) { s_logger.error("Failure during " + command + " on " + nuageVspResource.getName(), e); return new Answer(command, e); diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java index ecf06298ee3..6e737b8a0c2 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java @@ -27,6 +27,7 @@ import net.nuage.vsp.acs.client.exception.NuageVspException; import com.cloud.agent.api.manager.EntityExistsCommand; import com.cloud.dc.Vlan; import com.cloud.network.resource.NuageVspResource; +import com.cloud.network.vpc.VpcVO; import com.cloud.resource.ResourceWrapper; @ResourceWrapper(handles = EntityExistsCommand.class) @@ -44,6 +45,9 @@ public final class NuageVspEntityExistsCommandWrapper extends NuageVspCommandWra if (Vlan.class.isAssignableFrom(clazz)) { entityType = NuageVspEntity.SHARED_NETWORK; } + else if(VpcVO.class.isAssignableFrom(clazz)){ + entityType = NuageVspEntity.ZONE; + } return entityType; } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java new file mode 100644 index 00000000000..668034ed8dc --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java @@ -0,0 +1,51 @@ +// +// 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.vsp.resource.wrapper; + +import com.cloud.agent.api.manager.ListVspDomainTemplatesAnswer; +import com.cloud.agent.api.manager.ListVspDomainTemplatesCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; +import net.nuage.vsp.acs.client.api.NuageVspManagerClient; +import net.nuage.vsp.acs.client.api.model.VspDomainTemplate; +import net.nuage.vsp.acs.client.exception.NuageVspException; + +import javax.naming.ConfigurationException; +import java.util.List; + + +@ResourceWrapper(handles = ListVspDomainTemplatesCommand.class) +public class NuageVspListDomainTemplatesCommandWrapper extends CommandWrapper { + + @Override + public ListVspDomainTemplatesAnswer execute(ListVspDomainTemplatesCommand command, NuageVspResource serverResource) { + NuageVspManagerClient client = null; + try { + client = serverResource.getNuageVspManagerClient(); + List domainTemplates = client.getDomainTemplates(command.getDomain(), command.getName()); + + return new ListVspDomainTemplatesAnswer(command, domainTemplates); + } catch (ConfigurationException | NuageVspException e) { + return new ListVspDomainTemplatesAnswer(command, e); + } + + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java index 9b0e0d93213..5a0a5d12e0b 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java @@ -146,8 +146,7 @@ public class NuageVspEntityBuilder { List allSharedNetworks = _networkDao.listByGuestType(Network.GuestType.Shared); for (NetworkVO sharedNetwork : allSharedNetworks) { if (_networkModel.isNetworkAvailableInDomain(sharedNetwork.getId(), domain.getId())) { - NetworkOffering networkOffering = _networkOfferingDao.findById(sharedNetwork.getNetworkOfferingId()); - String preConfiguredDomainTemplateName = NuageVspUtil.getPreConfiguredDomainTemplateName(_configurationDao, _networkDetailsDao, sharedNetwork, networkOffering); + String preConfiguredDomainTemplateName = _nuageVspManager.getPreConfiguredDomainTemplateName(sharedNetwork); if (!sharedNetworkUuids.containsKey(preConfiguredDomainTemplateName)) { sharedNetworkUuids.put(preConfiguredDomainTemplateName, Lists.newArrayList()); } @@ -241,7 +240,7 @@ public class NuageVspEntityBuilder { boolean firewallServiceSupported = _networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.Firewall); vspNetworkBuilder.firewallServiceSupported(firewallServiceSupported); - String preConfiguredDomainTemplateName = NuageVspUtil.getPreConfiguredDomainTemplateName(_configurationDao, _networkDetailsDao, network, networkOffering); + String preConfiguredDomainTemplateName = _nuageVspManager.getPreConfiguredDomainTemplateName(network); vspNetworkBuilder.domainTemplateName(preConfiguredDomainTemplateName); if (usesVirtualRouter(networkOffering.getId())) { diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java index 7eff324a738..16d28b64aec 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java @@ -22,34 +22,12 @@ package com.cloud.util; import com.cloud.dc.Vlan; import com.cloud.dc.VlanDetailsVO; import com.cloud.dc.dao.VlanDetailsDao; -import com.cloud.network.Network; -import com.cloud.network.dao.NetworkDetailVO; -import com.cloud.network.dao.NetworkDetailsDao; import com.cloud.network.manager.NuageVspManager; -import com.cloud.offering.NetworkOffering; import com.cloud.utils.StringUtils; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.commons.codec.binary.Base64; public class NuageVspUtil { - public static String getPreConfiguredDomainTemplateName(ConfigurationDao configDao, NetworkDetailsDao networkDetailsDao, Network network, NetworkOffering networkOffering) { - NetworkDetailVO domainTemplateNetworkDetail = networkDetailsDao.findDetail(network.getId(), NuageVspManager.nuageDomainTemplateDetailName); - if (domainTemplateNetworkDetail != null) { - return domainTemplateNetworkDetail.getValue(); - } - - String configKey; - if (network.getVpcId() != null) { - configKey = NuageVspManager.NuageVspVpcDomainTemplateName.key(); - } else if (networkOffering.getGuestType() == Network.GuestType.Shared) { - configKey = NuageVspManager.NuageVspSharedNetworkDomainTemplateName.key(); - } else { - configKey = NuageVspManager.NuageVspIsolatedNetworkDomainTemplateName.key(); - } - return configDao.getValue(configKey); - } - public static String encodePassword(String originalPassword) { byte[] passwordBytes = originalPassword.getBytes(StringUtils.getPreferredCharset()); byte[] encodedPasswordBytes = Base64.encodeBase64(passwordBytes); diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java index 643a66f8122..f5a0f400e41 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java @@ -31,7 +31,11 @@ import net.nuage.vsp.acs.client.api.model.VspNic; import net.nuage.vsp.acs.client.api.model.VspStaticNat; import net.nuage.vsp.acs.client.api.model.VspVm; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.junit.Before; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -65,18 +69,24 @@ public class NuageTest { protected static final long NETWORK_ID = 42L; @Mock protected NetworkModel _networkModel; - @Mock protected ConfigurationDao _configurationDao; + @Mock protected ConfigurationDao _configDao; @Mock protected NuageVspEntityBuilder _nuageVspEntityBuilder; + @InjectMocks + ConfigDepotImpl configDepot = new ConfigDepotImpl(); + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); // Standard responses when(_networkModel.isProviderForNetwork(Network.Provider.NuageVsp, NETWORK_ID)).thenReturn(true); - when(_configurationDao.getValue(NuageVspIsolatedNetworkDomainTemplateName.key())).thenReturn("IsolatedDomainTemplate"); - when(_configurationDao.getValue(NuageVspVpcDomainTemplateName.key())).thenReturn("VpcDomainTemplate"); - when(_configurationDao.getValue(NuageVspSharedNetworkDomainTemplateName.key())).thenReturn("SharedDomainTemplate"); + + mockConfigValue(NuageVspIsolatedNetworkDomainTemplateName, "IsolatedDomainTemplate"); + mockConfigValue(NuageVspVpcDomainTemplateName, "VpcDomainTemplate"); + mockConfigValue(NuageVspSharedNetworkDomainTemplateName, "SharedDomainTemplate"); + + ConfigKey.init(configDepot); when(_nuageVspEntityBuilder.buildVspDomain(any(Domain.class))).thenReturn(buildVspDomain()); when(_nuageVspEntityBuilder.buildVspNetwork(any(Network.class))).thenReturn(buildVspNetwork()); @@ -89,6 +99,13 @@ public class NuageTest { when(_nuageVspEntityBuilder.buildVspAclRule(any(NetworkACLItem.class))).thenReturn(buildVspAclRule()); } + protected void mockConfigValue(ConfigKey configKey, T value) { + ConfigurationVO vo = new ConfigurationVO("test", configKey); + vo.setValue(value.toString()); + when(_configDao.getValue(configKey.key())).thenReturn(value.toString()); + when(_configDao.findById(configKey.key())).thenReturn(vo); + } + protected VspDomain buildVspDomain() { return new VspDomain.Builder() .uuid("domainUuid") diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java index e92f4a7b9e2..d8bdd4bda18 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java @@ -83,9 +83,6 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; -import static com.cloud.network.manager.NuageVspManager.NuageVspIsolatedNetworkDomainTemplateName; -import static com.cloud.network.manager.NuageVspManager.NuageVspSharedNetworkDomainTemplateName; -import static com.cloud.network.manager.NuageVspManager.NuageVspVpcDomainTemplateName; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @@ -133,10 +130,6 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(_dataCenterDao.findById((Long)any())).thenReturn(dc); - when(_configurationDao.getValue(NuageVspIsolatedNetworkDomainTemplateName.key())).thenReturn("IsolatedDomainTemplate"); - when(_configurationDao.getValue(NuageVspVpcDomainTemplateName.key())).thenReturn("VpcDomainTemplate"); - when(_configurationDao.getValue(NuageVspSharedNetworkDomainTemplateName.key())).thenReturn("SharedDomainTemplate"); - when(_physicalNetworkDao.findById(any(Long.class))).thenReturn(physnet); when(physnet.getIsolationMethods()).thenReturn(Arrays.asList("VSP")); when(physnet.getId()).thenReturn(NETWORK_ID); diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java index ec16a974d08..680a13e9647 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java @@ -19,6 +19,25 @@ package com.cloud.network.manager; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; + +import javax.naming.ConfigurationException; + +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; +import org.apache.cloudstack.resourcedetail.VpcDetailVO; +import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; + import com.cloud.NuageTest; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Command; @@ -30,6 +49,8 @@ import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDetailsDao; import com.cloud.network.NuageVspDeviceVO; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkDetailVO; +import com.cloud.network.dao.NetworkDetailsDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NuageVspDao; import com.cloud.network.dao.PhysicalNetworkDao; @@ -37,52 +58,69 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.resource.ResourceManager; import com.cloud.util.NuageVspEntityBuilder; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.framework.config.impl.ConfigurationVO; -import org.junit.Before; -import org.junit.Test; - -import javax.naming.ConfigurationException; -import java.util.ArrayList; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class NuageVspManagerTest extends NuageTest { private static final long NETWORK_ID = 42L; + private static final long VPC_ID = 1L; + private static final long VPC_ID2 = 2L; - private PhysicalNetworkDao _physicalNetworkDao = mock(PhysicalNetworkDao.class); - private PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao = mock(PhysicalNetworkServiceProviderDao.class); - private ResourceManager _resourceManager = mock(ResourceManager.class); - private HostDetailsDao _hostDetailsDao = mock(HostDetailsDao.class); - private NuageVspDao _nuageVspDao = mock(NuageVspDao.class); - private NetworkDao _networkDao = mock(NetworkDao.class); - private HostDao _hostDao = mock(HostDao.class); - private AgentManager _agentManager = mock(AgentManager.class); - private ConfigurationDao _configurationDao = mock(ConfigurationDao.class); - private NuageVspEntityBuilder _nuageVspEntityBuilder = mock(NuageVspEntityBuilder.class); - private NuageVspManagerImpl _nuageVspManager; + @Mock private PhysicalNetworkDao _physicalNetworkDao ; + @Mock private PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; + @Mock private ResourceManager _resourceManager; + @Mock private HostDetailsDao _hostDetailsDao; + @Mock private NuageVspDao _nuageVspDao; + @Mock private NetworkDao _networkDao; + @Mock private HostDao _hostDao; + @Mock private AgentManager _agentManager; + @Mock private NuageVspEntityBuilder _nuageVspEntityBuilder; + @Mock private NetworkDetailsDao _networkDetailsDao; + @Mock private VpcDetailsDao _vpcDetailsDao; - @Before - public void setUp() throws Exception { - super.setUp(); + @InjectMocks + private NuageVspManagerImpl _nuageVspManager = new NuageVspManagerImpl(); - _nuageVspManager = new NuageVspManagerImpl(); + private NetworkVO setUpMockedNetwork(Long vpcId, String domainTemplateName) { + NetworkVO networkToMock = mock(NetworkVO.class); + when(networkToMock.getId()).thenReturn(NETWORK_ID); - _nuageVspManager._physicalNetworkServiceProviderDao = _physicalNetworkServiceProviderDao; - _nuageVspManager._physicalNetworkDao = _physicalNetworkDao; - _nuageVspManager._resourceMgr = _resourceManager; - _nuageVspManager._hostDetailsDao = _hostDetailsDao; - _nuageVspManager._nuageVspDao = _nuageVspDao; - _nuageVspManager._networkDao = _networkDao; - _nuageVspManager._hostDao = _hostDao; - _nuageVspManager._agentMgr = _agentManager; - _nuageVspManager._configDao = _configurationDao; - _nuageVspManager._nuageVspEntityBuilder = _nuageVspEntityBuilder; + reset(_vpcDetailsDao, _networkDetailsDao); + + when(networkToMock.getVpcId()).thenReturn(vpcId); + + if (domainTemplateName != null) { + if (vpcId != null) { + VpcDetailVO detail = new VpcDetailVO(vpcId, NuageVspManager.nuageDomainTemplateDetailName, domainTemplateName, false); + when(_vpcDetailsDao.findDetail(vpcId, NuageVspManager.nuageDomainTemplateDetailName)).thenReturn(detail); + } else { + NetworkDetailVO detail = new NetworkDetailVO(NETWORK_ID, NuageVspManager.nuageDomainTemplateDetailName, domainTemplateName, false); + when(_networkDetailsDao.findDetail(NETWORK_ID, NuageVspManager.nuageDomainTemplateDetailName)).thenReturn(detail); + } + } + + return networkToMock; } + @Test + public void testNuagePreConfiguredDomainTemplates() { + NetworkVO _mockedL2Network = setUpMockedNetwork(VPC_ID, "VpcDomainTemplate2"); + String checkDomainTemplate =_nuageVspManager.getPreConfiguredDomainTemplateName(_mockedL2Network); + assertEquals("VpcDomainTemplate2", checkDomainTemplate); + + _mockedL2Network = setUpMockedNetwork(VPC_ID2, null); + checkDomainTemplate =_nuageVspManager.getPreConfiguredDomainTemplateName(_mockedL2Network); + assertEquals("VpcDomainTemplate", checkDomainTemplate); + + _mockedL2Network = setUpMockedNetwork(null, "IsolatedDomainTemplate2"); + checkDomainTemplate =_nuageVspManager.getPreConfiguredDomainTemplateName(_mockedL2Network); + assertEquals("IsolatedDomainTemplate2", checkDomainTemplate); + + _mockedL2Network = setUpMockedNetwork(null, null); + checkDomainTemplate =_nuageVspManager.getPreConfiguredDomainTemplateName(_mockedL2Network); + assertEquals("IsolatedDomainTemplate", checkDomainTemplate); + + } + + @Test public void testDeleteNuageVspDevice() throws ConfigurationException { @@ -107,7 +145,7 @@ public class NuageVspManagerTest extends NuageTest { ConfigurationVO cmsIdConfig = mock(ConfigurationVO.class); when(cmsIdConfig.getValue()).thenReturn("1:1"); - when(_configurationDao.findByName("nuagevsp.cms.id")).thenReturn(cmsIdConfig); + when(_configDao.findByName("nuagevsp.cms.id")).thenReturn(cmsIdConfig); final SyncNuageVspCmsIdAnswer answer = mock(SyncNuageVspCmsIdAnswer.class); when(answer.getResult()).thenReturn(true); diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java index 0ac13becaac..52d8f73f871 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java @@ -19,6 +19,14 @@ package com.cloud.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import net.nuage.vsp.acs.client.api.model.Protocol; import net.nuage.vsp.acs.client.api.model.VspAclRule; import net.nuage.vsp.acs.client.api.model.VspDomain; @@ -27,12 +35,15 @@ import net.nuage.vsp.acs.client.api.model.VspNic; import net.nuage.vsp.acs.client.api.model.VspStaticNat; import net.nuage.vsp.acs.client.api.model.VspVm; -import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; import org.junit.Before; import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; import com.google.common.collect.Lists; +import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; + import com.cloud.NuageTest; import com.cloud.dc.VlanDetailsVO; import com.cloud.dc.VlanVO; @@ -47,6 +58,7 @@ import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDetailsDao; import com.cloud.network.dao.NetworkVO; +import com.cloud.network.manager.NuageVspManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpc.NetworkACLItem; import com.cloud.network.vpc.VpcVO; @@ -61,14 +73,8 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicSecondaryIpDao; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class NuageVspEntityBuilderTest extends NuageTest { @@ -83,18 +89,23 @@ public class NuageVspEntityBuilderTest extends NuageTest { private static final long VLAN_ID = 5L; public static final String VM_IP = "192.168.0.24"; - private VpcDao _vpcDao = mock(VpcDao.class); - private VpcDetailsDao _vpcDetailsDao = mock(VpcDetailsDao.class); - private DomainDao _domainDao = mock(DomainDao.class); - private AccountDao _accountDao = mock(AccountDao.class); - private NetworkDao _networkDao = mock(NetworkDao.class); - private NetworkOfferingDao _networkOfferingDao = mock(NetworkOfferingDao.class); - private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao = mock(NetworkOfferingServiceMapDao.class); - private VlanDao _vlanDao = mock(VlanDao.class); - private VlanDetailsDao _vlanDetailsDao = mock(VlanDetailsDao.class); - private IPAddressDao _ipAddressDao = mock(IPAddressDao.class); - private NetworkDetailsDao _networkDetailsDao = mock(NetworkDetailsDao.class); - private NicDao _nicDao = mock(NicDao.class); + @Mock private AccountDao _accountDao; + @Mock private DomainDao _domainDao; + @Mock private IPAddressDao _ipAddressDao; + @Mock private NetworkDao _networkDao; + @Mock private NetworkDetailsDao _networkDetailsDao; + @Mock private NetworkOfferingDao _networkOfferingDao; + @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao; + @Mock private NicSecondaryIpDao _nicSecondaryIpDao; + @Mock private NicDao _nicDao; + @Mock private VlanDao _vlanDao; + @Mock private VlanDetailsDao _vlanDetailsDao; + @Mock private VpcDao _vpcDao; + @Mock private VpcDetailsDao _vpcDetailsDao; + + @Mock private NuageVspManager _nuageVspManager; + + @InjectMocks private NuageVspEntityBuilder _nuageVspEntityBuilder = new NuageVspEntityBuilder(); private DomainVO _mockedDomain = mock(DomainVO.class); @@ -122,21 +133,6 @@ public class NuageVspEntityBuilderTest extends NuageTest { public void setUp() throws Exception { super.setUp(); - _nuageVspEntityBuilder._vpcDao = _vpcDao; - _nuageVspEntityBuilder._vpcDetailsDao = _vpcDetailsDao; - _nuageVspEntityBuilder._domainDao = _domainDao; - _nuageVspEntityBuilder._accountDao = _accountDao; - _nuageVspEntityBuilder._networkDao = _networkDao; - _nuageVspEntityBuilder._networkOfferingDao = _networkOfferingDao; - _nuageVspEntityBuilder._networkOfferingServiceMapDao = _networkOfferingServiceMapDao; - _nuageVspEntityBuilder._vlanDao = _vlanDao; - _nuageVspEntityBuilder._vlanDetailsDao = _vlanDetailsDao; - _nuageVspEntityBuilder._configurationDao = _configurationDao; - _nuageVspEntityBuilder._ipAddressDao = _ipAddressDao; - _nuageVspEntityBuilder._networkModel = _networkModel; - _nuageVspEntityBuilder._networkDetailsDao = _networkDetailsDao; - _nuageVspEntityBuilder._nicDao = _nicDao; - setUpMockedDomain(); setUpMockedAccount(); setUpMockedNetworkOffering(_mockedNetworkOffering, Network.GuestType.Isolated); @@ -169,28 +165,28 @@ public class NuageVspEntityBuilderTest extends NuageTest { @Test public void testBuildVspNetwork() { VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network); - validateVspNetwork(vspNetwork, true, false, false, false, "IsolatedDomainTemplate"); + validateVspNetwork(vspNetwork, true, false, false, false); vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network); - validateVspNetwork(vspNetwork, true, false, false, false, "IsolatedDomainTemplate"); + validateVspNetwork(vspNetwork, true, false, false, false); vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork); - validateVspNetwork(vspNetwork, false, true, false, false, "IsolatedDomainTemplate"); + validateVspNetwork(vspNetwork, false, true, false, false); vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork); - validateVspNetwork(vspNetwork, false, true, false, false, "IsolatedDomainTemplate"); + validateVspNetwork(vspNetwork, false, true, false, false); vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork); - validateVspNetwork(vspNetwork, false, false, true, false, "VpcDomainTemplate"); + validateVspNetwork(vspNetwork, false, false, true, false); vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork); - validateVspNetwork(vspNetwork, false, false, true, false, "VpcDomainTemplate"); + validateVspNetwork(vspNetwork, false, false, true, false); vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork); - validateVspNetwork(vspNetwork, false, false, false, true, "SharedDomainTemplate"); + validateVspNetwork(vspNetwork, false, false, false, true); vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork); - validateVspNetwork(vspNetwork, false, false, false, true, "SharedDomainTemplate"); + validateVspNetwork(vspNetwork, false, false, false, true); } @Test @@ -235,8 +231,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { assertEquals("domainPath", vspDomain.getPath()); } - private void validateVspNetwork(VspNetwork vspNetwork, boolean isL2, boolean isL3, boolean isVpc, boolean isShared, - String domainTemplateName) { + private void validateVspNetwork(VspNetwork vspNetwork, boolean isL2, boolean isL3, boolean isVpc, boolean isShared) { assertEquals(NETWORK_ID, vspNetwork.getId()); assertEquals("networkUuid", vspNetwork.getUuid()); assertEquals("networkName", vspNetwork.getName()); @@ -260,7 +255,6 @@ public class NuageVspEntityBuilderTest extends NuageTest { assertEquals(isShared, vspNetwork.isShared()); assertEquals(true, vspNetwork.isFirewallServiceSupported()); assertEquals(true, vspNetwork.isEgressDefaultPolicy()); - assertEquals(domainTemplateName, vspNetwork.getDomainTemplateName()); assertEquals("10.10.10.0/24", vspNetwork.getCidr()); assertEquals("10.10.10.1", vspNetwork.getGateway()); } diff --git a/pom.xml b/pom.xml index 4ec4d111a6f..8c3c6997d76 100644 --- a/pom.xml +++ b/pom.xml @@ -1,23 +1,21 @@ + ~ 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. + --> 4.0.0 diff --git a/test/integration/plugins/nuagevsp/nuageTestCase.py b/test/integration/plugins/nuagevsp/nuageTestCase.py index e9edaac18e1..9ab4726d95f 100644 --- a/test/integration/plugins/nuagevsp/nuageTestCase.py +++ b/test/integration/plugins/nuagevsp/nuageTestCase.py @@ -905,7 +905,8 @@ class nuageTestCase(cloudstackTestCase): # verify_vsd_network - Verifies the given CloudStack domain and network/VPC # against the corresponding installed enterprise, domain, zone, and subnet # in VSD - def verify_vsd_network(self, domain_id, network, vpc=None): + def verify_vsd_network(self, domain_id, network, vpc=None, + domain_template_name=None): self.debug("Verifying the creation and state of Network - %s in VSD" % network.name) vsd_enterprise = self.vsd.get_enterprise( @@ -920,6 +921,18 @@ class nuageTestCase(cloudstackTestCase): "VSD enterprise name should match CloudStack domain " "uuid" ) + if domain_template_name: + vsd_domain_template = self.vsd.get_domain_template( + enterprise=vsd_enterprise, + filter=self.vsd.set_name_filter(domain_template_name)) + else: + vsd_domain_template = self.vsd.get_domain_template( + enterprise=vsd_enterprise, + filter=ext_network_filter) + self.assertEqual(vsd_domain.template_id, vsd_domain_template.id, + "VSD domain should be instantiated from appropriate " + "domain template" + ) if vpc: self.assertEqual(vsd_domain.description, "VPC_" + vpc.name, "VSD domain description should match VPC name in " diff --git a/test/integration/plugins/nuagevsp/test_nuage_vsp_domain_template.py b/test/integration/plugins/nuagevsp/test_nuage_vsp_domain_template.py new file mode 100644 index 00000000000..040f379fb6e --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_vsp_domain_template.py @@ -0,0 +1,831 @@ +# 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. + +""" Component tests for Nuage VSP SDN plugin's Domain Template feature +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.base import (Account, + Configurations, + Domain, + Network, + User, + VirtualMachine) +from marvin.cloudstackAPI import (associateNuageVspDomainTemplate, + listNuageVspDomainTemplates, + listNuageVspGlobalDomainTemplate) +# Import System Modules +from nose.plugins.attrib import attr + + +class TestNuageDomainTemplate(nuageTestCase): + """Test Nuage VSP SDN plugin's Domain Template feature + """ + + @classmethod + def setUpClass(cls): + """ + Create the following domain tree and accounts that are required for + executing Nuage VSP SDN plugin's Domain Template feature test cases: + Under ROOT - Create a domain D1 + Under domain D1 - Create a subdomain D11 + Under each of the domains - create an admin user and a regular + user account. + Create Nuage VSP VPC and network (tier) offerings + Create a VPC with a VPC network (tier) under each of the admin accounts + of the above domains + Create three pre-configured Nuage VSP domain templates per enterprise + in VSD corresponding to each of the above domains + """ + + super(TestNuageDomainTemplate, cls).setUpClass() + cls.domains_accounts_data = cls.test_data["acl"] + + try: + # Backup default (ROOT admin user) apikey and secretkey + cls.default_apikey = cls.api_client.connection.apiKey + cls.default_secretkey = cls.api_client.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.api_client, + cls.domains_accounts_data["domain1"] + ) + cls._cleanup.append(cls.domain_1) + + cls.domain_11 = Domain.create( + cls.api_client, + cls.domains_accounts_data["domain11"], + parentdomainid=cls.domain_1.id + ) + cls._cleanup.append(cls.domain_11) + + # Create an admin and an user account under ROOT domain + cls.account_root = Account.create( + cls.api_client, + cls.domains_accounts_data["accountROOT"], + admin=True, + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + cls._cleanup.append(cls.account_root) + + cls.account_roota = Account.create( + cls.api_client, + cls.domains_accounts_data["accountROOTA"], + admin=False, + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + cls._cleanup.append(cls.account_roota) + + # Create an admin and an user account under domain D1 + cls.account_d1 = Account.create( + cls.api_client, + cls.domains_accounts_data["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + cls._cleanup.append(cls.account_d1) + + cls.account_d1a = Account.create( + cls.api_client, + cls.domains_accounts_data["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + cls._cleanup.append(cls.account_d1a) + + # Create an admin and an user account under subdomain D11 + cls.account_d11 = Account.create( + cls.api_client, + cls.domains_accounts_data["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + cls._cleanup.append(cls.account_d11) + + cls.account_d11a = Account.create( + cls.api_client, + cls.domains_accounts_data["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + cls._cleanup.append(cls.account_d11a) + + # Create VPC offering + cls.vpc_offering = cls.create_VpcOffering( + cls.test_data["nuagevsp"]["vpc_offering"]) + + # Create VPC network (tier) offering + cls.network_offering = cls.create_NetworkOffering( + cls.test_data["nuagevsp"]["vpc_network_offering"]) + + # Create a VPC with a VPC network (tier) under each of the admin + # accounts of ROOT domain, domain D1, and subdomain D11 + # Create 500 pre-configured Nuage VSP domain templates per + # enterprise in VSD corresponding to each of the above domains + cls.cleanup_domain_templates = [] + cls.domain_template_list = [] + for i in range(0, 3): + cls.domain_template_list.append("domain_template_" + str(i)) + for account in [cls.account_root, cls.account_d1, cls.account_d11]: + vpc = cls.create_Vpc( + cls.vpc_offering, cidr='10.1.0.0/16', account=account) + cls.create_Network( + cls.network_offering, + vpc=vpc, + account=account) + for domain_template in cls.domain_template_list: + new_domain_template = cls.vsdk.NUDomainTemplate( + name=domain_template, + description=domain_template) + enterprise = cls._session.user.enterprises.get_first( + filter="externalID BEGINSWITH '%s'" % account.domainid) + enterprise.create_child(new_domain_template) + cls.cleanup_domain_templates.append( + enterprise.domain_templates.get_first( + filter="name is '%s'" % domain_template)) + except Exception as e: + cls.tearDownClass() + raise Exception("Failed to create the setup required to execute " + "the test cases: %s" % e) + return + + @classmethod + def tearDownClass(cls): + # Restore back default (ROOT admin user) apikey and secretkey + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + # Cleanup resources used + cls.debug("Cleaning up the resources") + for domain_template in cls.cleanup_domain_templates: + try: + domain_template.delete() + except Exception as e: + cls.error("Failed to cleanup domain template %s in VSD, got " + "%s" % (domain_template, e)) + cls.cleanup_domain_templates = [] + for obj in reversed(cls._cleanup): + try: + if isinstance(obj, VirtualMachine): + obj.delete(cls.api_client, expunge=True) + else: + obj.delete(cls.api_client) + except Exception as e: + cls.error("Failed to cleanup %s, got %s" % (obj, e)) + try: + cls.vpc_offering.delete(cls.api_client) + cls.network_offering.delete(cls.api_client) + cls.service_offering.delete(cls.api_client) + except Exception as e: + cls.error("Failed to cleanup offerings - %s" % e) + # cleanup_resources(cls.api_client, cls._cleanup) + cls._cleanup = [] + cls.debug("Cleanup complete!") + return + + def setUp(self): + self.account = self.account_root + self.cleanup = [] + return + + def tearDown(self): + # Restore back default (ROOT admin user) apikey and secretkey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + # Cleanup resources used + self.debug("Cleaning up the resources") + for obj in reversed(self.cleanup): + try: + if isinstance(obj, VirtualMachine): + obj.delete(self.api_client, expunge=True) + else: + obj.delete(self.api_client) + except Exception as e: + self.error("Failed to cleanup %s, got %s" % (obj, e)) + # cleanup_resources(self.api_client, self.cleanup) + self.cleanup = [] + self.debug("Cleanup complete!") + return + + @staticmethod + def generateKeysForUser(api_client, account): + user = User.list( + api_client, + account=account.name, + domainid=account.domainid + )[0] + + return (User.registerUserKeys( + api_client, + user.id + )) + + # list_NuageVspDomainTemplates - Lists pre-configured Nuage VSP domain + # template(s) for the given domain/account user + def list_NuageVspDomainTemplates(self, account=None, name=None): + if not account: + account = self.account + cmd = listNuageVspDomainTemplates.listNuageVspDomainTemplatesCmd() + cmd.domainid = account.domainid + cmd.zoneid = self.zone.id + domain_templates = self.api_client.listNuageVspDomainTemplates(cmd) + if name: + return [domain_template for domain_template in domain_templates + if str(domain_template.name) == name] + else: + return domain_templates + + # validate_NuageVspDomainTemplate - Validates the given pre-configured + # Nuage VSP domain template for the given domain/account user + def validate_NuageVspDomainTemplate(self, name, account=None): + """Validates the pre-configured Nuage VSP domain template""" + if not account: + account = self.account + self.debug("Validating the availability of pre-configured Nuage VSP " + "domain template - %s for domain/account user - %s " + % (name, account)) + domain_templates = self.list_NuageVspDomainTemplates( + name=name, account=account) + self.assertEqual(isinstance(domain_templates, list), True, + "List Nuage VSP Domain Templates should return a " + "valid list" + ) + self.assertEqual(domain_templates[0].name, name, + "Name of the Nuage VSP Domain Template should " + "be in the returned list" + ) + self.debug("Successfully validated the availability of pre-configured " + "Nuage VSP domain template - %s for domain/account user - " + "%s" % (name, account)) + + # associate_NuageVspDomainTemplate - Associates the given pre-configured + # Nuage VSP domain template to the given VPC + def associate_NuageVspDomainTemplate(self, domain_template_name, vpc): + cmd = associateNuageVspDomainTemplate.\ + associateNuageVspDomainTemplateCmd() + cmd.domaintemplate = domain_template_name + cmd.vpcid = vpc.id + cmd.zoneid = self.zone.id + return self.api_client.associateNuageVspDomainTemplate(cmd) + + # update_NuageVspGlobalDomainTemplate - Updates the global setting + # nuagevsp.vpc.domaintemplate.name with the given value + def update_NuageVspGlobalDomainTemplate(self, value): + self.debug("Updating global setting nuagevsp.vpc.domaintemplate.name " + "with value - %s" % value) + self.user_apikey = self.api_client.connection.apiKey + self.user_secretkey = self.api_client.connection.securityKey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + Configurations.update(self.api_client, + name="nuagevsp.vpc.domaintemplate.name", + value=value) + self.api_client.connection.apiKey = self.user_apikey + self.api_client.connection.securityKey = self.user_secretkey + self.debug("Successfully updated global setting " + "nuagevsp.vpc.domaintemplate.name with value - %s" % value) + + # list_NuageVspGlobalDomainTemplate - Lists the name of the global/default + # pre-configured Nuage VSP domain template as mentioned in the global + # setting "nuagevsp.vpc.domaintemplate.name" + def list_NuageVspGlobalDomainTemplate(self): + cmd = listNuageVspGlobalDomainTemplate.\ + listNuageVspGlobalDomainTemplateCmd() + return self.api_client.listNuageVspGlobalDomainTemplate(cmd) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_01_nuage_Domain_Template_selection_per_VPC(self): + """Test Nuage VSP Domain Template selection per VPC + """ + + # 1. Associate an invalid/non-existing Nuage VSP domain template to a + # VPC; verify that the association fails. + # 2. Associate a valid/existing pre-configured Nuage VSP domain + # template to a VPC; verify that the association is successful, VPC + # networks (domains) are instantiated from the associated domain + # template in VSD. + # 3. Verify that the state of such VPC networks (domains) in VSD is not + # affected with their restarts in CloudStack with and without + # cleanup. + # 4. Verify that multiple associations (update) of domain templates to + # a VPC goes through till the creation of its first VPC network + # (tier). + # 5. Verify that the VPC networks (domains) creation fails in VSD when + # the associated domain templates to their corresponding VPCs have + # been deleted in VSD. + # 6. Verify that the VPC networks (domains) creation fails in VSD when + # an acl list is associated with them after their corresponding VPCs + # have been associated with a pre-configured Nuage VSP domain + # template. + # 7. Delete all the created objects (cleanup). + + # Creating VPC + vpc_1 = self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + + # Associating pre-configured Nuage VSP Domain Template to VPC + with self.assertRaises(Exception): + self.validate_NuageVspDomainTemplate("invalid_domain_template") + self.debug("There is no domain template with name " + "invalid_domain_template in VSD") + with self.assertRaises(Exception): + self.associate_NuageVspDomainTemplate( + "invalid_domain_template", vpc_1) + self.debug("Association fails as there is no domain template with " + "name invalid_domain_template in VSD") + self.associate_NuageVspDomainTemplate( + self.domain_template_list[0], vpc_1) + + # Creating VPC networks (tiers) + vpc_1_tier_1 = self.create_Network( + self.network_offering, gateway='10.1.3.1', vpc=vpc_1) + vpc_1_tier_2 = self.create_Network( + self.network_offering, gateway='10.1.4.1', vpc=vpc_1) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_1, vpc_1, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_2, vpc_1, + domain_template_name=self.domain_template_list[0]) + + # Restart VPC networks (tiers) without cleanup + Network.restart(vpc_1_tier_1, self.api_client, cleanup=False) + Network.restart(vpc_1_tier_2, self.api_client, cleanup=False) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_1, vpc_1, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_2, vpc_1, + domain_template_name=self.domain_template_list[0]) + + # Restart VPC networks (tiers) with cleanup + Network.restart(vpc_1_tier_1, self.api_client, cleanup=True) + Network.restart(vpc_1_tier_2, self.api_client, cleanup=True) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_1, vpc_1, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_2, vpc_1, + domain_template_name=self.domain_template_list[0]) + + # Restart VPC without cleanup + self.restart_Vpc(vpc_1, cleanup=False) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_1, vpc_1, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_2, vpc_1, + domain_template_name=self.domain_template_list[0]) + + # Restart VPC with cleanup + self.restart_Vpc(vpc_1, cleanup=True) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_1, vpc_1, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_2, vpc_1, + domain_template_name=self.domain_template_list[0]) + + # Creating VPC + vpc_2 = self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + + # Associating pre-configured Nuage VSP Domain Template to VPC + self.validate_NuageVspDomainTemplate(self.domain_template_list[0]) + self.associate_NuageVspDomainTemplate( + self.domain_template_list[0], vpc_2) + self.validate_NuageVspDomainTemplate(self.domain_template_list[1]) + self.associate_NuageVspDomainTemplate( + self.domain_template_list[1], vpc_2) + + # Deleting the associated pre-configured Nuage VSP domain template + enterprise = self._session.user.enterprises.get_first( + filter="externalID BEGINSWITH '%s'" % self.account.domainid) + domain_template = enterprise.domain_templates.get_first( + filter="name is '%s'" % self.domain_template_list[1]) + domain_template.delete() + + # Creating VPC networks (tiers) + with self.assertRaises(Exception): + self.create_Network( + self.network_offering, + gateway='10.1.1.1', + vpc=vpc_2) + self.debug("Corresponding domain creation in VSD fails, but VPC " + "(tier) network gets created on CloudStack as the " + "associated pre-configured Nuage VSP domain template is no " + "longer existing in VSD") + + # Re-creating the associated pre-configured Nuage VSP domain template + new_domain_template = self.vsdk.NUDomainTemplate( + name=self.domain_template_list[1], + description=self.domain_template_list[1]) + enterprise = self._session.user.enterprises.get_first( + filter="externalID BEGINSWITH '%s'" % self.account.domainid) + enterprise.create_child(new_domain_template) + self.cleanup_domain_templates.append( + enterprise.domain_templates.get_first( + filter="name is '%s'" % self.domain_template_list[1])) + + vpc_2_tier_1 = self.create_Network( + self.network_offering, gateway='10.1.2.1', vpc=vpc_2) + vpc_2_tier_2 = self.create_Network( + self.network_offering, gateway='10.1.3.1', vpc=vpc_2) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_2_tier_1, vpc_2, + domain_template_name=self.domain_template_list[1]) + self.verify_vsd_network( + self.account.domainid, vpc_2_tier_2, vpc_2, + domain_template_name=self.domain_template_list[1]) + + # Creating VPC + vpc_3 = self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + + # Associating pre-configured Nuage VSP Domain Template to VPC + self.validate_NuageVspDomainTemplate(self.domain_template_list[0]) + self.associate_NuageVspDomainTemplate( + self.domain_template_list[0], vpc_3) + + # Creating an ACL list and an ACL item + acl_list = self.create_NetworkAclList( + name="acl", description="acl", vpc=vpc_3) + self.create_NetworkAclRule( + self.test_data["ingress_rule"], acl_list=acl_list) + + # Creating VPC networks (tiers) + with self.assertRaises(Exception): + self.create_Network( + self.network_offering, + gateway='10.1.1.1', + vpc=vpc_3, + acl_list=acl_list) + self.debug("Corresponding domain creation in VSD fails, but VPC " + "(tier) network gets created on CloudStack as creation of " + "Network ACLs from CloudStack is not supported when the " + "VPC is associated with a Nuage VSP pre-configured domain " + "template") + + vpc_3_tier_1 = self.create_Network( + self.network_offering, gateway='10.1.2.1', vpc=vpc_3) + vpc_3_tier_2 = self.create_Network( + self.network_offering, gateway='10.1.3.1', vpc=vpc_3) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_3_tier_1, vpc_3, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_3_tier_2, vpc_3, + domain_template_name=self.domain_template_list[0]) + + # Creating VPC and VPC network (tier) + vpc = self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + vpc_tier = self.create_Network(self.network_offering, vpc=vpc) + + # VSD verification + self.verify_vsd_network(self.account.domainid, vpc_tier, vpc) + + # Associating pre-configured Nuage VSP Domain Template to VPC + self.validate_NuageVspDomainTemplate(self.domain_template_list[0]) + with self.assertRaises(Exception): + self.associate_NuageVspDomainTemplate( + self.domain_template_list[0], vpc) + self.debug("Association fails as the corresponding domain and domain " + "templates are already created in VSD for the VPC vpc") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_02_nuage_Domain_Template_selection_per_VPC_as_ROOT_user(self): + """Test Nuage VSP Domain Template selection per VPC as ROOT domain + regular user + """ + + # Repeat the tests in the testcase + # "test_01_nuage_Domain_Template_selection_per_VPC" as ROOT domain + # regular user + + # Setting ROOT domain user account information + self.account = self.account_roota + + # Setting ROOT domain user keys in api_client + self.api_client.connection.apiKey = self.user_roota_apikey + self.api_client.connection.securityKey = self.user_roota_secretkey + + # Calling testcase "test_01_nuage_Domain_Template_selection_per_VPC" + self.test_01_nuage_Domain_Template_selection_per_VPC() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_03_nuage_Domain_Template_selection_per_VPC_as_domain_admin(self): + """Test Nuage VSP Domain Template selection per VPC as domain admin + user + """ + + # Repeat the tests in the testcase + # "test_01_nuage_Domain_Template_selection_per_VPC" as domain admin + # user + + # Setting domain D1 admin account information + self.account = self.account_d1 + + # Setting domain D1 admin keys in api_client + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + + # Calling testcase "test_01_nuage_Domain_Template_selection_per_VPC" + self.test_01_nuage_Domain_Template_selection_per_VPC() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_04_nuage_Domain_Template_selection_per_VPC_as_domain_user(self): + """Test Nuage VSP Domain Template selection per VPC as domain + regular user + """ + + # Repeat the tests in the testcase + # "test_01_nuage_Domain_Template_selection_per_VPC" as domain regular + # user + + # Setting domain D1 user account information + self.account = self.account_d1a + + # Setting domain D1 user keys in api_client + self.api_client.connection.apiKey = self.user_d1a_apikey + self.api_client.connection.securityKey = self.user_d1a_secretkey + + # Calling testcase "test_01_nuage_Domain_Template_selection_per_VPC" + self.test_01_nuage_Domain_Template_selection_per_VPC() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_05_nuage_Domain_Template_selection_per_VPC_as_subdom_admin(self): + """Test Nuage VSP Domain Template selection per VPC as subdomain admin + user + """ + + # Repeat the tests in the testcase + # "test_01_nuage_Domain_Template_selection_per_VPC" as subdomain admin + # user + + # Setting subdomain D11 admin account information + self.account = self.account_d11 + + # Setting subdomain D1 admin keys in api_client + self.api_client.connection.apiKey = self.user_d11_apikey + self.api_client.connection.securityKey = self.user_d11_secretkey + + # Calling testcase "test_01_nuage_Domain_Template_selection_per_VPC" + self.test_01_nuage_Domain_Template_selection_per_VPC() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_06_nuage_Domain_Template_selection_per_VPC_as_subdom_user(self): + """Test Nuage VSP Domain Template selection per VPC as subdomain + regular user + """ + + # Repeat the tests in the testcase + # "test_01_nuage_Domain_Template_selection_per_VPC" as subdomain + # regular user + + # Setting subdomain D11 user account information + self.account = self.account_d11a + + # Setting subdomain D11 user keys in api_client + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + + # Calling testcase "test_01_nuage_Domain_Template_selection_per_VPC" + self.test_01_nuage_Domain_Template_selection_per_VPC() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_07_nuage_Global_Domain_Template(self): + """Test Nuage VSP Global Domain Template + """ + + # 1. Update the global setting "nuagevsp.vpc.domaintemplate.name" with + # an invalid/non-existing Nuage VSP domain template name; verify + # that a new VPC creation fails, and gets cleaned up. + # 2. Update the global setting "nuagevsp.vpc.domaintemplate.name" with + # a valid/existing pre-configured Nuage VSP domain template name; + # verify that all VPC networks (domains) get instantiated from that + # pre-configured Nuage VSP domain template. + # 3. Verify that multiple associations (update) of domain templates to + # such VPCs goes through till the creation of their first VPC + # networks (tiers). + # 4. Delete all the created objects (cleanup). + + # Updating global setting "nuagevsp.vpc.domaintemplate.name" + self.update_NuageVspGlobalDomainTemplate( + value="invalid_domain_template") + domain_template = self.list_NuageVspGlobalDomainTemplate()[0].name + self.assertEqual(domain_template, "invalid_domain_template", + "Global setting nuagevsp.vpc.domaintemplate.name was " + "not updated successfully" + ) + with self.assertRaises(Exception): + self.validate_NuageVspDomainTemplate("invalid_domain_template") + self.debug("There is no domain template with name " + "invalid_domain_template in VSD") + + # Creating VPC + with self.assertRaises(Exception): + self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + self.debug("VPC creation fails as there is no domain template with " + "name invalid_domain_template in VSD as mentioned in " + "global setting nuagevsp.vpc.domaintemplate.name") + + # Updating global setting "nuagevsp.vpc.domaintemplate.name" + self.update_NuageVspGlobalDomainTemplate( + value=self.domain_template_list[0]) + domain_template = self.list_NuageVspGlobalDomainTemplate()[0].name + self.assertEqual(domain_template, self.domain_template_list[0], + "Global setting nuagevsp.vpc.domaintemplate.name was " + "not updated successfully" + ) + self.validate_NuageVspDomainTemplate(self.domain_template_list[0]) + + # Creating VPC and VPC networks (tiers) + vpc_1 = self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + vpc_1_tier_1 = self.create_Network( + self.network_offering, gateway='10.1.1.1', vpc=vpc_1) + vpc_1_tier_2 = self.create_Network( + self.network_offering, gateway='10.1.2.1', vpc=vpc_1) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_1, vpc_1, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_1_tier_2, vpc_1, + domain_template_name=self.domain_template_list[0]) + + # Creating VPC and VPC networks (tiers) + vpc_2 = self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + vpc_2_tier_1 = self.create_Network( + self.network_offering, gateway='10.1.1.1', vpc=vpc_2) + vpc_2_tier_2 = self.create_Network( + self.network_offering, gateway='10.1.2.1', vpc=vpc_2) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_2_tier_1, vpc_2, + domain_template_name=self.domain_template_list[0]) + self.verify_vsd_network( + self.account.domainid, vpc_2_tier_2, vpc_2, + domain_template_name=self.domain_template_list[0]) + + # Creating VPC + vpc_3 = self.create_Vpc(self.vpc_offering, cidr='10.1.0.0/16') + + # Associating pre-configured Nuage VSP Domain Template to VPC + self.validate_NuageVspDomainTemplate(self.domain_template_list[1]) + self.associate_NuageVspDomainTemplate( + self.domain_template_list[1], vpc_3) + + # Creating VPC networks (tiers) + vpc_3_tier_1 = self.create_Network( + self.network_offering, gateway='10.1.1.1', vpc=vpc_3) + vpc_3_tier_2 = self.create_Network( + self.network_offering, gateway='10.1.2.1', vpc=vpc_3) + + # VSD verification + self.verify_vsd_network( + self.account.domainid, vpc_3_tier_1, vpc_3, + domain_template_name=self.domain_template_list[1]) + self.verify_vsd_network( + self.account.domainid, vpc_3_tier_2, vpc_3, + domain_template_name=self.domain_template_list[1]) + + # Updating global setting "nuagevsp.vpc.domaintemplate.name" + self.update_NuageVspGlobalDomainTemplate(value="") + domain_template = self.list_NuageVspGlobalDomainTemplate()[0].name + self.assertEqual(domain_template, "", + "Global setting nuagevsp.vpc.domaintemplate.name was " + "not updated successfully" + ) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_08_nuage_Global_Domain_Template_as_ROOT_user(self): + """Test Nuage VSP Global Domain Template as ROOT domain regular user + """ + + # Repeat the tests in the testcase + # "test_07_nuage_Global_Domain_Template" as ROOT domain regular user + + # Setting ROOT domain user account information + self.account = self.account_roota + + # Setting ROOT domain user keys in api_client + self.api_client.connection.apiKey = self.user_roota_apikey + self.api_client.connection.securityKey = self.user_roota_secretkey + + # Calling testcase "test_07_nuage_Global_Domain_Template" + self.test_07_nuage_Global_Domain_Template() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_09_nuage_Global_Domain_Template_as_domain_admin(self): + """Test Nuage VSP Global Domain Template as domain admin user + """ + + # Repeat the tests in the testcase + # "test_07_nuage_Global_Domain_Template" as domain admin user + + # Setting domain D1 admin account information + self.account = self.account_d1 + + # Setting domain D1 admin keys in api_client + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + + # Calling testcase "test_07_nuage_Global_Domain_Template" + self.test_07_nuage_Global_Domain_Template() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_10_nuage_Global_Domain_Template_as_domain_user(self): + """Test Nuage VSP Global Domain Template as domain regular user + """ + + # Repeat the tests in the testcase + # "test_07_nuage_Global_Domain_Template" as domain regular user + + # Setting domain D1 user account information + self.account = self.account_d1a + + # Setting domain D1 user keys in api_client + self.api_client.connection.apiKey = self.user_d1a_apikey + self.api_client.connection.securityKey = self.user_d1a_secretkey + + # Calling testcase "test_07_nuage_Global_Domain_Template" + self.test_07_nuage_Global_Domain_Template() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_11_nuage_Global_Domain_Template_as_subdomain_admin(self): + """Test Nuage VSP Global Domain Template as subdomain admin user + """ + + # Repeat the tests in the testcase + # "test_07_nuage_Global_Domain_Template" as subdomain admin user + + # Setting subdomain D11 admin account information + self.account = self.account_d11 + + # Setting subdomain D1 admin keys in api_client + self.api_client.connection.apiKey = self.user_d11_apikey + self.api_client.connection.securityKey = self.user_d11_secretkey + + # Calling testcase "test_07_nuage_Global_Domain_Template" + self.test_07_nuage_Global_Domain_Template() + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_12_nuage_Global_Domain_Template_as_subdomain_user(self): + """Test Nuage VSP Global Domain Template as subdomain regular user + """ + + # Repeat the tests in the testcase + # "test_07_nuage_Global_Domain_Template" as subdomain regular user + + # Setting subdomain D11 user account information + self.account = self.account_d11a + + # Setting subdomain D11 user keys in api_client + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + + # Calling testcase "test_07_nuage_Global_Domain_Template" + self.test_07_nuage_Global_Domain_Template() diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index cffc5d4e4db..07450cf85e0 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -87,6 +87,8 @@ known_categories = { 'OpenDaylight': 'Network', 'createServiceInstance': 'Network', 'addGloboDnsHost': 'Network', + 'listnuagevspdomaintemplates': 'Network', + 'listnuagevspglobaldomaintemplate': 'Network', 'Vpn': 'VPN', 'Limit': 'Limit', 'ResourceCount': 'Limit', diff --git a/ui/l10n/en.js b/ui/l10n/en.js index 003c93f097d..3d0c42147c7 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -1194,6 +1194,8 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.none":"None", "label.not.found":"Not Found", "label.notifications":"Notifications", +"label.nuage.vpc.usedomaintemplate":"Use pre-configured Domain Template", +"label.nuage.vpc.domaintemplatelist":"Domain Template", "label.num.cpu.cores":"# of CPU Cores", "label.number.of.clusters":"Number of Clusters", "label.number.of.cpu.sockets":"The Number of CPU Sockets", diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 7ffb16dcd94..16feaf1f835 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -87,10 +87,10 @@ } else { //non-portable IP which has only one NIC /* - var nic = $.grep(instance.nic, function(nic) { - return nic.networkid == network.id; - })[0]; - */ + var nic = $.grep(instance.nic, function(nic) { + return nic.networkid == network.id; + })[0]; + */ // Get NIC IPs $.ajax({ @@ -171,10 +171,10 @@ } else { //non-portable IP which has only one NIC /* - var nic = $.grep(instance.nic, function(nic) { - return nic.networkid == network.id; - })[0]; - */ + var nic = $.grep(instance.nic, function(nic) { + return nic.networkid == network.id; + })[0]; + */ // Get NIC IPs $.ajax({ @@ -258,11 +258,11 @@ disallowedActions.push('remove'); } else { //non-sourceNAT IP supports staticNAT disallowedActions.push('enableVPN'); - if (ipObj.isstaticnat) { - disallowedActions.push('enableStaticNAT'); - } else { - disallowedActions.push('disableStaticNAT'); - } + if (ipObj.isstaticnat) { + disallowedActions.push('enableStaticNAT'); + } else { + disallowedActions.push('disableStaticNAT'); + } } //***** apply to both Isolated Guest Network IP, VPC IP (end) ***** @@ -270,20 +270,20 @@ if (!('vpc' in args.context)) { //***** Guest Network section > Guest Network page > IP Address page ***** if (args.context.networks[0].networkofferingconservemode == false) { /* - (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. - */ + (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. + */ if (ipObj.issourcenat == true) { disallowedActions.push('enableStaticNAT'); disallowedActions.push('enableVPN'); } /* - (2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first. - 1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. - 2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. - 3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. - 4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. - */ + (2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first. + 1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. + 2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. + 3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. + 4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. + */ else { //ipObj.issourcenat == false if (ipObj.isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. disallowedActions.push('enableVPN'); @@ -712,7 +712,7 @@ }); } else { args.response.success({ - data: null + data: null }); } } @@ -1112,7 +1112,7 @@ confirm: function(args) { return 'message.action.delete.network'; }, - isWarning: true, + isWarning: true, notification: function(args) { return 'label.action.delete.network'; } @@ -1656,7 +1656,7 @@ async: true, success: function(json) { var response = json.listnetworkofferingsresponse.networkoffering ? - json.listnetworkofferingsresponse.networkoffering[0] : null; + json.listnetworkofferingsresponse.networkoffering[0] : null; if (response != null) { if (response.egressdefaultpolicy == true) { @@ -2412,7 +2412,7 @@ args.response.success({ data: $.grep( data.listvirtualmachinesresponse.virtualmachine ? - data.listvirtualmachinesresponse.virtualmachine : [], + data.listvirtualmachinesresponse.virtualmachine : [], function(instance) { return $.inArray(instance.state, [ 'Destroyed', 'Expunging' @@ -2698,7 +2698,7 @@ var network = $.grep( args.context.vpc ? - args.context.vpc[0].network : args.context.networks, + args.context.vpc[0].network : args.context.networks, function(network) { return network.id = ipObj.associatednetworkid; })[0]; @@ -2777,8 +2777,8 @@ if (networkObj.networkofferingconservemode == false) { /* - (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. - */ + (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. + */ if (args.context.ipAddresses[0].issourcenat) { if (havingFirewallService == false) { //firewall is not supported in IP from VPC section (because ACL has already supported in tier from VPC section) disallowedActions.push("firewall"); @@ -2789,12 +2789,12 @@ } /* - (2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first. - 1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. - 2. If VPN service is supported (i.e. IP comes from Guest Network section, not from VPC section), once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. - 3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. - 4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. - */ + (2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first. + 1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. + 2. If VPN service is supported (i.e. IP comes from Guest Network section, not from VPC section), once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. + 3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. + 4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. + */ else { //args.context.ipAddresses[0].issourcenat == false if (havingFirewallService == false) disallowedActions.push("firewall"); @@ -3136,7 +3136,7 @@ success: function(data) { var vmData = $.grep( data.listvirtualmachinesresponse.virtualmachine ? - data.listvirtualmachinesresponse.virtualmachine : [], + data.listvirtualmachinesresponse.virtualmachine : [], function(instance) { //Hiding the autoScale VMs var nonAutoScale = 0; @@ -3271,18 +3271,18 @@ isEditable: true, select: function(args) { var data = [{ - id: 'roundrobin', - name: 'roundrobin', - description: _l('label.lb.algorithm.roundrobin') - }, { - id: 'leastconn', - name: 'leastconn', - description: _l('label.lb.algorithm.leastconn') - }, { - id: 'source', - name: 'source', - description: _l('label.lb.algorithm.source') - }]; + id: 'roundrobin', + name: 'roundrobin', + description: _l('label.lb.algorithm.roundrobin') + }, { + id: 'leastconn', + name: 'leastconn', + description: _l('label.lb.algorithm.leastconn') + }, { + id: 'source', + name: 'source', + description: _l('label.lb.algorithm.source') + }]; if (typeof args.context != 'undefined') { var lbAlgs = getLBAlgorithms(args.context.networks[0]); data = (lbAlgs.length == 0) ? data : lbAlgs; @@ -3459,7 +3459,7 @@ var stickyData = $.extend(true, {}, args.data.sticky); var certificateData = $.extend(true, {}, args.data.sslcertificate); - //***** create new LB rule > Add VMs ***** + //***** create new LB rule > Add VMs ***** $.ajax({ url: createURL('createLoadBalancerRule'), data: data, @@ -4027,7 +4027,7 @@ args.response.success({ data: $.grep( data.listvirtualmachinesresponse.virtualmachine ? - data.listvirtualmachinesresponse.virtualmachine : [], + data.listvirtualmachinesresponse.virtualmachine : [], function(instance) { return $.inArray(instance.state, [ 'Destroyed', 'Expunging' @@ -4295,17 +4295,17 @@ return $('
') .append( - $('
    ').addClass('info') + $('
      ').addClass('info') .append( - // VPN IP - $('
    • ').addClass('ip').html(_l('message.enabled.vpn') + ' ') + // VPN IP + $('
    • ').addClass('ip').html(_l('message.enabled.vpn') + ' ') .append($('').html(ipAddress)) - ) + ) .append( - // PSK - $('
    • ').addClass('psk').html(_l('message.enabled.vpn.ip.sec') + ' ') + // PSK + $('
    • ').addClass('psk').html(_l('message.enabled.vpn.ip.sec') + ' ') .append($('').html(psk)) - ) + ) .append( //Note $('
    • ').html(_l('message.enabled.vpn.note')) @@ -4667,7 +4667,7 @@ args.response.success({ data: $.map( data.listsecuritygroupsresponse.securitygroup[0].ingressrule ? - data.listsecuritygroupsresponse.securitygroup[0].ingressrule : [], + data.listsecuritygroupsresponse.securitygroup[0].ingressrule : [], ingressEgressDataMap ) }); @@ -4877,7 +4877,7 @@ args.response.success({ data: $.map( data.listsecuritygroupsresponse.securitygroup[0].egressrule ? - data.listsecuritygroupsresponse.securitygroup[0].egressrule : [], + data.listsecuritygroupsresponse.securitygroup[0].egressrule : [], ingressEgressDataMap ) }); @@ -5069,7 +5069,7 @@ items, function (vpc, i) { return vpc.regionlevelvpc; - }); + }); args.response.success({ data: items @@ -5080,7 +5080,7 @@ message: parseXMLHttpResponse(XMLHttpResponse) }); args.response.error(); - } + } }); }, actions: { @@ -5120,6 +5120,7 @@ required: true }, select: function(args) { + var data = {}; $.ajax({ url: createURL('listZones'), @@ -5129,6 +5130,47 @@ var advZones = $.grep(zones, function(zone) { return zone.networktype == 'Advanced' && !zone.securitygroupsenabled; }); + + //We need to be able to change the visibility of the NuageVspDT checkbox based on the selected zone (if the zone supports nuage) + var nuageDomainTemplateHandler = function(event, zoneid) { + zoneid = zoneid || this.value; + + //check if the zone id is already in the cache or not otherwise do a lookup + var cache = args.context.domainTemplateMap; + if (!(cache && cache[zoneid])) { + $.ajax({ + url: createURL('listNuageVspDomainTemplates'), + data: { zoneid: zoneid }, + success: function(json) { + var domaintemplates = json.listnuagevspdomaintemplatesresponse.domaintemplates ? json.listnuagevspdomaintemplatesresponse.domaintemplates : []; + + if (domaintemplates.length) { + args.$form.find("[rel=nuageusedomaintemplate]").show(); + } else { + args.$form.find("[rel=nuageusedomaintemplate]").hide(); + } + } + }); + args.$form.find("[rel=nuageusedomaintemplate]").find("input").attr('checked', false); + } else if (cache[zoneid].length) { + if(args.context.globalDomainTemplateUsed[zoneid]){ + args.$form.find("[rel=nuageusedomaintemplate]").show(); + args.$form.find("[rel=nuagedomaintemplatelist]").show(); + args.$form.find("[rel=nuageusedomaintemplate]").find("input").attr('checked', true); + } else { + args.$form.find("[rel=nuageusedomaintemplate]").find("input").attr('checked', false); + } + args.$form.find("[rel=nuageusedomaintemplate]").show(); + } else { + args.$form.find("[rel=nuageusedomaintemplate]").hide(); + args.$form.find("[rel=nuageusedomaintemplate]").find("input").attr('checked', false); + } + }; + + nuageDomainTemplateHandler(null, advZones[0].id); + args.$select.bind('click', nuageDomainTemplateHandler); //bind on both events click, change, change event of dropdown. + args.$select.bind('change', nuageDomainTemplateHandler); + args.$form.find("[rel=nuageusedomaintemplate]").find("input").attr('checked', false); args.response.success({ data: $.map(advZones, function(zone) { return { @@ -5137,6 +5179,9 @@ }; }) }); + }, + error: function(errorMsg){ + args.$form.find("[rel=nuageusedomaintemplate]").hide(); } }); } @@ -5159,17 +5204,17 @@ validation: { required: true }, - + dependsOn: "zoneid", select: function(args) { var data = {}; $.ajax({ url: createURL('listVPCOfferings'), data: {}, success: function(json) { - var offerings = json.listvpcofferingsresponse.vpcoffering ? json.listvpcofferingsresponse.vpcoffering : []; - var filteredofferings = $.grep(offerings, function(offering) { - return offering.state == 'Enabled'; - }); + var offerings = json.listvpcofferingsresponse.vpcoffering ? json.listvpcofferingsresponse.vpcoffering : []; + var filteredofferings = $.grep(offerings, function(offering) { + return offering.state == 'Enabled'; + }); args.response.success({ data: $.map(filteredofferings, function(vpco) { return { @@ -5181,44 +5226,169 @@ } }); } + }, + nuageusedomaintemplate: { + label: 'label.nuage.vpc.usedomaintemplate', + isBoolean: true, + isChecked: false, + isHidden: function(args){ + var cache=args.context.domainTemplateMap; + return !(cache && cache[args.zoneid] && cache[args.zoneid].length); + } + }, + nuagedomaintemplatelist: { + label: 'label.nuage.vpc.domaintemplatelist', + isHidden: true, + dependsOn: ["nuageusedomaintemplate","zoneid"], + select: function(args) { + if(!args.context.domainTemplateMap){//create array if it does not exist. + args.context.domainTemplateMap = []; + args.context.globalDomainTemplateUsed = []; + } + $.ajax({ + url: createURL('listNuageVspDomainTemplates'), + dataType: "json", + data: { + zoneid: args.zoneid + }, + async: true, + success: function (json) { + $.ajax({ + url: createURL('listNuageVspGlobalDomainTemplate'), + dataType: "json", + data: { + name: "nuagevsp.vpc.domaintemplate.name" + }, + async: true, + success: function(PDTjson){ + var domaintemplates = json.listnuagevspdomaintemplatesresponse.domaintemplates ? json.listnuagevspdomaintemplatesresponse.domaintemplates : []; + var preConfiguredDomainTemplate = PDTjson.listnuagevspglobaldomaintemplateresponse.count == 1 ? PDTjson.listnuagevspglobaldomaintemplateresponse.domaintemplates[0].name : ""; + + if (!domaintemplates.length) { + args.$form.find("[rel=nuageusedomaintemplate]").hide(); + } + + var index = -1; + $.each(domaintemplates, function(key,value) { + if (preConfiguredDomainTemplate == value.name) { + index = key; + } + }); + + //Set global pre configured DT as the default by placing it to the top of the drop down list. + if (index != -1) { + domaintemplates.unshift(domaintemplates[index]); + domaintemplates.splice(index + 1, 1); + args.$form.find("[rel=nuageusedomaintemplate]").show(); + args.$form.find("[rel=nuagedomaintemplatelist]").show(); + args.$form.find("[rel=nuageusedomaintemplate]").find("input").attr('checked', true); + args.context.globalDomainTemplateUsed[args.zoneid] = true; + } else { + args.context.globalDomainTemplateUsed[args.zoneid] = false; + } + + args.context.domainTemplateMap[args.zoneid] = domaintemplates; + args.response.success({ + data: $.map(domaintemplates, function (dt) { + return { + id: dt.name, + description: dt.description + }; + }) + }); + } + }); + + } + }); + + //} + + } + } + } }, action: function(args) { - var vpcOfferingName = args.data.vpcoffering - var dataObj = { - name: args.data.name, - displaytext: args.data.displaytext, - zoneid: args.data.zoneid, - cidr: args.data.cidr, - vpcofferingid: args.data.vpcoffering - }; + var vpcOfferingName = args.data.vpcoffering; + var dataObj = { + name: args.data.name, + displaytext: args.data.displaytext, + zoneid: args.data.zoneid, + cidr: args.data.cidr, + vpcofferingid: args.data.vpcoffering + }; - if (args.data.networkdomain != null && args.data.networkdomain.length > 0) - $.extend(dataObj, { - networkdomain: args.data.networkdomain - }); + if (args.data.networkdomain != null && args.data.networkdomain.length > 0) + $.extend(dataObj, { + networkdomain: args.data.networkdomain + }); - $.ajax({ - url: createURL("createVPC"), - dataType: "json", - data: dataObj, - async: true, - success: function(json) { - var jid = json.createvpcresponse.jobid; - args.response.success({ - _custom: { - jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.vpc; + $.ajax({ + url: createURL("createVPC"), + dataType: "json", + data: dataObj, + async: true, + success: function(vpcjson) { + var jid = vpcjson.createvpcresponse.jobid; + if(args.data.nuageusedomaintemplate){ + //Nuagepre-configured DT is chosen + var dataObj = { + domaintemplate: args.data.nuagedomaintemplatelist, + vpcid: vpcjson.createvpcresponse.id, + zoneid: args.data.zoneid + }; + $.ajax({ + url: createURL("associateNuageVspDomainTemplate"), + dataType: "json", + data: dataObj, + async: true, + success: function(json) { + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + return json.queryasyncjobresultresponse.jobresult.vpc; + } } + }); + }, + error: function(errordata) { + $.ajax({ + url: createURL("deleteVPC"), + data: { + id: vpcjson.createvpcresponse.id + }, + success: function(json) { + + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + args.response.error(parseXMLHttpResponse(errordata) + ". Rollback of VPC initiated."); + } + }); + } else { + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + return json.queryasyncjobresultresponse.jobresult.vpc; } - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); + } + }); + } + + + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + + }, notification: { @@ -5288,45 +5458,45 @@ title: 'label.restart.vpc', desc: function(args) { if (Boolean(args.context.vpc[0].redundantvpcrouter)) { - return 'message.restart.vpc'; - } else { - return 'message.restart.vpc.remark'; - } + return 'message.restart.vpc'; + } else { + return 'message.restart.vpc.remark'; + } }, preFilter: function(args) { - var zoneObj; - $.ajax({ - url: createURL("listZones&id=" + args.context.vpc[0].zoneid), - dataType: "json", - async: false, - success: function(json) { - zoneObj = json.listzonesresponse.zone[0]; - } - }); + var zoneObj; + $.ajax({ + url: createURL("listZones&id=" + args.context.vpc[0].zoneid), + dataType: "json", + async: false, + success: function(json) { + zoneObj = json.listzonesresponse.zone[0]; + } + }); - args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked - args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown - args.$form.find('.form-item[rel=makeredundant]').find('input').attr('checked', 'checked'); //checked - args.$form.find('.form-item[rel=makeredundant]').css('display', 'inline-block'); //shown + args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked + args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown + args.$form.find('.form-item[rel=makeredundant]').find('input').attr('checked', 'checked'); //checked + args.$form.find('.form-item[rel=makeredundant]').css('display', 'inline-block'); //shown - if (Boolean(args.context.vpc[0].redundantvpcrouter)) { - args.$form.find('.form-item[rel=makeredundant]').hide(); - } else { - args.$form.find('.form-item[rel=makeredundant]').show(); - } - }, - fields: { - cleanup: { - label: 'label.clean.up', - isBoolean: true - }, - makeredundant: { - label: 'label.make.redundant', - isBoolean: true - } - } + if (Boolean(args.context.vpc[0].redundantvpcrouter)) { + args.$form.find('.form-item[rel=makeredundant]').hide(); + } else { + args.$form.find('.form-item[rel=makeredundant]').show(); + } + }, + fields: { + cleanup: { + label: 'label.clean.up', + isBoolean: true + }, + makeredundant: { + label: 'label.make.redundant', + isBoolean: true + } + } }, messages: { confirm: function(args) { diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js index 6f4fedcac0f..1564a2b6f25 100644 --- a/ui/scripts/ui/dialog.js +++ b/ui/scripts/ui/dialog.js @@ -271,6 +271,18 @@ $dependsOn.attr('checked', true); } } + } else if (typeof(field.isHidden) == 'function') { + //If a checkbox depends on a field. Call the isHidden function of the checkbox. + $dependsOn.bind('change', function(event) { + var $target = $(this); + var $dependent = $target.closest('form').find('[depends-on=\'' + dependsOn + '\']'); + $dependsOn.attr('checked', isChecked); + if (field.isHidden(args)) { + $dependent.hide(); + } else { + $dependent.show(); + } + }); } }