@@ -65,6 +65,49 @@ def get_max_per_host(placement_client, resources, required_traits):
65
65
return count_per_rp
66
66
67
67
68
+ def get_resource_provider_info (compute_client , placement_client ):
69
+ # get host aggregates to look up things like az
70
+ nova_aggregates = list (compute_client .aggregates ())
71
+
72
+ azones = {}
73
+ project_filters = {}
74
+ for agg in nova_aggregates :
75
+ az = agg .metadata .get ("availability_zone" )
76
+ if az :
77
+ azones [agg .uuid ] = az
78
+
79
+ projects = []
80
+ for key in agg .metadata .keys ():
81
+ if key .startswith ("filter_tenant_id" ):
82
+ projects .append (agg .metadata [key ])
83
+ if projects :
84
+ # TODO(johngarbutt): expose project id to aggregate names?
85
+ project_filters [agg .uuid ] = {"name" : agg .name , "projects" : projects }
86
+
87
+ # print(json.dumps(azones, indent=2))
88
+ # print(json.dumps(project_filters, indent=2))
89
+
90
+ raw_rps = list (placement_client .resource_providers ())
91
+
92
+ resource_providers = {}
93
+ for raw_rp in raw_rps :
94
+ rp = {"uuid" : raw_rp .id }
95
+ resource_providers [raw_rp .name ] = rp
96
+ # TODO - get aggregates
97
+ response = placement_client .get (
98
+ f"/resource_providers/{ raw_rp .id } /aggregates" ,
99
+ headers = {"OpenStack-API-Version" : "placement 1.19" },
100
+ )
101
+ response .raise_for_status ()
102
+ aggs = response .json ()
103
+ rp ["aggregates" ] = aggs ["aggregates" ]
104
+ for agg_id in rp ["aggregates" ]:
105
+ if agg_id in azones :
106
+ rp ["az" ] = azones [agg_id ]
107
+ if agg_id in project_filters :
108
+ rp ["project_filter" ] = project_filters [agg_id ]["name" ]
109
+ return resource_providers
110
+
68
111
69
112
def print_details (compute_client , placement_client ):
70
113
flavors = list (compute_client .flavors ())
@@ -78,17 +121,23 @@ def print_details(compute_client, placement_client):
78
121
print (f'openstack_total_capacity_per_flavor{{flavor="{ flavor_name } "}} { total } ' )
79
122
80
123
# capacity per host
81
- raw_rps = list (placement_client .resource_providers ())
82
- resource_providers = {rp .name : rp .id for rp in raw_rps }
124
+ resource_providers = get_resource_provider_info (compute_client , placement_client )
83
125
hostnames = sorted (resource_providers .keys ())
84
126
for hostname in hostnames :
85
- rp_id = resource_providers [hostname ]
127
+ rp = resource_providers [hostname ]
128
+ rp_id = rp ["uuid" ]
86
129
for flavor_name in flavor_names :
87
130
all_counts = capacity_per_flavor .get (flavor_name , {})
88
131
our_count = all_counts .get (rp_id , 0 )
89
132
if our_count == 0 :
90
133
continue
91
134
host_str = f'hypervisor="{ hostname } "'
135
+ az = rp .get ("az" )
136
+ if az :
137
+ host_str += f',az="{ az } "'
138
+ project_filter = rp .get ("project_filter" )
139
+ if project_filter :
140
+ host_str += f',project_filter="{ project_filter } "'
92
141
print (
93
142
f'openstack_capacity_by_hostname{{{ host_str } ,flavor="{ flavor_name } "}} { our_count } '
94
143
)
@@ -98,6 +147,6 @@ def print_exporter_data(app):
98
147
print_details (app .compute_client , app .placement_client )
99
148
100
149
101
- if __name__ == ' __main__' :
150
+ if __name__ == " __main__" :
102
151
conn = openstack .connect ()
103
- print_details (conn .compute , conn .placement )
152
+ print_details (conn .compute , conn .placement )
0 commit comments