aboutsummaryrefslogtreecommitdiffstats
path: root/network/ports/net_ip_list_map.j2.yaml
blob: 16bd398609f07a5a543449b49d996c4b0cdda2c5 (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
heat_template_version: pike

parameters:
  ControlPlaneIpList:
    default: []
    type: comma_delimited_list
{%- for network in networks %}
  {{network.name}}IpList:
    default: []
    type: comma_delimited_list
{%- endfor %}
  EnabledServices:
    default: []
    type: comma_delimited_list
  ServiceNetMap:
    default: {}
    type: json
  ServiceHostnameList:
    default: []
    type: comma_delimited_list
  NetworkHostnameMap:
    default: []
    type: json
{%- for network in networks %}
  {{network.name}}NetName:
    default: {{network.name_lower}}
    description: The name of the {{network.name_lower}} network.
    type: string
{%- endfor %}


resources:
   # This adds the extra "services" on for keystone
   # so that keystone_admin_api_network and
   # keystone_public_api_network point to the correct
   # network on the nodes running the "keystone" service
  EnabledServicesValue:
    type: OS::Heat::Value
    properties:
      type: comma_delimited_list
      value:
        yaql:
          expression: let(root => $) -> $.data.extra_services.items().where($[0] in $root.data.enabled_services).select($[1]).flatten() + $root.data.enabled_services
          data:
            enabled_services: {get_param: EnabledServices}
            extra_services:
              # If anything other than keystone needs this
              # then we should add an extra_networks interface
              # to the service templates role_data but for
              # now we hard-code the keystone special case
              keystone:
                - keystone_admin_api
                - keystone_public_api

  NetIpMapValue:
    type: OS::Heat::Value
    properties:
      type: json
      value:
        map_replace:
          - ctlplane: {get_param: ControlPlaneIpList}
{%- for network in networks %}
            {{network.name_lower}}: {get_param: {{network.name}}IpList}
{%- endfor %}
          - keys:
{%- for network in networks %}
              {{network.name_lower}}: {get_param: {{network.name}}NetName}
{%- endfor %}

outputs:
  net_ip_map:
    description: >
      A Hash containing a mapping of network names to assigned lists
      of IP addresses.
    value: {get_attr: [NetIpMapValue, value]}
  service_ips:
    description: >
      Map of enabled services to a list of their IP addresses
    value:
      yaql:
        # This filters any entries where the value hasn't been substituted for
        # a list, e.g it's still $service_network.  This happens when there is
        # no network defined for the service in the ServiceNetMap, which is OK
        # as not all services have to be bound to a network, so we filter them
        expression: dict($.data.map.items().where(not isString($[1])))
        data:
          map:
            map_replace:
              - map_replace:
                  - map_merge:
                      repeat:
                        template:
                          SERVICE_node_ips: SERVICE_network
                        for_each:
                          SERVICE: {get_attr: [EnabledServicesValue, value]}
                  - values: {get_param: ServiceNetMap}
              - values: {get_attr: [NetIpMapValue, value]}
  ctlplane_service_ips:
    description: >
      Map of enabled services to a list of their ctlplane IP addresses
    value:
      yaql:
        expression: dict($.data.map.items().where(len($[1]) > 0))
        data:
          map:
            map_merge:
              repeat:
                template:
                  SERVICE_ctlplane_node_ips: {get_param: ControlPlaneIpList}
                for_each:
                  SERVICE: {get_attr: [EnabledServicesValue, value]}
  service_hostnames:
    description: >
      Map of enabled services to a list of hostnames where they're running
    value:
      map_replace:
        - yaql:
            # This filters any entries where the value hasn't been substituted for
            # a list, e.g it's still $service_network.  This happens when there is
            # no network defined for the service in the ServiceNetMap, which is OK
            # as not all services have to be bound to a network, so we filter them
            expression: dict($.data.map.items().where(not $[1].endsWith("_network")))
            data:
              map:
                map_replace:
                  - map_merge:
                      repeat:
                        template:
                          SERVICE_node_names: SERVICE_network
                        for_each:
                          SERVICE: {get_attr: [EnabledServicesValue, value]}
                  - values: {get_param: ServiceNetMap}
        - values: {get_param: NetworkHostnameMap}
  short_service_hostnames:
    description: >
      Map of enabled services to a list of hostnames where they're running regardless of the network
    value:
      yaql:
        # If ServiceHostnameList is empty the role is deployed with zero nodes
        # therefore we don't want to add any *_node_names to the map
        expression: dict($.data.map.items().where(len($[1]) > 0))
        data:
          map:
            map_merge:
              repeat:
                template:
                  SERVICE_short_node_names: {get_param: ServiceHostnameList}
                for_each:
                    SERVICE: {get_attr: [EnabledServicesValue, value]}
  short_service_bootstrap_hostnames:
    description: >
      Map of enabled services to a list of hostnames where they're running regardless of the network
      Used for bootstrap purposes
    value:
      yaql:
        # If ServiceHostnameList is empty the role is deployed with zero nodes
        # therefore we don't want to add any *_node_names to the map
        expression: dict($.data.map.items().where(len($[1]) > 0))
        data:
          map:
            map_merge:
              repeat:
                template:
                  SERVICE_short_bootstrap_node_name: {get_param: ServiceHostnameList}
                for_each:
                    SERVICE: {get_attr: [EnabledServicesValue, value]}