blob: a0835a12ed448cd8e66d44370ab20434f9d0e874 [file] [log] [blame]
Nicolas Nobleddef2462015-01-06 18:08:25 -08001#!/bin/bash
Craig Tiller06059952015-02-18 08:34:56 -08002# Copyright 2015, Google Inc.
Craig Tiller83428812015-02-16 12:13:57 -08003# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15# * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
Nicolas Nobleddef2462015-01-06 18:08:25 -080031
32# Bash funcs shared that combine common gcutil actions into single commands
33
34# remove_instance removes a named instance
35#
36# remove_instance <project> <instance_name> [<zone>="us-central1-b"]
37remove_instance() {
38 local project=$1
39 [[ -n $project ]] || {
40 echo "$FUNCNAME: missing arg: project" 1>&2
41 return 1
42 }
43 local an_instance=$2
44 [[ -n $an_instance ]] || {
45 echo "$FUNCNAME: missing arg: an_instance" 1>&2
46 return 1
47 }
48 local zone=$3
49 [[ -n $zone ]] || zone="us-central1-b"
50
51 gcloud --project $project --quiet \
52 compute instances delete $an_instance --zone=$zone
53}
54
55# has_instance checks if a project contains a named instance
56#
57# has_instance <project> <instance_name>
58has_instance() {
59 local project=$1
60 [[ -n $project ]] || {
61 echo "$FUNCNAME: missing arg: project" 1>&2
62 return 1
63 }
64 local checked_instance=$2
65 [[ -n $checked_instance ]] || {
66 echo "$FUNCNAME: missing arg: checked_instance" 1>&2
67 return 1
68 }
69
70 instances=$(gcloud --project $project compute instances list \
71 | sed -e 's/ \+/ /g' | cut -d' ' -f 1)
72 for i in $instances
73 do
74 if [[ $i == $checked_instance ]]
75 then
76 return 0
77 fi
78 done
79
80 return 1
81}
82
83# find_network_ip finds the ip address of a instance if it is present in the project.
84#
85# find_network_ip <project> <instance_name>
86find_network_ip() {
87 local project=$1
88 [[ -n $project ]] || {
89 echo "$FUNCNAME: missing arg: project" 1>&2
90 return 1
91 }
92 local checked_instance=$2
93 [[ -n $checked_instance ]] || {
94 echo "$FUNCNAME: missing arg: checked_instance" 1>&2
95 return 1
96 }
97
98 has_instance $project $checked_instance || return 1
99 gcloud --project $project compute instances list \
100 | grep -e "$checked_instance\s" | sed -e 's/ \+/ /g' | cut -d' ' -f 4
101}
102
103# delete_disks deletes a bunch of disks matching a pattern
104#
105# delete_disks <project> <disk_pattern>
106delete_disks() {
107 local project=$1
108 [[ -n $project ]] || {
109 echo "$FUNCNAME: missing arg: project" 1>&2
110 return 1
111 }
112 local disk_pattern=$2
113 [[ -n $disk_pattern ]] || {
114 echo "$FUNCNAME: missing arg: disk_pattern" 1>&2
115 return 1
116 }
117
118 trash_disks=$(gcloud --project=$project compute disks list \
119 | sed -e 's/ \+/ /g' | cut -d' ' -f 1 | grep $disk_pattern)
120 [[ -n $trash_disks ]] && gcloud --project $project \
121 --quiet compute disks delete $trash_disks
122}
123
124# has_firewall checks if a project contains a named firewall
125#
126# has_firewall <project> <checked_firewall>
127has_firewall() {
128 local project=$1
129 [[ -n $project ]] || {
130 echo "$FUNCNAME: missing arg: project" 1>&2
131 return 1
132 }
133 local checked_firewall=$2
134 [[ -n $checked_firewall ]] || {
135 echo "$FUNCNAME: missing arg: checked_firewall" 1>&2
136 return 1
137 }
138
139 instances=$(gcloud --project $project compute firewall-rules list \
140 | sed -e 's/ \+/ /g' | cut -d' ' -f 1)
141 for i in $instances
142 do
143 if [[ $i == $checked_firewall ]]
144 then
145 return 0
146 fi
147 done
148
149 return 1
150}
151
152# remove_firewall removes a named firewall from a project.
153#
154# remove_firewall <project> <checked_firewall>
155remove_firewall() {
156 local project=$1
157 [[ -n $project ]] || {
158 echo "$FUNCNAME: missing arg: project" 1>&2
159 return 1
160 }
161 local a_firewall=$2
162 [[ -n $a_firewall ]] || {
163 echo "$FUNCNAME: missing arg: a_firewall" 1>&2
164 return 1
165 }
166
167 gcloud --project $project --quiet compute firewall-rules delete $a_firewall
168}
169
170# has_network checks if a project contains a named network
171#
172# has_network <project> <checked_network>
173has_network() {
174 local project=$1
175 [[ -n $project ]] || {
176 echo "$FUNCNAME: missing arg: project" 1>&2
177 return 1
178 }
179 local checked_network=$2
180 [[ -n $checked_network ]] || {
181 echo "$FUNCNAME: missing arg: checked_network" 1>&2
182 return 1
183 }
184
185 instances=$(gcloud --project $project compute networks list \
186 | sed -e 's/ \+/ /g' | cut -d' ' -f 1)
187 for i in $instances
188 do
189 if [[ $i == $checked_network ]]
190 then
191 return 0
192 fi
193 done
194
195 return 1
196}
197
198# maybe_setup_dev_network adds a network with the given name with firewalls
199# useful to development
200#
201# - All machines can accessed internally and externally over SSH (port 22)
202# - All machines can access one another other the internal network
203# - All machines can be accessed externally via port 80, 443, 8080 and 8443
204maybe_setup_dev_network() {
205 local name=$1
206 [[ -n $name ]] || {
207 echo "$FUNCNAME: missing arg: network name" 1>&2
208 return 1
209 }
210
211 local project=$2
212 [[ -n $project ]] || {
213 echo "$FUNCNAME: missing arg: project" 1>&2
214 return 1
215 }
216
217 has_network $project $name || {
218 echo "creating network '$name'" 1>&2
219 gcloud compute --project $project networks create $name || return 1
220 }
221
222 # allow instances on the network to connect to each other internally
223 has_firewall $project "$name-ssh" || {
224 echo "adding firewall '$name-ssh'" 1>&2
225 gcloud compute --project $project firewall-rules create "$name-ssh" \
226 --network $name \
227 --allow tcp:22 || return 1;
228 }
229
230 # allow instances on the network to connect to each other internally
231 has_firewall $project "$name-internal" || {
232 echo "adding firewall '$name-internal'" 1>&2
233 gcloud compute --project $project firewall-rules create "$name-internal" \
234 --network $name \
235 --source-ranges 10.0.0.0/16 --allow tcp udp icmp || return 1;
236 }
237
238 # allow instances on the network to be connected to from external ips on
239 # specific ports
240 has_firewall $project "$name-external" || {
241 echo "adding firewall '$name-external'" 1>&2
242 gcloud compute --project $project firewall-rules create "$name-external" \
243 --network $name \
244 --allow tcp:80 tcp:8080 tcp:443 tcp:8443 || return 1;
245 }
246}
247
248# maybe_remove_dev_network removes a network set up by maybe_setup_dev_network
249maybe_remove_dev_network() {
250 local name=$1
251 [[ -n $name ]] || {
252 echo "$FUNCNAME: missing arg: network name" 1>&2
253 return 1
254 }
255
256 local project=$2
257 [[ -n $project ]] || {
258 echo "$FUNCNAME: missing arg: project" 1>&2
259 return 1
260 }
261
262 has_network $project $name || {
263 echo "network $name is not present"
264 return 0
265 }
266 for i in $(gcloud compute firewall-rules list \
267 | grep "$name-" | cut -d' ' -f 1)
268 do
269 gcloud compute --quiet firewall-rules delete $i || return 1;
270 done
271 gcloud compute --quiet networks delete $name
272}
273
274# find_named_ip finds the external ip address for a given name.
275#
276# find_named_ip <named-ip-address>
277find_named_ip() {
278 local name=$1
279 [[ -n $name ]] || { echo "$FUNCNAME: missing arg: name" 1>&2; return 1; }
280 [[ $name == 'none' ]] && return 0;
281
282 gcloud compute addresses list | sed -e 's/ \+/ /g' \
283 | grep $name | cut -d' ' -f 3
Craig Tillerce5021b2015-02-18 09:25:21 -0800284}