|
#!/usr/bin/env ruby |
|
require './_secret.rb' |
|
secret = get_secret! |
|
|
|
out1 = send :`, %(curl -H 'X-token: #{secret["SELECTEL_KEY"]}' |
|
https://api.selectel.ru/vpc/resell/v2/projects).gsub("\n", " ") |
|
|
|
system "rm -fr selectel; mkdir -p selectel" |
|
|
|
JSON.load(out1)["projects"].each do |project| |
|
puts "_____ PROJECT: #{project["name"]} _______" |
|
out2 = send :`, %(curl -H 'X-token: #{secret["SELECTEL_KEY"]}' |
|
-X POST |
|
-H 'Content-Type: application/json' |
|
-d '{"token":{"project_id":"#{project["id"]}"}}' |
|
https://api.selectel.ru/vpc/resell/v2/tokens).gsub("\n", " ") |
|
token = JSON.load(out2)["token"]["id"] |
|
|
|
out3 = send :`, %(curl |
|
-X POST |
|
-H 'Content-Type: application/json' |
|
-d '{"auth":{ |
|
"identity":{ |
|
"methods":["token"], |
|
"token": { |
|
"id": "#{token}" |
|
} |
|
}, |
|
"scope": { |
|
"project": { |
|
"id": "#{project["id"]}" |
|
} |
|
} |
|
}}' |
|
https://api.selvpc.ru/identity/v3/auth/tokens |
|
).gsub("\n", " ") |
|
|
|
volumes = { |
|
} |
|
detached_volumes = [] |
|
JSON.load(out3)["token"]["catalog"].find{ |item| |
|
item["name"] == "cinder" && item["type"] == "volumev2" |
|
}["endpoints"].select { |ep| |
|
ep["interface"] == "public" |
|
}.each do |ep| |
|
out6 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/volumes) |
|
JSON.load(out6)["volumes"].each do |volume| |
|
out7 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/volumes/#{volume["id"]}) |
|
v = JSON.load(out7)["volume"] |
|
if v["attachments"].length >= 1 |
|
a = v["attachments"][0] |
|
volumes[a["server_id"]] ||= [] |
|
volumes[a["server_id"]].push({ |
|
"id" => v["id"], |
|
"name" => volume["name"], |
|
"size" => v["size"], |
|
"type" => v["volume_type"], |
|
"device" => a["device"] |
|
}) |
|
else |
|
detached_volumes.push( |
|
"id" => v["id"], |
|
"region" => ep["region"], |
|
"name" => volume["name"], |
|
"size" => v["size"], |
|
"type" => v["volume_type"] |
|
) |
|
end |
|
end |
|
end |
|
|
|
servers = [] |
|
JSON.load(out3)["token"]["catalog"].find{ |item| |
|
item["name"] == "nova" && item["type"] == "compute" |
|
}["endpoints"].select { |ep| |
|
ep["interface"] == "public" |
|
}.each do |ep| |
|
out4 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/servers) |
|
JSON.load(out4)["servers"].each do |server| |
|
out5 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/servers/#{server["id"]}) |
|
s = JSON.load(out5)["server"] |
|
out8 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/flavors/#{s["flavor"]["id"]}) |
|
flavor = JSON.load(out8)["flavor"] |
|
servers.push( |
|
"region" => ep["region"], |
|
"name" => server["name"], |
|
"id" => server["id"], |
|
"ram" => flavor["ram"], |
|
"cpus" => flavor["vcpus"], |
|
"ips" => s["addresses"].values.flatten.map{ |a| a["addr"] }.join(", ") |
|
) |
|
end |
|
end |
|
|
|
networks = [] |
|
JSON.load(out3)["token"]["catalog"].flat_map { |item| item["endpoints"] }.select { |ep| |
|
ep["interface"] == "public" && ep["name"] == "network" |
|
}.each do |ep| |
|
out4 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/v2.0/networks) |
|
JSON.load(out4)["networks"].reject { |network| |
|
# пропустить внешнюю сеть и публичные |
|
network["name"] == "external-network" || network["name"] =~ /\/29$/ |
|
}.each do |network| |
|
networks.push( |
|
"region" => ep["region"], |
|
"name" => network["name"], |
|
"id" => network["id"] |
|
) |
|
end |
|
end |
|
|
|
subnets = [] |
|
JSON.load(out3)["token"]["catalog"].flat_map { |item| item["endpoints"] }.select { |ep| |
|
ep["interface"] == "public" && ep["name"] == "network" |
|
}.each do |ep| |
|
out4 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/v2.0/subnets) |
|
JSON.load(out4)["subnets"].reject { |x| |
|
# пропустить публичные |
|
x["name"] =~ /\/29$/ |
|
}.each do |x| |
|
subnets.push( |
|
"region" => ep["region"], |
|
"name" => x["name"], |
|
"id" => x["id"] |
|
) |
|
end |
|
end |
|
|
|
routers = [] |
|
JSON.load(out3)["token"]["catalog"].flat_map { |item| item["endpoints"] }.select { |ep| |
|
ep["interface"] == "public" && ep["name"] == "network" |
|
}.each do |ep| |
|
out4 = send :`, %(curl -H 'X-Auth-Token: #{token}' #{ep["url"]}/v2.0/routers) |
|
JSON.load(out4)["routers"].each do |x| |
|
routers.push( |
|
"region" => ep["region"], |
|
"name" => x["name"], |
|
"id" => x["id"] |
|
) |
|
end |
|
end |
|
|
|
File.open("selectel/#{project["name"]}.txt", "w") do |f| |
|
detached_volumes.sort_by { |v| v["name"] }.each do |v| |
|
f.puts "#{v["region"]}: #{v["name"]} [#{v["size"]} MB #{v["type"]}] - (#{v["id"]})" |
|
end |
|
if detached_volumes.length > 0 |
|
f.puts "" |
|
f.puts "" |
|
end |
|
|
|
servers.sort_by { |s| s["name"] }.each do |s| |
|
f.puts "#{s["region"]}: #{s["name"]} (#{s["id"]}) - #{s["ram"]} MB, #{s["cpus"]} CPU, IPs: #{s["ips"]}" |
|
(volumes[s["id"]] || {}).sort_by { |v| v["device"] }.each do |v| |
|
f.puts " #{v["device"]} == #{v["name"]} [#{v["size"]} MB #{v["type"]}] - (#{v["id"]})" |
|
end |
|
f.puts "" |
|
end |
|
|
|
f.puts "Networks:" |
|
networks.sort_by { |n| n["name"] }.each do |n| |
|
f.puts " #{n["region"]}: #{n["name"]} (#{n["id"]})" |
|
end |
|
|
|
f.puts "Subnets:" |
|
subnets.sort_by { |n| n["name"] }.each do |n| |
|
f.puts " #{n["region"]}: #{n["name"]} (#{n["id"]})" |
|
end |
|
|
|
f.puts "Routers:" |
|
routers.sort_by { |n| n["name"] }.each do |n| |
|
f.puts " #{n["region"]}: #{n["name"]} (#{n["id"]})" |
|
end |
|
end |
|
end |
|
|
|
puts "Done." |