def delete_project(self, tenant_name, part_name):
        """Delete project on the DCNM.

        :param tenant_name: name of project.
        :param part_name: name of partition.
        """
        res = self._delete_partition(tenant_name, part_name)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Deleted %s partition in DCNM.", part_name)
        else:
            LOG.error(
                _LE("Failed to delete %(part)s partition in DCNM."
                    "Response: %(res)s"), {
                        'part': part_name,
                        'res': res
                    })
            raise dexc.DfaClientRequestFailed(reason=res)

        res = self._delete_org(tenant_name)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Deleted %s organization in DCNM.", tenant_name)
        else:
            LOG.error(
                _LE("Failed to delete %(org)s organization in DCNM."
                    "Response: %(res)s"), {
                        'org': tenant_name,
                        'res': res
                    })
            raise dexc.DfaClientRequestFailed(reason=res)
    def create_project(self, org_name, part_name, dci_id, desc=None):
        """Create project on the DCNM.

        :param org_name: name of organization.
        :param part_name: name of partition.
        :param dci_id: Data Center interconnect id.
        :param desc: description of project.
        """
        desc = desc or org_name
        res = self._create_org(org_name, desc)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Created %s organization in DCNM.", org_name)
        else:
            LOG.error(
                _LE("Failed to create %(org)s organization in DCNM."
                    "Response: %(res)s"), {
                        'org': org_name,
                        'res': res
                    })
            raise dexc.DfaClientRequestFailed(reason=res)

        res = self._create_or_update_partition(org_name, part_name, dci_id,
                                               desc)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Created %s partition in DCNM.", part_name)
        else:
            LOG.error(
                _LE("Failed to create %(part)s partition in DCNM."
                    "Response: %(res)s"), {
                        'part': part_name,
                        'res': res
                    })
            raise dexc.DfaClientRequestFailed(reason=res)
    def _send_request(self, operation, url, payload, desc):
        """Send request to DCNM."""

        res = None
        try:
            payload_json = None
            if payload and payload != '':
                payload_json = jsonutils.dumps(payload)
            self._login()
            desc_lookup = {
                'POST': ' creation',
                'PUT': ' update',
                'DELETE': ' deletion',
                'GET': ' get'
            }

            res = requests.request(operation,
                                   url,
                                   data=payload_json,
                                   headers=self._req_headers,
                                   timeout=self.timeout_resp)
            desc += desc_lookup.get(operation, operation.lower())
            LOG.info(_LI("DCNM-send_request: %(desc)s %(url)s %(pld)s"), {
                'desc': desc,
                'url': url,
                'pld': payload
            })

            self._logout()
        except (requests.HTTPError, requests.Timeout,
                requests.ConnectionError) as exc:
            LOG.exception(_LE('Error during request: %s'), exc)
            raise dexc.DfaClientRequestFailed(reason=exc)

        return res
    def update_project(self,
                       org_name,
                       part_name,
                       dci_id=UNKNOWN_DCI_ID,
                       service_node_ip=UNKNOWN_SRVN_NODE_IP,
                       vrf_prof=None,
                       desc=None):
        """Update project on the DCNM.

        :param org_name: name of organization.
        :param part_name: name of partition.
        :param dci_id: Data Center interconnect id.
        :param desc: description of project.
        """
        desc = desc or org_name
        res = self._create_or_update_partition(org_name,
                                               part_name,
                                               desc,
                                               dci_id=dci_id,
                                               service_node_ip=service_node_ip,
                                               vrf_prof=vrf_prof,
                                               operation='PUT')
        if res and res.status_code in self._resp_ok:
            LOG.debug("Update %s partition in DCNM.", part_name)
        else:
            LOG.error(
                _LE("Failed to update %(part)s partition in DCNM."
                    "Response: %(res)s"), {
                        'part': part_name,
                        'res': res
                    })
            raise dexc.DfaClientRequestFailed(reason=res)
    def create_partition(self,
                         org_name,
                         part_name,
                         dci_id,
                         vrf_prof,
                         service_node_ip=None,
                         desc=None):
        """Create partition on the DCNM.

        :param org_name: name of organization to be created
        :param part_name: name of partition to be created
        :param dci_id: DCI ID
        :vrf_prof: VRF profile for the partition
        :param service_node_ip: Specifies the Default route IP address.
        :param desc: string that describes organization
        """
        desc = desc or org_name
        res = self._create_or_update_partition(org_name,
                                               part_name,
                                               desc,
                                               dci_id=dci_id,
                                               service_node_ip=service_node_ip,
                                               vrf_prof=vrf_prof)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Created %s partition in DCNM.", part_name)
        else:
            LOG.error(
                _LE("Failed to create %(part)s partition in DCNM."
                    "Response: %(res)s"), ({
                        'part': part_name,
                        'res': res
                    }))
            raise dexc.DfaClientRequestFailed(reason=self._failure_msg(res))
    def create_network(self, tenant_name, network, subnet):
        """Create network on the DCNM.

        :param tenant_name: name of tenant the network belongs to
        :param network: network parameters
        :param subnet: subnet parameters of the network
        """
        seg_id = str(network.segmentation_id)
        subnet_ip_mask = subnet.cidr.split('/')
        gw_ip = subnet.gateway_ip
        cfg_args = [
            "$segmentId=" + seg_id, "$netMaskLength=" + subnet_ip_mask[1],
            "$gatewayIpAddress=" + gw_ip, "$networkName=" + network.name,
            "$vlanId=0", "$vrfName=" + tenant_name + ':' + self._part_name
        ]
        cfg_args = ';'.join(cfg_args)

        ip_range = ','.join([
            "%s-%s" % (p['start'], p['end']) for p in subnet.allocation_pools
        ])

        dhcp_scopes = {
            'ipRange': ip_range,
            'subnet': subnet.cidr,
            'gateway': gw_ip
        }

        network_info = {
            "segmentId": seg_id,
            "vlanId": "0",
            "mobilityDomainId": "None",
            "profileName": network.config_profile,
            "networkName": network.name,
            "configArg": cfg_args,
            "organizationName": tenant_name,
            "partitionName": self._part_name,
            "description": network.name,
            "dhcpScope": dhcp_scopes
        }
        if self.is_iplus:
            # Need to add the vrf name to the network info
            prof = self._config_profile_get(network.config_profile)
            if prof and prof.get('profileSubType') == 'network:universal':
                # For universal profile vrf has to e organization:partition
                network_info["vrfName"] = ':'.join(
                    (tenant_name, self._part_name))
            else:
                # Otherwise, it should be left empty.
                network_info["vrfName"] = ""

        LOG.debug("Creating %s network in DCNM.", network_info)

        res = self._create_network(network_info)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Created %s network in DCNM.", network_info)
        else:
            LOG.error(_LE("Failed to create %s network in DCNM."),
                      network_info)
            raise dexc.DfaClientRequestFailed(reason=res)
    def delete_partition(self, org_name, partition_name):
        """Send partition delete request to DCNM.

        :param partition_name: name of partition to be deleted
        """
        res = self._delete_partition(org_name, partition_name)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Deleted %s partition in DCNM.", partition_name)
        else:
            LOG.error("Failed to delete %(part)s partition in DCNM."
                      "Response: %(res)s",
                      ({'part': partition_name, 'res': res}))
            raise dexc.DfaClientRequestFailed(reason=self._failure_msg(res))
    def update_segmentid_range(self, orchestrator_id, segid_min, segid_max):
        """update segment id range in DCNM. """
        url = "%s/%s" % (self._segmentid_ranges_url, orchestrator_id)

        payload = {'orchestratorId': orchestrator_id,
                   'segmentIdRanges': "%s-%s" % (segid_min, segid_max)}

        res = self._send_request('PUT', url, payload, 'segment-id range')
        if not (res and res.status_code in self._resp_ok):
            LOG.error("Failed to update segment id range for orchestrator "
                      "%(orch)s on DCNM: %(text)s",
                      {'orch': orchestrator_id, 'text': res.text})
            raise dexc.DfaClientRequestFailed(reason=self._failure_msg(res))
    def delete_service_network(self, tenant_name, network):
        """Delete service network on the DCNM.

        :param tenant_name: name of tenant the network belongs to
        :param network: object that contains network parameters
        """

        network_info = {}
        part_name = network.part_name
        if not part_name:
            part_name = self._part_name
        seg_id = str(network.segmentation_id)
        if network.vlan:
            vlan_id = str(network.vlan)
            if network.mob_domain_name is not None:
                mob_domain_name = network.mob_domain_name
            else:
                # The current way will not work since _default_md is obtained
                # during create_service_network. It's preferrable to get it
                # during init TODO(padkrish)
                if self._default_md is None:
                    self._set_default_mobility_domain()
                mob_domain_name = self._default_md
            network_info = {
                'organizationName': tenant_name,
                'partitionName': part_name,
                'mobDomainName': mob_domain_name,
                'vlanId': vlan_id,
                'segmentId': seg_id,
            }
        else:
            network_info = {
                'organizationName': tenant_name,
                'partitionName': part_name,
                'segmentId': seg_id,
            }
        LOG.debug("Deleting %s network in DCNM.", network_info)

        res = self._delete_network(network_info)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Deleted %s network in DCNM.", network_info)
        else:
            LOG.error(_LE("Failed to delete %s network in DCNM."),
                      network_info)
            raise dexc.DfaClientRequestFailed(reason=self._failure_msg(res))
    def delete_network(self, tenant_name, network):
        """Delete network on the DCNM.

        :param tenant_name: name of tenant the network belongs to
        :param network: object that contains network parameters
        """
        seg_id = network.segmentation_id
        network_info = {
            'organizationName': tenant_name,
            'partitionName': self._part_name,
            'segmentId': seg_id,
        }
        LOG.debug("Deleting %s network in DCNM.", network_info)

        res = self._delete_network(network_info)
        if res and res.status_code in self._resp_ok:
            LOG.debug("Deleted %s network in DCNM.", network_info)
        else:
            LOG.error("Failed to delete %s network in DCNM.", network_info)
            raise dexc.DfaClientRequestFailed(reason=res)
    def create_service_network(self,
                               tenant_name,
                               network,
                               subnet,
                               dhcp_range=True):
        """Create network on the DCNM.

        :param tenant_name: name of tenant the network belongs to
        :param network: network parameters
        :param subnet: subnet parameters of the network
        """
        network_info = {}
        subnet_ip_mask = subnet.cidr.split('/')
        if self._default_md is None:
            self._set_default_mobility_domain()
        vlan_id = '0'
        gw_ip = subnet.gateway_ip
        part_name = network.part_name
        if not part_name:
            part_name = self._part_name

        if network.vlan_id:
            vlan_id = str(network.vlan_id)
            if network.mob_domain_name is not None:
                mob_domain_name = network.mob_domain_name
            else:
                mob_domain_name = self._default_md
        else:
            mob_domain_name = None

        seg_id = str(network.segmentation_id)
        seg_str = "$segmentId=" + seg_id
        cfg_args = [
            seg_str, "$netMaskLength=" + subnet_ip_mask[1],
            "$gatewayIpAddress=" + gw_ip, "$networkName=" + network.name,
            "$vlanId=" + vlan_id, "$vrfName=" + tenant_name + ':' + part_name
        ]
        cfg_args = ';'.join(cfg_args)

        ip_range = ','.join([
            "%s-%s" % (p['start'], p['end']) for p in subnet.allocation_pools
        ])

        dhcp_scopes = {
            'ipRange': ip_range,
            'subnet': subnet.cidr,
            'gateway': gw_ip
        }

        network_info = {
            "vlanId": vlan_id,
            "mobilityDomainId": mob_domain_name,
            "profileName": network.config_profile,
            "networkName": network.name,
            "configArg": cfg_args,
            "organizationName": tenant_name,
            "partitionName": part_name,
            "description": network.name,
            "netmaskLength": subnet_ip_mask[1],
            "gateway": gw_ip
        }
        if seg_id:
            network_info["segmentId"] = seg_id
        if dhcp_range:
            network_info["dhcpScope"] = dhcp_scopes
        if hasattr(subnet, 'secondary_gw'):
            network_info["secondaryGateway"] = subnet.secondary_gw
        if self._is_iplus:
            # Need to add the vrf name to the network info
            prof = self._config_profile_get(network.config_profile)
            if prof and prof.get('profileSubType') == 'network:universal':
                # For universal profile vrf has to e organization:partition
                network_info["vrfName"] = ':'.join((tenant_name, part_name))
            else:
                # Otherwise, it should be left empty.
                network_info["vrfName"] = ""

        LOG.info(_LI("Creating %s network in DCNM."), network_info)

        res = self._create_network(network_info)
        if res and res.status_code in self._resp_ok:
            LOG.info(_LI("Created %s network in DCNM."), network_info)
        else:
            LOG.error(_LE("Failed to create %s network in DCNM."),
                      network_info)
            raise dexc.DfaClientRequestFailed(reason=self._failure_msg(res))