52
52
# The location of the private key (PEM format)
53
53
service_account_private_key: /home/erjohnso/PRIVKEY.pem
54
54
provider: gce
55
+ # Specify whether to use public or private IP for deploy script.
56
+ # Valid options are:
57
+ # private_ips - The salt-master is also hosted with GCE
58
+ # public_ips - The salt-master is hosted outside of GCE
59
+ ssh_interface: public_ips
55
60
56
61
:maintainer: Eric Johnson <erjohnso@google.com>
57
62
:maturity: new
@@ -229,6 +234,16 @@ def _expand_disk(disk):
229
234
return ret
230
235
231
236
237
+ def _expand_address (addy ):
238
+ '''
239
+ Convert the libcloud GCEAddress object into something more serializable.
240
+ '''
241
+ ret = {}
242
+ ret .update (addy .__dict__ )
243
+ ret ['extra' ]['zone' ] = addy .region .name
244
+ return ret
245
+
246
+
232
247
def _expand_balancer (lb ):
233
248
'''
234
249
Convert the libcloud load-balancer object into something more serializable.
@@ -404,14 +419,25 @@ def __get_metadata(vm_):
404
419
return metadata
405
420
406
421
407
- def __get_host (node ):
422
+ def __get_host (node , vm_ ):
408
423
'''
409
424
Return public IP, private IP, or hostname for the libcloud 'node' object
410
425
'''
411
- if len (node .public_ips ) > 0 :
412
- return node .public_ips [0 ]
413
- if len (node .private_ips ) > 0 :
414
- return node .private_ips [0 ]
426
+ if __get_ssh_interface (vm_ ) == 'private_ips' :
427
+ ip_address = node .private_ips [0 ]
428
+ log .info ('Salt node data. Private_ip: {0}' .format (ip_address ))
429
+ else :
430
+ ip_address = node .public_ips [0 ]
431
+ log .info ('Salt node data. Public_ip: {0}' .format (ip_address ))
432
+
433
+ # if len(node.public_ips) > 0:
434
+ # return node.public_ips[0]
435
+ # if len(node.private_ips) > 0:
436
+ # return node.private_ips[0]
437
+
438
+ if len (ip_address ) > 0 :
439
+ return ip_address
440
+
415
441
return node .name
416
442
417
443
@@ -425,6 +451,35 @@ def __get_network(conn, vm_):
425
451
return conn .ex_get_network (network )
426
452
427
453
454
+ def __get_ssh_interface (vm_ ):
455
+ '''
456
+ Return the ssh_interface type to connect to. Either 'public_ips' (default)
457
+ or 'private_ips'.
458
+ '''
459
+ return config .get_cloud_config_value (
460
+ 'ssh_interface' , vm_ , __opts__ , default = 'public_ips' ,
461
+ search_global = False
462
+ )
463
+
464
+
465
+ def __create_orget_address (conn , name , region ):
466
+ '''
467
+ Reuse or create a static IP address.
468
+ Returns a native GCEAddress construct to use with libcloud.
469
+ '''
470
+ try :
471
+ addy = conn .ex_get_address (name , region )
472
+ except ResourceNotFoundError : # pylint: disable=W0703
473
+ addr_kwargs = {
474
+ 'name' : name ,
475
+ 'region' : region
476
+ }
477
+ new_addy = create_address (addr_kwargs , "function" )
478
+ addy = conn .ex_get_address (new_addy ['name' ], new_addy ['region' ])
479
+
480
+ return addy
481
+
482
+
428
483
def _parse_allow (allow ):
429
484
'''
430
485
Convert firewall rule allowed user-string to specified REST API format.
@@ -928,6 +983,161 @@ def show_hc(kwargs=None, call=None):
928
983
return _expand_item (conn .ex_get_healthcheck (kwargs ['name' ]))
929
984
930
985
986
+ def create_address (kwargs = None , call = None ):
987
+ '''
988
+ Create a static address in a region.
989
+
990
+ CLI Example:
991
+
992
+ .. code-block:: bash
993
+
994
+ salt-cloud -f create_address gce name=my-ip region=us-central1 address=IP
995
+ '''
996
+ if call != 'function' :
997
+ raise SaltCloudSystemExit (
998
+ 'The create_address function must be called with -f or --function.'
999
+ )
1000
+
1001
+ if not kwargs or 'name' not in kwargs :
1002
+ log .error (
1003
+ 'A name must be specified when creating an address.'
1004
+ )
1005
+ return False
1006
+ if 'region' not in kwargs :
1007
+ log .error (
1008
+ 'A region must be specified for the address.'
1009
+ )
1010
+ return False
1011
+
1012
+ name = kwargs ['name' ]
1013
+ ex_region = kwargs ['region' ]
1014
+ ex_address = kwargs .get ("address" , None )
1015
+
1016
+ conn = get_conn ()
1017
+
1018
+ salt .utils .cloud .fire_event (
1019
+ 'event' ,
1020
+ 'create address' ,
1021
+ 'salt/cloud/address/creating' ,
1022
+ kwargs ,
1023
+ transport = __opts__ ['transport' ]
1024
+ )
1025
+
1026
+ addy = conn .ex_create_address (name , ex_region , ex_address )
1027
+
1028
+ salt .utils .cloud .fire_event (
1029
+ 'event' ,
1030
+ 'created address' ,
1031
+ 'salt/cloud/address/created' ,
1032
+ kwargs ,
1033
+ transport = __opts__ ['transport' ]
1034
+ )
1035
+
1036
+ log .info ('Created GCE Address ' + name )
1037
+
1038
+ return _expand_address (addy )
1039
+
1040
+
1041
+ def delete_address (kwargs = None , call = None ):
1042
+ '''
1043
+ Permanently delete a static address.
1044
+
1045
+ CLI Example:
1046
+
1047
+ .. code-block:: bash
1048
+
1049
+ salt-cloud -f delete_address gce name=my-ip
1050
+ '''
1051
+ if call != 'function' :
1052
+ raise SaltCloudSystemExit (
1053
+ 'The delete_address function must be called with -f or --function.'
1054
+ )
1055
+
1056
+ if not kwargs or 'name' not in kwargs :
1057
+ log .error (
1058
+ 'A name must be specified when deleting an address.'
1059
+ )
1060
+ return False
1061
+
1062
+ if not kwargs or 'region' not in kwargs :
1063
+ log .error (
1064
+ 'A region must be specified when deleting an address.'
1065
+ )
1066
+ return False
1067
+
1068
+ name = kwargs ['name' ]
1069
+ ex_region = kwargs ['region' ]
1070
+
1071
+ conn = get_conn ()
1072
+
1073
+ salt .utils .cloud .fire_event (
1074
+ 'event' ,
1075
+ 'delete address' ,
1076
+ 'salt/cloud/address/deleting' ,
1077
+ {
1078
+ 'name' : name ,
1079
+ },
1080
+ transport = __opts__ ['transport' ]
1081
+ )
1082
+
1083
+ try :
1084
+ result = conn .ex_destroy_address (
1085
+ conn .ex_get_address (name , ex_region )
1086
+ )
1087
+ except ResourceNotFoundError as exc :
1088
+ log .error (
1089
+ 'Address {0} could not be found (region {1})\n '
1090
+ 'The following exception was thrown by libcloud:\n {2}' .format (
1091
+ name , ex_region , exc ),
1092
+ exc_info_on_loglevel = logging .DEBUG
1093
+ )
1094
+ return False
1095
+
1096
+ salt .utils .cloud .fire_event (
1097
+ 'event' ,
1098
+ 'deleted address' ,
1099
+ 'salt/cloud/address/deleted' ,
1100
+ {
1101
+ 'name' : name ,
1102
+ },
1103
+ transport = __opts__ ['transport' ]
1104
+ )
1105
+
1106
+ log .info ('Deleted GCE Address ' + name )
1107
+
1108
+ return result
1109
+
1110
+
1111
+ def show_address (kwargs = None , call = None ):
1112
+ '''
1113
+ Show the details of an existing static address.
1114
+
1115
+ CLI Example:
1116
+
1117
+ .. code-block:: bash
1118
+
1119
+ salt-cloud -f show_address gce name=mysnapshot region=us-central1
1120
+ '''
1121
+ if call != 'function' :
1122
+ raise SaltCloudSystemExit (
1123
+ 'The show_snapshot function must be called with -f or --function.'
1124
+ )
1125
+ if not kwargs or 'name' not in kwargs :
1126
+ log .error (
1127
+ 'Must specify name.'
1128
+ )
1129
+ return False
1130
+
1131
+ if not kwargs or 'region' not in kwargs :
1132
+ log .error (
1133
+ 'Must specify region.'
1134
+ )
1135
+ return False
1136
+
1137
+ conn = get_conn ()
1138
+ return _expand_address (conn .ex_get_address (kwargs ['name' ], kwargs ['region' ]))
1139
+
1140
+
931
1141
def create_lb (kwargs = None , call = None ):
932
1142
'''
933
1143
Create a load-balancer configuration.
@@ -972,15 +1182,19 @@ def create_lb(kwargs=None, call=None):
972
1182
protocol = kwargs .get ('protocol' , 'tcp' )
973
1183
algorithm = kwargs .get ('algorithm' , None )
974
1184
ex_healthchecks = kwargs .get ('healthchecks' , None )
1185
+
975
1186
# pylint: disable=W0511
976
- # TODO(erjohnso): need to support GCEAddress, but that requires adding
977
- # salt functions to create/destroy/show address...
978
- ex_address = None
1187
+
1188
+ conn = get_conn ()
1189
+ lb_conn = get_lb_conn (conn )
1190
+
1191
+ ex_address = kwargs .get ('address' , None )
1192
+ if ex_address is not None :
1193
+ ex_address = __create_orget_address (conn , ex_address , ex_region )
1194
+
979
1195
if ex_healthchecks :
980
1196
ex_healthchecks = ex_healthchecks .split (',' )
981
1197
982
- lb_conn = get_lb_conn (get_conn ())
983
-
984
1198
salt .utils .cloud .fire_event (
985
1199
'event' ,
986
1200
'create load_balancer' ,
@@ -1327,6 +1541,7 @@ def delete_disk(kwargs=None, call=None):
1327
1541
1328
1542
1329
1543
def create_disk (kwargs = None , call = None ):
1544
+
1330
1545
'''
1331
1546
Create a new persistent disk. Must specify `disk_name` and `location`.
1332
1547
Can also specify an `image` or `snapshot` but if neither of those are
@@ -1821,6 +2036,7 @@ def create(vm_=None, call=None):
1821
2036
}
1822
2037
1823
2038
if LIBCLOUD_VERSION_INFO > (0 , 15 , 1 ):
2039
+
1824
2040
# This only exists in current trunk of libcloud and should be in next
1825
2041
# release
1826
2042
kwargs .update ({
@@ -1837,6 +2053,9 @@ def create(vm_=None, call=None):
1837
2053
1838
2054
if 'external_ip' in kwargs and kwargs ['external_ip' ] == "None" :
1839
2055
kwargs ['external_ip' ] = None
2056
+ elif kwargs ['external_ip' ] != 'ephemeral' :
2057
+ region = '-' .join (kwargs ['location' ].name .split ('-' )[:2 ])
2058
+ kwargs ['external_ip' ] = __create_orget_address (conn , kwargs ['external_ip' ], region )
1840
2059
1841
2060
log .info ('Creating GCE instance {0} in {1}' .format (vm_ ['name' ],
1842
2061
kwargs ['location' ].name )
@@ -1879,7 +2098,7 @@ def create(vm_=None, call=None):
1879
2098
ssh_user , ssh_key = __get_ssh_credentials (vm_ )
1880
2099
deploy_kwargs = {
1881
2100
'opts' : __opts__ ,
1882
- 'host' : __get_host (node_data ),
2101
+ 'host' : __get_host (node_data , vm_ ),
1883
2102
'username' : ssh_user ,
1884
2103
'key_filename' : ssh_key ,
1885
2104
'script' : deploy_script .script ,
0 commit comments