inventory.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/usr/bin/env python
  2. """
  3. This is an Ansible dynamic inventory for OpenStack.
  4. It requires your OpenStack credentials to be set in clouds.yaml or your shell
  5. environment.
  6. """
  7. from __future__ import print_function
  8. from collections import Mapping
  9. import json
  10. import shade
  11. def base_openshift_inventory(cluster_hosts):
  12. '''Set the base openshift inventory.'''
  13. inventory = {}
  14. masters = [server.name for server in cluster_hosts
  15. if server.metadata['host-type'] == 'master']
  16. etcd = [server.name for server in cluster_hosts
  17. if server.metadata['host-type'] == 'etcd']
  18. if not etcd:
  19. etcd = masters
  20. infra_hosts = [server.name for server in cluster_hosts
  21. if server.metadata['host-type'] == 'node' and
  22. server.metadata['sub-host-type'] == 'infra']
  23. app = [server.name for server in cluster_hosts
  24. if server.metadata['host-type'] == 'node' and
  25. server.metadata['sub-host-type'] == 'app']
  26. cns = [server.name for server in cluster_hosts
  27. if server.metadata['host-type'] == 'cns']
  28. nodes = list(set(masters + infra_hosts + app + cns))
  29. dns = [server.name for server in cluster_hosts
  30. if server.metadata['host-type'] == 'dns']
  31. load_balancers = [server.name for server in cluster_hosts
  32. if server.metadata['host-type'] == 'lb']
  33. osev3 = list(set(nodes + etcd + load_balancers))
  34. inventory['cluster_hosts'] = {'hosts': [s.name for s in cluster_hosts]}
  35. inventory['OSEv3'] = {'hosts': osev3}
  36. inventory['masters'] = {'hosts': masters}
  37. inventory['etcd'] = {'hosts': etcd}
  38. inventory['nodes'] = {'hosts': nodes}
  39. inventory['infra_hosts'] = {'hosts': infra_hosts}
  40. inventory['app'] = {'hosts': app}
  41. inventory['glusterfs'] = {'hosts': cns}
  42. inventory['dns'] = {'hosts': dns}
  43. inventory['lb'] = {'hosts': load_balancers}
  44. return inventory
  45. def get_docker_storage_mountpoints(volumes):
  46. '''Check volumes to see if they're being used for docker storage'''
  47. docker_storage_mountpoints = {}
  48. for volume in volumes:
  49. if volume.metadata.get('purpose') == "openshift_docker_storage":
  50. for attachment in volume.attachments:
  51. if attachment.server_id in docker_storage_mountpoints:
  52. docker_storage_mountpoints[attachment.server_id].append(attachment.device)
  53. else:
  54. docker_storage_mountpoints[attachment.server_id] = [attachment.device]
  55. return docker_storage_mountpoints
  56. def build_inventory():
  57. '''Build the dynamic inventory.'''
  58. cloud = shade.openstack_cloud()
  59. # TODO(shadower): filter the servers based on the `OPENSHIFT_CLUSTER`
  60. # environment variable.
  61. cluster_hosts = [
  62. server for server in cloud.list_servers()
  63. if 'metadata' in server and 'clusterid' in server.metadata]
  64. inventory = base_openshift_inventory(cluster_hosts)
  65. for server in cluster_hosts:
  66. if 'group' in server.metadata:
  67. group = server.metadata.get('group')
  68. if group not in inventory:
  69. inventory[group] = {'hosts': []}
  70. inventory[group]['hosts'].append(server.name)
  71. inventory['_meta'] = {'hostvars': {}}
  72. # cinder volumes used for docker storage
  73. docker_storage_mountpoints = get_docker_storage_mountpoints(cloud.list_volumes())
  74. for server in cluster_hosts:
  75. ssh_ip_address = server.public_v4 or server.private_v4
  76. hostvars = {
  77. 'ansible_host': ssh_ip_address
  78. }
  79. public_v4 = server.public_v4 or server.private_v4
  80. if public_v4:
  81. hostvars['public_v4'] = server.public_v4
  82. hostvars['openshift_public_ip'] = server.public_v4
  83. # TODO(shadower): what about multiple networks?
  84. if server.private_v4:
  85. hostvars['private_v4'] = server.private_v4
  86. hostvars['openshift_ip'] = server.private_v4
  87. # NOTE(shadower): Yes, we set both hostname and IP to the private
  88. # IP address for each node. OpenStack doesn't resolve nodes by
  89. # name at all, so using a hostname here would require an internal
  90. # DNS which would complicate the setup and potentially introduce
  91. # performance issues.
  92. hostvars['openshift_hostname'] = server.metadata.get(
  93. 'openshift_hostname', server.private_v4)
  94. hostvars['openshift_public_hostname'] = server.name
  95. if server.metadata['host-type'] == 'cns':
  96. hostvars['glusterfs_devices'] = ['/dev/nvme0n1']
  97. node_labels = server.metadata.get('node_labels')
  98. # NOTE(shadower): the node_labels value must be a dict not string
  99. if not isinstance(node_labels, Mapping):
  100. node_labels = json.loads(node_labels)
  101. if node_labels:
  102. hostvars['openshift_node_labels'] = node_labels
  103. # check for attached docker storage volumes
  104. if 'os-extended-volumes:volumes_attached' in server:
  105. if server.id in docker_storage_mountpoints:
  106. hostvars['docker_storage_mountpoints'] = ' '.join(docker_storage_mountpoints[server.id])
  107. inventory['_meta']['hostvars'][server.name] = hostvars
  108. return inventory
  109. if __name__ == '__main__':
  110. print(json.dumps(build_inventory(), indent=4, sort_keys=True))