· 6 years ago · May 03, 2019, 10:56 AM
1#!/usr/bin/env python3
2
3import json
4import requests
5import time
6from datetime import datetime
7
8# Config
9# Вот Ñто вÑе по хорошему бы заебенить в отдельный файлик
10IAM_URL = 'https://iam.api.cloud.yandex.net/iam/v1/tokens'
11oauth_token = ''
12folder = ''
13instances = []
14
15
16def get_iam(oauth):
17 r = requests.post(IAM_URL, json={'yandexPassportOauthToken': oauth})
18 if r.status_code != 200:
19 error = r.json()
20 # ошибки вÑе-таки лучше не принтами дебажить, а отлавливать полноценно и пытатьÑÑ Ñ€ÐµÑ‚Ñ€Ð°Ð¸Ñ‚ÑŒ, например
21 print('ERROR: {}'.format(error['message']))
22 quit()
23 data = json.loads(r.text)
24 return data.get('iamToken')
25
26# Manage
27def instance_list():
28 iam_token = get_iam(oauth_token)
29 # а че бы Ñтот юрл тоже не вынеÑти в конфиг?
30 url = 'https://compute.api.cloud.yandex.net/compute/v1/instances'
31 headers = {
32 # вкуÑовщина, конечно, но Ñ Ð²Ð¼ÐµÑто формата люблю f-string в таких ÑитуациÑÑ… юзать, они более аккуратные
33 'Authorization': 'Bearer {}'.format(iam_token),
34 'content-type': 'application/json'
35 }
36 # зачем отдельно инитить дату, еÑли можно ее Ñразу в реквеÑте пропихнтуь типа {'folderid':f'{folder}'}, врÑд ли у тебÑ
37 # Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð±ÑƒÐ´ÐµÑ‚ менÑтьÑÑ Ð² дальнейшем
38 data = {
39 'folderId': folder
40 }
41 r = requests.get(url, headers=headers, json=data)
42 if r.status_code != 200:
43 error = r.json()
44 print('ERROR: {}'.format(error['message']))
45 res = json.loads(r.text)
46 instances = []
47 [instances.append(i['id']) for i in res.get('instances')]
48 # конÑтрукцию выше можно заменить на instances = [instances.append(i['id']) for i in res.get('instances')] и дропать,
49 # еÑли будет пуÑтой ÑпиÑок отдавать
50 return instances
51
52
53def instance_get(instance_id):
54 iam_token = get_iam(oauth_token)
55 # о, а тут уже Ñ„Ñтринги) и опÑть же вÑе юрлы лучше в конфиг, от глаз подальше
56 url = f'https://compute.api.cloud.yandex.net/compute/v1/instances/{instance_id}'
57 headers = {
58 'Authorization': 'Bearer {}'.format(iam_token),
59 'content-type': 'application/json'
60 }
61 r = requests.get(url, headers=headers)
62 if r.status_code != 200:
63 error = r.json()
64 print('ERROR: {}'.format(error['message']))
65 res = json.loads(r.text)
66 # зачем четыре разных принта? можно же в одном через \n выводить
67 print('Name: ', res['name'])
68 print('ID: ', res['id'])
69 print('Status: ', res['status'])
70 print('\n')
71
72
73def manage_instance(instance_id, action):
74 iam_token = get_iam(oauth_token)
75 # ну ты понÑл про юрлы, да
76 url = f'https://compute.api.cloud.yandex.net/compute/v1/instances/{instance_id}:{action}'
77 headers = {
78 'Authorization': 'Bearer {}'.format(iam_token),
79 'content-type': 'application/json'
80 }
81 r = requests.post(url, headers=headers)
82 if r.status_code != 200:
83 error = r.json()
84 print('ERROR: {}'.format(error['message']))
85 res = json.loads(r.text)
86 return res.get('id')
87
88
89def get_disk_id(instance_id):
90 iam_token = get_iam(oauth_token)
91 url = f'https://compute.api.cloud.yandex.net/compute/v1/instances/{instance_id}'
92 headers = {
93 'Authorization': 'Bearer {}'.format(iam_token),
94 'content-type': 'application/json'
95 }
96 r = requests.get(url, headers=headers)
97 if r.status_code != 200:
98 error = r.json()
99 print('ERROR: {}'.format(error['message']))
100 res = json.loads(r.text)
101 return res.get('bootDisk')['diskId']
102
103
104def operation_status(operation_id):
105 iam_token = get_iam(oauth_token)
106 url = f'https://operation.api.cloud.yandex.net/operations/{operation_id}'
107 headers = {
108 'Authorization': 'Bearer {}'.format(iam_token),
109 'content-type': 'application/json'
110 }
111 r = requests.get(url, headers=headers)
112 if r.status_code != 200:
113 error = r.json()
114 print('ERROR: {}'.format(error['message']))
115 res = json.loads(r.text)
116 return res.get('done')
117
118
119def call_time():
120 current_time = datetime.now()
121 raw_time = current_time.strftime('%B-%d-%Y')
122 return str(raw_time).lower()
123
124
125def create_snapshot(disk_id):
126 iam_token = get_iam(oauth_token)
127 url = 'https://compute.api.cloud.yandex.net/compute/v1/snapshots'
128 headers = {
129 'Authorization': 'Bearer {}'.format(iam_token),
130 'content-type': 'application/json'
131 }
132 data = {
133 'folderId': folder,
134 'diskId': disk_id,
135 'name': call_time() + '-' + disk_id
136 }
137 r = requests.post(url, json=data, headers=headers)
138 if r.status_code != 200:
139 error = r.json()
140 print('ERROR: {}'.format(error['message']))
141 res = json.loads(r.text)
142 print(r.status_code, f'Snapshot created for disk: {disk_id}')
143 return res.get('id')
144
145
146def running():
147 #instances = instance_list()
148 for instance in instances:
149 disk_id = get_disk_id(instance)
150 instance_stop = manage_instance(instance, 'stop')
151 if instance_stop:
152 print(f'Instance {instance} stopped')
153 while True:
154 time.sleep(1)
155 status = operation_status(instance_stop)
156 if status is True:
157 snap = create_snapshot(disk_id)
158 break
159 while True:
160 time.sleep(1)
161 if operation_status(snap) is True:
162 manage_instance(instance, 'start')
163 print(f'Instance {instance} started\n')
164 break
165 for instance in instances:
166 instance_get(instance)
167
168
169if __name__ == '__main__':
170 running()