def _get_services(self):
        svc_controller = self._controllers['Service']

        message = ''

        cp_index = 1
        for elem_cp in self._models['CloudModel']['control-planes']:
            if not ControlPlane.is_active(elem_cp):
                cp_index += 1
                continue

            t_index = 1
            for elem_t in elem_cp['tiers']:
                if not Tier.is_active(elem_t):
                    t_index += 1
                    continue

                num_services = len(elem_t['members']['vip']['services'])

                message += 'In the %s tier of the %s control plane (%s), ' \
                           'the following %s defined:\n' % \
                    (ordinal(t_index), ordinal(cp_index), elem_cp['type'],
                     pluralize(num_services, 'service is', 'services are'))

                services = sorted(elem_t['members']['1']['services'])
                for elem_s in services:
                    mnemonic = svc_controller.name_to_mnemonic(elem_s['name'])
                    name = svc_controller.mnemonic_to_name(elem_s['name'])
                    message += '    %s (%s)\n' % (mnemonic, name)

                message += '\n'

                if 'vip' in elem_t['members']:
                    services = sorted(elem_t['members']['vip']['services'])
                    num_services = len(services)
                    message += '    with VIP access to %s:\n' % (
                        pluralize(num_services, 'this service',
                                  'these services'))

                    for elem_s in services:
                        mnemonic = svc_controller.name_to_mnemonic(
                            elem_s['name'])
                        name = svc_controller.mnemonic_to_name(elem_s['name'])
                        message += '        %s (%s)\n' % (mnemonic, name)

                    message += '\n'

                t_index += 1

            cp_index += 1

        return message
    def _get_services(self):
        svc_controller = self._controllers['Service']

        message = ''

        cp_index = 1
        for elem_cp in self._models['CloudModel']['control-planes']:
            if not ControlPlane.is_active(elem_cp):
                cp_index += 1
                continue

            t_index = 1
            for elem_t in elem_cp['tiers']:
                if not Tier.is_active(elem_t):
                    t_index += 1
                    continue

                num_services = len(elem_t['members']['vip']['services'])

                message += 'In the %s tier of the %s control plane (%s), ' \
                           'the following %s defined:\n' % \
                    (ordinal(t_index), ordinal(cp_index), elem_cp['type'],
                     pluralize(num_services, 'service is', 'services are'))

                services = sorted(elem_t['members']['1']['services'])
                for elem_s in services:
                    mnemonic = svc_controller.name_to_mnemonic(elem_s['name'])
                    name = svc_controller.mnemonic_to_name(elem_s['name'])
                    message += '    %s (%s)\n' % (mnemonic, name)

                message += '\n'

                if 'vip' in elem_t['members']:
                    services = sorted(elem_t['members']['vip']['services'])
                    num_services = len(services)
                    message += '    with VIP access to %s:\n' % (pluralize(
                        num_services, 'this service', 'these services'))

                    for elem_s in services:
                        mnemonic = svc_controller.name_to_mnemonic(
                            elem_s['name'])
                        name = svc_controller.mnemonic_to_name(elem_s['name'])
                        message += '        %s (%s)\n' % (mnemonic, name)

                    message += '\n'

                t_index += 1

            cp_index += 1

        return message
    def _get_networks(self):
        svc_controller = self._controllers['Service']

        message = ''

        networks = OrderedDict()

        for elem_cp in self._models['CloudModel']['control-planes']:
            if not ControlPlane.is_active(elem_cp):
                continue

            for elem_t in elem_cp['tiers']:
                if not Tier.is_active(elem_t):
                    continue

                for elem_s in elem_t['services']:
                    for elem_nr in elem_s['network_refs']:
                        if elem_nr not in networks:
                            networks[elem_nr] = []

                        if elem_s['name'] not in networks[elem_nr]:
                            networks[elem_nr].append(elem_s['name'])

        for n, services in six.iteritems(networks):
            sservices = sorted(services)
            message += 'The following %s connected to the "%s" ' \
                       'traffic group:\n' % (
                           pluralize(len(sservices), 'service ' 'is',
                                                     'services are'), n)

            for elem_s in sservices:
                mnemonic = svc_controller.name_to_mnemonic(elem_s)
                name = svc_controller.mnemonic_to_name(elem_s)
                message += '    %s (%s)\n' % (mnemonic, name)

            message += '\n    and are accessed with the following:\n'

            for elem_cp in self._models['CloudModel']['control-planes']:
                if not ControlPlane.is_active(elem_cp):
                    continue

                cp_type = ControlPlane.get_name(elem_cp)

                addresses = []

                for nt, elem_nt in six.iteritems(elem_cp['network-topology']):
                    if nt.lower() != n.lower():
                        continue

                    for t, elem_t in six.iteritems(elem_nt):
                        for m, elem_m in six.iteritems(elem_t):
                            addr = cp_type

                            if m.lower() == 'vip':
                                addr += ' for VIP access on the ' \
                                        '%s tier: ' % \
                                        ordinal(int(t))
                            else:
                                addr += ' on the '\
                                        '%s member of the %s tier: ' % \
                                        (ordinal(int(m)), ordinal(int(t)))

                            addr += elem_m['ip-address']

                            addresses.append(addr)

                sorted_addresses = sorted(addresses)
                for elem_a in sorted_addresses:
                    message += '        %s\n' % elem_a

            message += '\n'

        return message
    def _get_networks(self):
        svc_controller = self._controllers['Service']

        message = ''

        networks = OrderedDict()

        for elem_cp in self._models['CloudModel']['control-planes']:
            if not ControlPlane.is_active(elem_cp):
                continue

            for elem_t in elem_cp['tiers']:
                if not Tier.is_active(elem_t):
                    continue

                for elem_s in elem_t['services']:
                    for elem_nr in elem_s['network_refs']:
                        if elem_nr not in networks:
                            networks[elem_nr] = []

                        if elem_s['name'] not in networks[elem_nr]:
                            networks[elem_nr].append(elem_s['name'])

        for n, services in six.iteritems(networks):
            sservices = sorted(services)
            message += 'The following %s connected to the "%s" ' \
                       'traffic group:\n' % (
                           pluralize(len(sservices), 'service ' 'is',
                                                     'services are'), n)

            for elem_s in sservices:
                mnemonic = svc_controller.name_to_mnemonic(elem_s)
                name = svc_controller.mnemonic_to_name(elem_s)
                message += '    %s (%s)\n' % (mnemonic, name)

            message += '\n    and are accessed with the following:\n'

            for elem_cp in self._models['CloudModel']['control-planes']:
                if not ControlPlane.is_active(elem_cp):
                    continue

                cp_type = ControlPlane.get_name(elem_cp)

                addresses = []

                for nt, elem_nt in six.iteritems(elem_cp['network-topology']):
                    if nt.lower() != n.lower():
                        continue

                    for t, elem_t in six.iteritems(elem_nt):
                        for m, elem_m in six.iteritems(elem_t):
                            addr = cp_type

                            if m.lower() == 'vip':
                                addr += ' for VIP access on the ' \
                                        '%s tier: ' % \
                                        ordinal(int(t))
                            else:
                                addr += ' on the '\
                                        '%s member of the %s tier: ' % \
                                        (ordinal(int(m)), ordinal(int(t)))

                            addr += elem_m['ip-address']

                            addresses.append(addr)

                sorted_addresses = sorted(addresses)
                for elem_a in sorted_addresses:
                    message += '        %s\n' % elem_a

            message += '\n'

        return message
    def _get_server(self, nt_controller, server):
        elem_a = server['allocations']
        if 'hostname' not in elem_a:
            return
        cp_type = server['control-plane'].lower()
        message = ''

        message += '%s "%s %s" server has been allocated to the %s ' \
                   'control plane ' % (
                       aoran(server['vendor'], True),
                       server['vendor'], server['model'],
                       cp_type)

        node_type = nt_controller.get(
            server['node-type-elements']['type'])

        if server['member']:
            member = int(server['member'].replace('M', ''))
            tier = int(server['tier'].replace('T', ''))

            message += 'as %s "%s"\nin the %s member of the %s tier. ' % \
                       (aoran(node_type.friendly_name, False),
                        node_type.friendly_name,
                        ordinal(member), ordinal(tier))

        else:
            message += 'as %s "%s".\n' % (
                aoran(node_type.friendly_name, False),
                node_type.friendly_name)

        message += 'It\'s hostname is "%s" and\nit\'s in the "%s" ' \
                   'failure zone. ' % (
                       elem_a['hostname'], server['failure-zone'])
        message += 'It\'s PXE address is "%s".\n' % (
            server['pxe-ip-addr'])

        message += '\n'

        for li, elem_li in six.iteritems(elem_a['logical-interfaces']):
            message += ' ' * 4
            message += 'This server has a logical interface "%s".\n' % li

            if 'machine-info' in elem_li:
                elem_mi = elem_li['machine-info']

                if ('nic-bonding' in elem_mi and
                        'bond-name' in elem_mi['nic-bonding']):
                    elem_nb = elem_mi['nic-bonding']

                    elem_ni = elem_mi['nic-interface']

                    message += ' ' * 8
                    message += 'This interface uses NIC Bonding and ' \
                               'the bond name is "%s".\n' % (
                                   elem_nb['bond-name'],)

                    if 'ethernet' in elem_ni:
                        elem_e = elem_ni['ethernet']

                        message += ' ' * 12
                        message += 'The bond includes the physical ' \
                                   'ethernet ports: "%s".\n' % (
                                       ', '.join(
                                           elem_e['interface-ports']))

                    else:
                        elem_be = elem_ni['bus-enumeration']

                        for elem_ip in elem_be['interface-ports']:
                            message += ' ' * 12
                            message += 'The bond includes an enumeration ' \
                                       'where PCI Bus Address "%s"\n' % (
                                           elem_ip['bus-address'],)

                            message += ' ' * 16
                            message += 'is bound to port ' \
                                       '"%s" using label "%s".\n' % (
                                           elem_ip['port'],
                                           elem_ip['label'])

                else:
                    elem_ni = elem_mi['nic-interface']

                    if 'ethernet' in elem_ni:
                        elem_e = elem_ni['ethernet']
                        message += ' ' * 8
                        message += 'This interface is bound to the ' \
                                   'physical ethernet port "%s".\n' % (
                                       elem_e['interface-ports'][0],)

                    else:
                        elem_be = elem_ni['bus-enumeration']
                        elem_ip = elem_be['interface-ports'][0]

                        message += ' ' * 8
                        message += 'The interface includes an ' \
                                   'enumeration where PCI Bus ' \
                                   'Address "%s"\n' % (
                                       elem_ip['bus-address'],)

                        message += ' ' * 12
                        message += 'is bound to port ' \
                                   '"%s" using label "%s".\n' % (
                                       elem_ip['port'], elem_ip['label'])

                networks = sorted(elem_li['networks'])
                for elem_n in networks:
                    ip_host = elem_a['hostname'].replace('NETPXE', elem_n)
                    ip_addr = self._get_ip_addr(ip_host)
                    vlan = self._get_vlan(
                        elem_a['hostname'],
                        server['node-type-elements']['type'],
                        li, elem_n)

                    message += ' ' * 8

                    if vlan:
                        message += 'The "%s" traffic group ' \
                                   'is on VLAN "%s" and ' \
                                   'is bound to the IP Address "%s"\n' % (
                                       elem_n, vlan, ip_addr)
                    else:
                        message += 'The "%s" traffic group ' \
                                   'is not on a VLAN ' \
                                   'and is bound to the IP Address ' \
                                   '"%s"\n' % (elem_n, ip_addr)
        return message
    def _get_server(self, nt_controller, server):
        elem_a = server['allocations']
        if 'hostname' not in elem_a:
            return
        cp_type = server['control-plane'].lower()
        message = ''

        message += '%s "%s %s" server has been allocated to the %s ' \
                   'control plane ' % (
                       aoran(server['vendor'], True),
                       server['vendor'], server['model'],
                       cp_type)

        node_type = nt_controller.get(server['node-type-elements']['type'])

        if server['member']:
            member = int(server['member'].replace('M', ''))
            tier = int(server['tier'].replace('T', ''))

            message += 'as %s "%s"\nin the %s member of the %s tier. ' % \
                       (aoran(node_type.friendly_name, False),
                        node_type.friendly_name,
                        ordinal(member), ordinal(tier))

        else:
            message += 'as %s "%s".\n' % (aoran(
                node_type.friendly_name, False), node_type.friendly_name)

        message += 'It\'s hostname is "%s" and\nit\'s in the "%s" ' \
                   'failure zone. ' % (
                       elem_a['hostname'], server['failure-zone'])
        message += 'It\'s PXE address is "%s".\n' % (server['pxe-ip-addr'])

        message += '\n'

        for li, elem_li in six.iteritems(elem_a['logical-interfaces']):
            message += ' ' * 4
            message += 'This server has a logical interface "%s".\n' % li

            if 'machine-info' in elem_li:
                elem_mi = elem_li['machine-info']

                if ('nic-bonding' in elem_mi
                        and 'bond-name' in elem_mi['nic-bonding']):
                    elem_nb = elem_mi['nic-bonding']

                    elem_ni = elem_mi['nic-interface']

                    message += ' ' * 8
                    message += 'This interface uses NIC Bonding and ' \
                               'the bond name is "%s".\n' % (
                                   elem_nb['bond-name'],)

                    if 'ethernet' in elem_ni:
                        elem_e = elem_ni['ethernet']

                        message += ' ' * 12
                        message += 'The bond includes the physical ' \
                                   'ethernet ports: "%s".\n' % (
                                       ', '.join(
                                           elem_e['interface-ports']))

                    else:
                        elem_be = elem_ni['bus-enumeration']

                        for elem_ip in elem_be['interface-ports']:
                            message += ' ' * 12
                            message += 'The bond includes an enumeration ' \
                                       'where PCI Bus Address "%s"\n' % (
                                           elem_ip['bus-address'],)

                            message += ' ' * 16
                            message += 'is bound to port ' \
                                       '"%s" using label "%s".\n' % (
                                           elem_ip['port'],
                                           elem_ip['label'])

                else:
                    elem_ni = elem_mi['nic-interface']

                    if 'ethernet' in elem_ni:
                        elem_e = elem_ni['ethernet']
                        message += ' ' * 8
                        message += 'This interface is bound to the ' \
                                   'physical ethernet port "%s".\n' % (
                                       elem_e['interface-ports'][0],)

                    else:
                        elem_be = elem_ni['bus-enumeration']
                        elem_ip = elem_be['interface-ports'][0]

                        message += ' ' * 8
                        message += 'The interface includes an ' \
                                   'enumeration where PCI Bus ' \
                                   'Address "%s"\n' % (
                                       elem_ip['bus-address'],)

                        message += ' ' * 12
                        message += 'is bound to port ' \
                                   '"%s" using label "%s".\n' % (
                                       elem_ip['port'], elem_ip['label'])

                networks = sorted(elem_li['networks'])
                for elem_n in networks:
                    ip_host = elem_a['hostname'].replace('NETPXE', elem_n)
                    ip_addr = self._get_ip_addr(ip_host)
                    vlan = self._get_vlan(elem_a['hostname'],
                                          server['node-type-elements']['type'],
                                          li, elem_n)

                    message += ' ' * 8

                    if vlan:
                        message += 'The "%s" traffic group ' \
                                   'is on VLAN "%s" and ' \
                                   'is bound to the IP Address "%s"\n' % (
                                       elem_n, vlan, ip_addr)
                    else:
                        message += 'The "%s" traffic group ' \
                                   'is not on a VLAN ' \
                                   'and is bound to the IP Address ' \
                                   '"%s"\n' % (elem_n, ip_addr)
        return message
    def _get_structure(self):
        nt_controller = self._controllers['NodeType']

        path = self._instructions['cloud_input_path']
        name, nickname = CloudNameController.get_cloud_names(path)

        if nickname and (len(nickname) > 0):
            message = 'The "%s" cloud was created with a nickname of "%s" ' % (
                name, nickname)
        else:
            message = 'The "%s" cloud was created with no nickname ' % name

        num_cp = len(self._models['CloudModel']['control-planes'])
        message += 'and "%d" defined control %s.\n\n' % \
                   (num_cp, pluralize(num_cp, 'plane', 'planes'))

        cp_index = 1
        for elem_cp in self._models['CloudModel']['control-planes']:
            if not ControlPlane.is_active(elem_cp):
                continue

            cp_type = ControlPlane.get_name(elem_cp)
            num_tiers = ControlPlane.get_active_tier_count(elem_cp)
            str_tiers = pluralize(num_tiers, 'tier', 'tiers')
            message += 'The %s control plane is a "%s" (%s) and has "%d" ' \
                       '%s.\n' % (ordinal(cp_index), cp_type, elem_cp['type'],
                                  num_tiers, str_tiers)

            t_index = 1
            for elem_t in elem_cp['tiers']:
                if not Tier.is_active(elem_t):
                    continue

                mc = Tier.get_active_member_count(elem_t)
                if mc == 1:
                    message += 'The %s tier in this control plane is not ' \
                               'clustered.' % ordinal(t_index)
                else:
                    message += 'The %s tier in this control plane is ' \
                               'clustered, having "%s" %s in the cluster.' % \
                               (ordinal(t_index), mc,
                                pluralize(mc, 'member', 'members'))
                message += '\n'

                t_index += 1

            if ('resource-nodes' not in elem_cp or
                    elem_cp['resource-nodes'] == {}):
                message += 'There are no resource nodes defined in this ' \
                           'control plane.\n'
            else:
                for rn, elem_rn in six.iteritems(elem_cp['resource-nodes']):
                    count = elem_rn['count']
                    node_type = nt_controller.get(rn)

                    fn_singular = node_type.friendly_name
                    fn_plural = node_type.friendly_name + 's'

                    message += 'There %s %s %s (%s) ' \
                               'defined in this control plane.\n' % (
                                   pluralize(count, 'is', 'are'), count,
                                   pluralize(count, fn_singular, fn_plural),
                                   rn)

            message += '\n'
            cp_index += 1

        return message