summaryrefslogtreecommitdiffstats
path: root/puppet/services/neutron-dhcp.yaml
blob: 91582db8f014668133b072097b3113ef5326cab9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
heat_template_version: pike

description: >
  OpenStack Neutron DHCP agent configured with Puppet

parameters:
  ServiceNetMap:
    default: {}
    description: Mapping of service_name -> network name. Typically set
                 via parameter_defaults in the resource registry.  This
                 mapping overrides those in ServiceNetMapDefaults.
    type: json
  DefaultPasswords:
    default: {}
    type: json
  RoleName:
    default: ''
    description: Role name on which the service is applied
    type: string
  RoleParameters:
    default: {}
    description: Parameters specific to the role
    type: json
  EndpointMap:
    default: {}
    description: Mapping of service endpoint -> protocol. Typically set
                 via parameter_defaults in the resource registry.
    type: json
  NeutronEnableMetadataNetwork:
    default: false
    description: If True, DHCP provide metadata network. Requires either
                 IsolatedMetadata or ForceMetadata parameters to also be True.
    type: boolean
  NeutronEnableIsolatedMetadata:
    default: false
    description: If True, DHCP provide metadata route to VM.
    type: boolean
  NeutronEnableForceMetadata:
    default: false
    description: If True, DHCP always provides metadata route to VM.
    type: boolean
  MonitoringSubscriptionNeutronDhcp:
    default: 'overcloud-neutron-dhcp'
    type: string
  NeutronDhcpAgentLoggingSource:
    type: json
    default:
      tag: openstack.neutron.agent.dhcp
      path: /var/log/neutron/dhcp-agent.log
  NeutronDhcpAgentDnsmasqDnsServers:
    default: []
    description: List of servers to use as dnsmasq forwarders
    type: comma_delimited_list

resources:

  NeutronBase:
    type: ./neutron-base.yaml
    properties:
      ServiceNetMap: {get_param: ServiceNetMap}
      DefaultPasswords: {get_param: DefaultPasswords}
      EndpointMap: {get_param: EndpointMap}
      RoleName: {get_param: RoleName}
      RoleParameters: {get_param: RoleParameters}

outputs:
  role_data:
    description: Role data for the Neutron DHCP agent service.
    value:
      service_name: neutron_dhcp
      monitoring_subscription: {get_param: MonitoringSubscriptionNeutronDhcp}
      logging_source: {get_param: NeutronDhcpAgentLoggingSource}
      logging_groups:
        - neutron
      config_settings:
        map_merge:
          - get_attr: [NeutronBase, role_data, config_settings]
          - neutron::agents::dhcp::enable_isolated_metadata: {get_param: NeutronEnableIsolatedMetadata}
            neutron::agents::dhcp::enable_force_metadata: {get_param: NeutronEnableForceMetadata}
            neutron::agents::dhcp::enable_metadata_network: {get_param: NeutronEnableMetadataNetwork}
            neutron::agents::dhcp::dnsmasq_dns_servers: {get_param: NeutronDhcpAgentDnsmasqDnsServers}
            tripleo.neutron_dhcp.firewall_rules:
              '115 neutron dhcp input':
                proto: 'udp'
                dport: 67
              '116 neutron dhcp output':
                proto: 'udp'
                chain: 'OUTPUT'
                dport: 68
      step_config: |
        include tripleo::profile::base::neutron::dhcp
      upgrade_tasks:
        - name: Check if neutron_dhcp_agent is deployed
          command: systemctl is-enabled neutron-dhcp-agent
          tags: common
          ignore_errors: True
          register: neutron_dhcp_agent_enabled
        - name: "PreUpgrade step0,validation: Check service neutron-dhcp-agent is running"
          shell: /usr/bin/systemctl show 'neutron-dhcp-agent' --property ActiveState | grep '\bactive\b'
          when: neutron_dhcp_agent_enabled.rc == 0
          tags: step0,validation
        - name: Stop neutron_dhcp service
          tags: step1
          when: neutron_dhcp_agent_enabled.rc == 0
          service: name=neutron-dhcp-agent state=stopped
ate self.temp_dir = None self.env = None self.env_id = None self.last_node = None def get_env(self): env_list = parse(exec_cmd('fuel env')) if len(env_list) == 0: err('No environment deployed') elif len(env_list) > 1: err('More than 1 environment deployed') self.env = env_list[0] self.env_id = self.env[E['id']] def download_config(self, config_type): log('Download %s config for environment %s' % (config_type, self.env_id)) exec_cmd('fuel %s --env %s --download --dir %s' % (config_type, self.env_id, self.temp_dir)) def download_node_config(self, nodeid): log('Download node %s config for environment %s to %s' % (nodeid, self.env_id,self.temp_dir)) exec_cmd('fuel deployment --node-id %s --env %s --default --dir %s' % (nodeid, self.env_id, self.temp_dir)) def write(self, file, text, newline=True): mode = 'a' if os.path.isfile(file) else 'w' with open(file, mode) as f: f.write('%s%s' % (text, ('\n' if newline else ''))) def write_yaml(self, file, data, newline=True): self.write(file, yaml.dump(data, default_flow_style=False).strip(), newline) def get_node_by_id(self, node_list, node_id): for node in node_list: if node[N['id']] == node_id: return node def reap_interface(self, node_id, interfaces): interface, mac = self.get_interface(node_id) if_name = None if interfaces: if_name = self.check_dict_exists(interfaces, interface) if not if_name: if_name = 'interfaces_%s' % str(len(interfaces) + 1) interfaces[if_name] = interface return if_name, mac def reap_transformation(self, node_id, roles, transformations): main_role = 'controller' if 'controller' in roles else 'compute' node_file = glob.glob('%s/deployment_%s/%s.yaml' % (self.temp_dir, self.env_id, node_id)) tr_name = None with open(node_file[0]) as f: node_config = yaml.load(f) transformation = {'transformations': node_config['network_scheme']['transformations']} if transformations: tr_name = self.check_dict_exists(transformations, transformation) if not tr_name: tr_name = 'transformations_%s' % str(len(transformations) + 1) transformations[tr_name] = transformation return tr_name def check_dict_exists(self, main_dict, dict): for key, val in main_dict.iteritems(): if cmp(dict, val) == 0: return key def reap_nodes_interfaces_transformations(self): node_list = parse(exec_cmd('fuel node')) real_node_ids = [node[N['id']] for node in node_list] real_node_ids.sort() min_node = real_node_ids[0] interfaces = {} transformations = {} dea_nodes = [] dha_nodes = [] for real_node_id in real_node_ids: node_id = int(real_node_id) - int(min_node) + 1 self.last_node = node_id node = self.get_node_by_id(node_list, real_node_id) roles = commafy(node[N['roles']]) if not roles: err('Fuel Node %s has no role' % real_node_id) dea_node = {'id': node_id, 'role': roles} dha_node = {'id': node_id} if_name, mac = self.reap_interface(real_node_id, interfaces) log('reap transformation for node %s' % real_node_id) tr_name = self.reap_transformation(real_node_id, roles, transformations) dea_node.update( {'interfaces': if_name, 'transformations': tr_name}) dha_node.update( {'pxeMac': mac if mac else None, 'ipmiIp': None, 'ipmiUser': None, 'ipmiPass': None, 'libvirtName': None, 'libvirtTemplate': None}) dea_nodes.append(dea_node) dha_nodes.append(dha_node) self.write_yaml(self.dha_file, {'nodes': dha_nodes}, False) self.write_yaml(self.dea_file, {'nodes': dea_nodes}) self.write_yaml(self.dea_file, interfaces) self.write_yaml(self.dea_file, transformations) self.reap_fuel_node_info() self.write_yaml(self.dha_file, {'disks': DISKS}) def reap_fuel_node_info(self): dha_nodes = [] dha_node = { 'id': self.last_node + 1, 'libvirtName': None, 'libvirtTemplate': None, 'isFuel': True, 'username': 'root', 'password': 'r00tme'} dha_nodes.append(dha_node) self.write(self.dha_file, DHA_2.format(node_id=dha_node['id']), False) self.write_yaml(self.dha_file, dha_nodes) def reap_environment_info(self): network_file = ('%s/network_%s.yaml' % (self.temp_dir, self.env_id)) network = self.read_yaml(network_file) env = {'environment': {'name': self.env[E['name']], 'net_segment_type': network['networking_parameters']['segmentation_type']}} self.write_yaml(self.dea_file, env) wanted_release = None rel_list = parse(exec_cmd('fuel release')) for rel in rel_list: if rel[R['id']] == self.env[E['release_id']]: wanted_release = rel[R['name']] self.write_yaml(self.dea_file, {'wanted_release': wanted_release}) def reap_fuel_settings(self): data = self.read_yaml('/etc/fuel/astute.yaml') fuel = {} del data['ADMIN_NETWORK']['mac'] del data['ADMIN_NETWORK']['interface'] for key in ['ADMIN_NETWORK', 'HOSTNAME', 'DNS_DOMAIN', 'DNS_SEARCH', 'DNS_UPSTREAM', 'NTP1', 'NTP2', 'NTP3', 'FUEL_ACCESS']: fuel[key] = data[key] for key in fuel['ADMIN_NETWORK'].keys(): if key not in ['ipaddress', 'netmask', 'dhcp_pool_start', 'dhcp_pool_end', 'ssh_network']: del fuel['ADMIN_NETWORK'][key] self.write_yaml(self.dea_file, {'fuel': fuel}) def reap_network_settings(self): network_file = ('%s/network_%s.yaml' % (self.temp_dir, self.env_id)) data = self.read_yaml(network_file) network = {} network['networking_parameters'] = data['networking_parameters'] network['networks'] = data['networks'] for net in network['networks']: del net['id'] del net['group_id'] self.write_yaml(self.dea_file, {'network': network}) def reap_settings(self): settings_file = '%s/settings_%s.yaml' % (self.temp_dir, self.env_id) settings = self.read_yaml(settings_file) self.write_yaml(self.dea_file, {'settings': settings}) def get_interface(self, real_node_id): exec_cmd('fuel node --node-id %s --network --download --dir %s' % (real_node_id, self.temp_dir)) interface_file = ('%s/node_%s/interfaces.yaml' % (self.temp_dir, real_node_id)) interfaces = self.read_yaml(interface_file) interface_config = {} pxe_mac = None for interface in interfaces: networks = [] for network in interface['assigned_networks']: networks.append(network['name']) if network['name'] == 'fuelweb_admin': pxe_mac = interface['mac'] if networks: interface_config[interface['name']] = networks return interface_config, pxe_mac def read_yaml(self, yaml_file): with open(yaml_file) as f: data = yaml.load(f) return data def intro(self): delete(self.dea_file) delete(self.dha_file) self.temp_dir = tempfile.mkdtemp() date = time.strftime('%c') self.write(self.dea_file, DEA_1.format(date=date, comment=self.comment), False) self.write(self.dha_file, DHA_1.format(date=date, comment=self.comment)) self.get_env() # Need to download deployment with explicit node ids node_list = parse(exec_cmd('fuel node')) real_node_ids = [node[N['id']] for node in node_list] real_node_ids.sort() self.download_node_config(','.join(real_node_ids)) self.download_config('settings') self.download_config('network') def create_base_dea(self): exec_cmd('python %s %s %s %s' % (TEMPLATER, self.dea_file, self.template, self.base_dea)) def finale(self): log('DEA file is available at %s' % self.dea_file) log('DHA file is available at %s (this is just a template)' % self.dha_file) if self.base_dea: log('DEA base file is available at %s' % self.base_dea) shutil.rmtree(self.temp_dir) def reap(self): self.intro() self.reap_environment_info() self.reap_nodes_interfaces_transformations() self.reap_fuel_settings() self.reap_network_settings() self.reap_settings() if self.base_dea: self.create_base_dea() self.finale() def parse_arguments(): parser = ArgParser(prog='python %s' % __file__) parser.add_argument('dea_file', nargs='?', action='store', default='dea.yaml', help='Deployment Environment Adapter: dea.yaml') parser.add_argument('dha_file', nargs='?', action='store', default='dha.yaml', help='Deployment Hardware Adapter: dha.yaml') parser.add_argument('comment', nargs='?', action='store', help='Comment') parser.add_argument('-base_dea', dest='base_dea', help='Create specified base DEA file from "dea_file"') parser.add_argument('-template', dest='template', nargs='?', default='base_dea_template.yaml', help='Base DEA is generated from this template') args = parser.parse_args() return (args.dea_file, args.dha_file, args.comment, args.base_dea, args.template) def main(): dea_file, dha_file, comment, base_dea, template = parse_arguments() r = Reap(dea_file, dha_file, comment, base_dea, template) r.reap() if __name__ == '__main__': main()