golden hour
/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules
⬆️ Go Up
Upload
File/Folder
Size
Actions
__init__.py
35 B
Del
OK
__pycache__
-
Del
OK
acme.py
12.74 KB
Del
OK
aix_group.py
4.12 KB
Del
OK
aix_shadow.py
1.93 KB
Del
OK
aixpkg.py
24.15 KB
Del
OK
aliases.py
5.07 KB
Del
OK
alternatives.py
5.71 KB
Del
OK
ansiblegate.py
19.51 KB
Del
OK
apache.py
12.47 KB
Del
OK
apcups.py
2.15 KB
Del
OK
apf.py
3.09 KB
Del
OK
apkpkg.py
16 KB
Del
OK
aptly.py
15.28 KB
Del
OK
aptpkg.py
116.64 KB
Del
OK
archive.py
48.63 KB
Del
OK
arista_pyeapi.py
22.06 KB
Del
OK
artifactory.py
24.78 KB
Del
OK
at.py
10.72 KB
Del
OK
at_solaris.py
8.51 KB
Del
OK
augeas_cfg.py
13.93 KB
Del
OK
aws_sqs.py
6.55 KB
Del
OK
azurearm_compute.py
20.8 KB
Del
OK
azurearm_dns.py
15.8 KB
Del
OK
azurearm_network.py
82.99 KB
Del
OK
azurearm_resource.py
35.75 KB
Del
OK
bamboohr.py
7.36 KB
Del
OK
baredoc.py
11.13 KB
Del
OK
bcache.py
28.97 KB
Del
OK
beacons.py
27.82 KB
Del
OK
bigip.py
69.11 KB
Del
OK
bluez_bluetooth.py
6.76 KB
Del
OK
boto3_elasticache.py
37.34 KB
Del
OK
boto3_elasticsearch.py
53.17 KB
Del
OK
boto3_route53.py
39.82 KB
Del
OK
boto3_sns.py
12.93 KB
Del
OK
boto_apigateway.py
61.86 KB
Del
OK
boto_asg.py
35.69 KB
Del
OK
boto_cfn.py
7.95 KB
Del
OK
boto_cloudfront.py
12.75 KB
Del
OK
boto_cloudtrail.py
14.45 KB
Del
OK
boto_cloudwatch.py
10.99 KB
Del
OK
boto_cloudwatch_event.py
9.48 KB
Del
OK
boto_cognitoidentity.py
14.63 KB
Del
OK
boto_datapipeline.py
6.94 KB
Del
OK
boto_dynamodb.py
14.98 KB
Del
OK
boto_ec2.py
79.27 KB
Del
OK
boto_efs.py
14.05 KB
Del
OK
boto_elasticache.py
23.69 KB
Del
OK
boto_elasticsearch_domain.py
15.85 KB
Del
OK
boto_elb.py
35.53 KB
Del
OK
boto_elbv2.py
10.78 KB
Del
OK
boto_iam.py
75.62 KB
Del
OK
boto_iot.py
26.2 KB
Del
OK
boto_kinesis.py
19.62 KB
Del
OK
boto_kms.py
17.29 KB
Del
OK
boto_lambda.py
35.05 KB
Del
OK
boto_rds.py
34.92 KB
Del
OK
boto_route53.py
32.55 KB
Del
OK
boto_s3.py
4.24 KB
Del
OK
boto_s3_bucket.py
31.8 KB
Del
OK
boto_secgroup.py
25.22 KB
Del
OK
boto_sns.py
7.22 KB
Del
OK
boto_sqs.py
6.43 KB
Del
OK
boto_ssm.py
3.63 KB
Del
OK
boto_vpc.py
113.08 KB
Del
OK
bower.py
5.85 KB
Del
OK
bridge.py
10.81 KB
Del
OK
bsd_shadow.py
6.25 KB
Del
OK
btrfs.py
33.66 KB
Del
OK
cabal.py
3.79 KB
Del
OK
capirca_acl.py
40.04 KB
Del
OK
cassandra_cql.py
54.16 KB
Del
OK
cassandra_mod.py
4.3 KB
Del
OK
celery.py
3.33 KB
Del
OK
ceph.py
15.82 KB
Del
OK
chassis.py
1.52 KB
Del
OK
chef.py
4.66 KB
Del
OK
chocolatey.py
41.55 KB
Del
OK
chronos.py
2.89 KB
Del
OK
chroot.py
11.73 KB
Del
OK
cimc.py
23.02 KB
Del
OK
ciscoconfparse_mod.py
14.79 KB
Del
OK
cisconso.py
3.83 KB
Del
OK
cloud.py
9.39 KB
Del
OK
cmdmod.py
163.73 KB
Del
OK
composer.py
10.31 KB
Del
OK
config.py
16.98 KB
Del
OK
consul.py
69.3 KB
Del
OK
container_resource.py
12.94 KB
Del
OK
cp.py
31.98 KB
Del
OK
cpan.py
5.54 KB
Del
OK
cron.py
28.09 KB
Del
OK
cryptdev.py
10.08 KB
Del
OK
csf.py
16.04 KB
Del
OK
cyg.py
8.32 KB
Del
OK
daemontools.py
5.41 KB
Del
OK
data.py
3.85 KB
Del
OK
datadog_api.py
7.76 KB
Del
OK
ddns.py
7.12 KB
Del
OK
deb_apache.py
7.41 KB
Del
OK
deb_postgres.py
4.18 KB
Del
OK
debconfmod.py
4.06 KB
Del
OK
debian_ip.py
64.91 KB
Del
OK
debian_service.py
6.55 KB
Del
OK
debuild_pkgbuild.py
34.68 KB
Del
OK
defaults.py
6.55 KB
Del
OK
devinfo.py
9.07 KB
Del
OK
devmap.py
627 B
Del
OK
dig.py
8.75 KB
Del
OK
disk.py
30.82 KB
Del
OK
djangomod.py
7.53 KB
Del
OK
dnsmasq.py
5.71 KB
Del
OK
dnsutil.py
11.51 KB
Del
OK
dockercompose.py
32.62 KB
Del
OK
dockermod.py
224.85 KB
Del
OK
dpkg_lowpkg.py
12.94 KB
Del
OK
drac.py
10.97 KB
Del
OK
dracr.py
38.53 KB
Del
OK
drbd.py
7.19 KB
Del
OK
dummyproxy_pkg.py
2.46 KB
Del
OK
dummyproxy_service.py
2.91 KB
Del
OK
ebuildpkg.py
38.74 KB
Del
OK
eix.py
1.58 KB
Del
OK
elasticsearch.py
51.44 KB
Del
OK
environ.py
8.96 KB
Del
OK
eselect.py
4.99 KB
Del
OK
esxcluster.py
1.66 KB
Del
OK
esxdatacenter.py
1.68 KB
Del
OK
esxi.py
2.79 KB
Del
OK
esxvm.py
1.63 KB
Del
OK
etcd_mod.py
8.56 KB
Del
OK
ethtool.py
11.12 KB
Del
OK
event.py
7.67 KB
Del
OK
extfs.py
8.78 KB
Del
OK
file.py
232.18 KB
Del
OK
firewalld.py
20.51 KB
Del
OK
freebsd_sysctl.py
4.99 KB
Del
OK
freebsd_update.py
6.19 KB
Del
OK
freebsdjail.py
7.16 KB
Del
OK
freebsdkmod.py
6.17 KB
Del
OK
freebsdpkg.py
17.04 KB
Del
OK
freebsdports.py
13.13 KB
Del
OK
freebsdservice.py
12.53 KB
Del
OK
freezer.py
10.2 KB
Del
OK
gcp_addon.py
4.07 KB
Del
OK
gem.py
10.6 KB
Del
OK
genesis.py
21.75 KB
Del
OK
gentoo_service.py
9.18 KB
Del
OK
gentoolkitmod.py
8.39 KB
Del
OK
git.py
172.01 KB
Del
OK
github.py
53.19 KB
Del
OK
glanceng.py
4.69 KB
Del
OK
glassfish.py
19.49 KB
Del
OK
glusterfs.py
19.55 KB
Del
OK
gnomedesktop.py
6.85 KB
Del
OK
google_chat.py
1.52 KB
Del
OK
gpg.py
39.09 KB
Del
OK
grafana4.py
30.27 KB
Del
OK
grains.py
21.81 KB
Del
OK
groupadd.py
11.87 KB
Del
OK
grub_legacy.py
3.08 KB
Del
OK
guestfs.py
2.37 KB
Del
OK
hadoop.py
3.76 KB
Del
OK
haproxyconn.py
10.17 KB
Del
OK
hashutil.py
6.77 KB
Del
OK
heat.py
25.25 KB
Del
OK
helm.py
39.27 KB
Del
OK
hg.py
7.16 KB
Del
OK
highstate_doc.py
22.76 KB
Del
OK
hosts.py
10.47 KB
Del
OK
http.py
3.76 KB
Del
OK
icinga2.py
4.46 KB
Del
OK
idem.py
1.75 KB
Del
OK
ifttt.py
2.28 KB
Del
OK
ilo.py
15.98 KB
Del
OK
incron.py
7.68 KB
Del
OK
influxdb08mod.py
15.07 KB
Del
OK
influxdbmod.py
16.13 KB
Del
OK
infoblox.py
17.53 KB
Del
OK
ini_manage.py
14.63 KB
Del
OK
inspectlib
-
Del
OK
inspector.py
8.19 KB
Del
OK
introspect.py
4.02 KB
Del
OK
iosconfig.py
14.78 KB
Del
OK
ipmi.py
25.47 KB
Del
OK
ipset.py
17.97 KB
Del
OK
iptables.py
57.44 KB
Del
OK
iwtools.py
3.99 KB
Del
OK
jboss7.py
20.51 KB
Del
OK
jboss7_cli.py
15.23 KB
Del
OK
jenkinsmod.py
11.9 KB
Del
OK
jinja.py
2.66 KB
Del
OK
jira_mod.py
7.07 KB
Del
OK
junos.py
73.96 KB
Del
OK
k8s.py
24.87 KB
Del
OK
kapacitor.py
5.37 KB
Del
OK
kerberos.py
5.42 KB
Del
OK
kernelpkg_linux_apt.py
6.71 KB
Del
OK
kernelpkg_linux_yum.py
7.26 KB
Del
OK
key.py
1007 B
Del
OK
keyboard.py
2.64 KB
Del
OK
keystone.py
43.14 KB
Del
OK
keystoneng.py
21.82 KB
Del
OK
keystore.py
7.18 KB
Del
OK
kmod.py
7.65 KB
Del
OK
kubeadm.py
34.64 KB
Del
OK
kubernetesmod.py
46.77 KB
Del
OK
launchctl_service.py
9.69 KB
Del
OK
layman.py
4.22 KB
Del
OK
ldap3.py
18.81 KB
Del
OK
ldapmod.py
5.9 KB
Del
OK
libcloud_compute.py
23.48 KB
Del
OK
libcloud_dns.py
9.73 KB
Del
OK
libcloud_loadbalancer.py
13.14 KB
Del
OK
libcloud_storage.py
12.16 KB
Del
OK
linux_acl.py
7.7 KB
Del
OK
linux_ip.py
5.55 KB
Del
OK
linux_lvm.py
17.86 KB
Del
OK
linux_service.py
4.64 KB
Del
OK
linux_shadow.py
12.96 KB
Del
OK
linux_sysctl.py
7.5 KB
Del
OK
localemod.py
11.84 KB
Del
OK
locate.py
2.58 KB
Del
OK
logadm.py
9.44 KB
Del
OK
logmod.py
1.25 KB
Del
OK
logrotate.py
7.72 KB
Del
OK
lvs.py
11.54 KB
Del
OK
lxc.py
147.27 KB
Del
OK
lxd.py
90.07 KB
Del
OK
mac_assistive.py
11.37 KB
Del
OK
mac_brew_pkg.py
19.91 KB
Del
OK
mac_desktop.py
2.77 KB
Del
OK
mac_group.py
6.62 KB
Del
OK
mac_keychain.py
6.39 KB
Del
OK
mac_pkgutil.py
2.84 KB
Del
OK
mac_portspkg.py
11.36 KB
Del
OK
mac_power.py
13.29 KB
Del
OK
mac_service.py
19.64 KB
Del
OK
mac_shadow.py
14.23 KB
Del
OK
mac_softwareupdate.py
14.52 KB
Del
OK
mac_sysctl.py
5.13 KB
Del
OK
mac_system.py
15.07 KB
Del
OK
mac_timezone.py
8.34 KB
Del
OK
mac_user.py
16.41 KB
Del
OK
mac_xattr.py
6.27 KB
Del
OK
macdefaults.py
2.33 KB
Del
OK
macpackage.py
6.66 KB
Del
OK
makeconf.py
17.31 KB
Del
OK
mandrill.py
6.31 KB
Del
OK
marathon.py
5.36 KB
Del
OK
match.py
13 KB
Del
OK
mattermost.py
3.4 KB
Del
OK
mdadm_raid.py
9.86 KB
Del
OK
mdata.py
3.38 KB
Del
OK
memcached.py
6.13 KB
Del
OK
mine.py
18.84 KB
Del
OK
minion.py
7.68 KB
Del
OK
mod_random.py
7.18 KB
Del
OK
modjk.py
12.48 KB
Del
OK
mongodb.py
29.75 KB
Del
OK
monit.py
5.51 KB
Del
OK
moosefs.py
3.87 KB
Del
OK
mount.py
58.44 KB
Del
OK
mssql.py
14.64 KB
Del
OK
msteams.py
2.11 KB
Del
OK
munin.py
2.4 KB
Del
OK
mysql.py
90.66 KB
Del
OK
nacl.py
9.72 KB
Del
OK
nagios.py
6.53 KB
Del
OK
nagios_rpc.py
5.09 KB
Del
OK
namecheap_domains.py
12.84 KB
Del
OK
namecheap_domains_dns.py
5.93 KB
Del
OK
namecheap_domains_ns.py
4.51 KB
Del
OK
namecheap_ssl.py
25.69 KB
Del
OK
namecheap_users.py
2.4 KB
Del
OK
napalm_bgp.py
9.72 KB
Del
OK
napalm_formula.py
11.33 KB
Del
OK
napalm_mod.py
61.37 KB
Del
OK
napalm_netacl.py
28.59 KB
Del
OK
napalm_network.py
93.22 KB
Del
OK
napalm_ntp.py
10.22 KB
Del
OK
napalm_probes.py
13.25 KB
Del
OK
napalm_route.py
5.09 KB
Del
OK
napalm_snmp.py
7.05 KB
Del
OK
napalm_users.py
6.49 KB
Del
OK
napalm_yang_mod.py
20.28 KB
Del
OK
netaddress.py
1.6 KB
Del
OK
netbox.py
32.22 KB
Del
OK
netbsd_sysctl.py
3.92 KB
Del
OK
netbsdservice.py
6.43 KB
Del
OK
netmiko_mod.py
19.61 KB
Del
OK
netscaler.py
27.02 KB
Del
OK
network.py
63.42 KB
Del
OK
neutron.py
44.92 KB
Del
OK
neutronng.py
15.02 KB
Del
OK
nexus.py
22.95 KB
Del
OK
nfs3.py
3.9 KB
Del
OK
nftables.py
33.58 KB
Del
OK
nginx.py
3.83 KB
Del
OK
nilrt_ip.py
36.18 KB
Del
OK
nix.py
8.03 KB
Del
OK
nova.py
19.6 KB
Del
OK
npm.py
10.4 KB
Del
OK
nspawn.py
41.35 KB
Del
OK
nxos.py
24.65 KB
Del
OK
nxos_api.py
14.72 KB
Del
OK
nxos_upgrade.py
14.74 KB
Del
OK
omapi.py
3.6 KB
Del
OK
openbsd_sysctl.py
3.74 KB
Del
OK
openbsdpkg.py
10.97 KB
Del
OK
openbsdrcctl_service.py
6.33 KB
Del
OK
openbsdservice.py
8.31 KB
Del
OK
openscap.py
2.81 KB
Del
OK
openstack_config.py
3.21 KB
Del
OK
openstack_mng.py
2.71 KB
Del
OK
openvswitch.py
17.19 KB
Del
OK
opkg.py
49.67 KB
Del
OK
opsgenie.py
3.29 KB
Del
OK
oracle.py
5.82 KB
Del
OK
osquery.py
24.93 KB
Del
OK
out.py
2.53 KB
Del
OK
pacmanpkg.py
31.92 KB
Del
OK
pagerduty.py
4.7 KB
Del
OK
pagerduty_util.py
13.48 KB
Del
OK
pam.py
2.01 KB
Del
OK
panos.py
61.05 KB
Del
OK
parallels.py
19.85 KB
Del
OK
parted_partition.py
21.53 KB
Del
OK
pcs.py
14.11 KB
Del
OK
pdbedit.py
10.79 KB
Del
OK
pecl.py
3.79 KB
Del
OK
peeringdb.py
8.39 KB
Del
OK
pf.py
9.51 KB
Del
OK
philips_hue.py
1.55 KB
Del
OK
pillar.py
21.37 KB
Del
OK
pip.py
53.42 KB
Del
OK
pkg_resource.py
12.3 KB
Del
OK
pkgin.py
17.29 KB
Del
OK
pkgng.py
61.07 KB
Del
OK
pkgutil.py
9.85 KB
Del
OK
portage_config.py
22.73 KB
Del
OK
postfix.py
16.24 KB
Del
OK
postgres.py
88.24 KB
Del
OK
poudriere.py
7.85 KB
Del
OK
powerpath.py
2.57 KB
Del
OK
proxy.py
11.49 KB
Del
OK
ps.py
20.89 KB
Del
OK
publish.py
10.25 KB
Del
OK
puppet.py
10.9 KB
Del
OK
purefa.py
33.59 KB
Del
OK
purefb.py
13.69 KB
Del
OK
pushbullet.py
1.88 KB
Del
OK
pushover_notify.py
3.48 KB
Del
OK
pw_group.py
4.62 KB
Del
OK
pw_user.py
12.47 KB
Del
OK
pyenv.py
6.93 KB
Del
OK
qemu_img.py
1.53 KB
Del
OK
qemu_nbd.py
3.28 KB
Del
OK
quota.py
6.43 KB
Del
OK
rabbitmq.py
38.4 KB
Del
OK
rallydev.py
6.09 KB
Del
OK
random_org.py
23.76 KB
Del
OK
rbac_solaris.py
16.05 KB
Del
OK
rbenv.py
10.75 KB
Del
OK
rdp.py
6.08 KB
Del
OK
rebootmgr.py
7.68 KB
Del
OK
redismod.py
16.36 KB
Del
OK
reg.py
16.36 KB
Del
OK
rest_pkg.py
2.26 KB
Del
OK
rest_sample_utils.py
558 B
Del
OK
rest_service.py
3.63 KB
Del
OK
restartcheck.py
24.1 KB
Del
OK
restconf.py
3.15 KB
Del
OK
ret.py
1.27 KB
Del
OK
rh_ip.py
38.55 KB
Del
OK
rh_service.py
16.61 KB
Del
OK
riak.py
5.19 KB
Del
OK
rpm_lowpkg.py
27.67 KB
Del
OK
rpmbuild_pkgbuild.py
24.53 KB
Del
OK
rsync.py
8.04 KB
Del
OK
runit.py
17.17 KB
Del
OK
rvm.py
11.1 KB
Del
OK
s3.py
9.93 KB
Del
OK
s6.py
3.62 KB
Del
OK
salt_proxy.py
4.48 KB
Del
OK
salt_version.py
4.58 KB
Del
OK
saltcheck.py
46.66 KB
Del
OK
saltcloudmod.py
954 B
Del
OK
saltutil.py
57.49 KB
Del
OK
schedule.py
50.81 KB
Del
OK
scp_mod.py
6.22 KB
Del
OK
scsi.py
2.66 KB
Del
OK
sdb.py
2.48 KB
Del
OK
seed.py
8.87 KB
Del
OK
selinux.py
24.2 KB
Del
OK
sensehat.py
7.79 KB
Del
OK
sensors.py
1.3 KB
Del
OK
serverdensity_device.py
8.1 KB
Del
OK
servicenow.py
4.36 KB
Del
OK
slack_notify.py
7.83 KB
Del
OK
slackware_service.py
6.84 KB
Del
OK
slsutil.py
19.04 KB
Del
OK
smartos_imgadm.py
12.04 KB
Del
OK
smartos_nictagadm.py
6.46 KB
Del
OK
smartos_virt.py
5.21 KB
Del
OK
smartos_vmadm.py
26.2 KB
Del
OK
smbios.py
10.05 KB
Del
OK
smf_service.py
8.52 KB
Del
OK
smtp.py
5.41 KB
Del
OK
snapper.py
27.14 KB
Del
OK
solaris_fmadm.py
11.2 KB
Del
OK
solaris_group.py
2.8 KB
Del
OK
solaris_shadow.py
7.98 KB
Del
OK
solaris_system.py
3.72 KB
Del
OK
solaris_user.py
11.06 KB
Del
OK
solarisipspkg.py
18.68 KB
Del
OK
solarispkg.py
15.4 KB
Del
OK
solr.py
45.54 KB
Del
OK
solrcloud.py
14.63 KB
Del
OK
splunk.py
8.14 KB
Del
OK
splunk_search.py
8.76 KB
Del
OK
sqlite3.py
2.54 KB
Del
OK
ssh.py
43.89 KB
Del
OK
ssh_pkg.py
1.08 KB
Del
OK
ssh_service.py
3.39 KB
Del
OK
state.py
82.34 KB
Del
OK
status.py
57.79 KB
Del
OK
statuspage.py
14.67 KB
Del
OK
supervisord.py
11.15 KB
Del
OK
suse_apache.py
2.45 KB
Del
OK
suse_ip.py
35.72 KB
Del
OK
svn.py
10.75 KB
Del
OK
swarm.py
13.5 KB
Del
OK
swift.py
5.53 KB
Del
OK
sysbench.py
6.62 KB
Del
OK
sysfs.py
6.61 KB
Del
OK
syslog_ng.py
31.52 KB
Del
OK
sysmod.py
22.59 KB
Del
OK
sysrc.py
3.38 KB
Del
OK
system.py
19.28 KB
Del
OK
system_profiler.py
3.54 KB
Del
OK
systemd_service.py
46.29 KB
Del
OK
telegram.py
3.28 KB
Del
OK
telemetry.py
12.87 KB
Del
OK
temp.py
831 B
Del
OK
test.py
15.4 KB
Del
OK
test_virtual.py
237 B
Del
OK
testinframod.py
9.92 KB
Del
OK
textfsm_mod.py
16.22 KB
Del
OK
timezone.py
19.98 KB
Del
OK
tls.py
58.63 KB
Del
OK
tomcat.py
18.59 KB
Del
OK
trafficserver.py
10.44 KB
Del
OK
transactional_update.py
35.83 KB
Del
OK
travisci.py
2.05 KB
Del
OK
tuned.py
2.34 KB
Del
OK
twilio_notify.py
2.95 KB
Del
OK
udev.py
3.72 KB
Del
OK
upstart_service.py
16.92 KB
Del
OK
uptime.py
3.23 KB
Del
OK
useradd.py
22.63 KB
Del
OK
uwsgi.py
996 B
Del
OK
vagrant.py
20.4 KB
Del
OK
varnish.py
3.08 KB
Del
OK
vault.py
15.61 KB
Del
OK
vbox_guest.py
10.55 KB
Del
OK
vboxmanage.py
14.71 KB
Del
OK
vcenter.py
1.61 KB
Del
OK
victorops.py
6.54 KB
Del
OK
virt.py
287.71 KB
Del
OK
virtualenv_mod.py
15.09 KB
Del
OK
vmctl.py
9.56 KB
Del
OK
vsphere.py
380.41 KB
Del
OK
webutil.py
3.66 KB
Del
OK
win_auditpol.py
4.74 KB
Del
OK
win_autoruns.py
2.29 KB
Del
OK
win_certutil.py
4.55 KB
Del
OK
win_dacl.py
32.27 KB
Del
OK
win_disk.py
1.8 KB
Del
OK
win_dism.py
20.7 KB
Del
OK
win_dns_client.py
4.19 KB
Del
OK
win_dsc.py
27.54 KB
Del
OK
win_event.py
22.32 KB
Del
OK
win_file.py
64.39 KB
Del
OK
win_firewall.py
20.15 KB
Del
OK
win_groupadd.py
11.27 KB
Del
OK
win_iis.py
68.78 KB
Del
OK
win_ip.py
11.43 KB
Del
OK
win_lgpo.py
491.76 KB
Del
OK
win_lgpo_reg.py
17.9 KB
Del
OK
win_license.py
2.72 KB
Del
OK
win_network.py
13.9 KB
Del
OK
win_ntp.py
1.8 KB
Del
OK
win_path.py
11.12 KB
Del
OK
win_pkg.py
86.43 KB
Del
OK
win_pki.py
15.8 KB
Del
OK
win_powercfg.py
9.85 KB
Del
OK
win_psget.py
8.97 KB
Del
OK
win_servermanager.py
14.21 KB
Del
OK
win_service.py
32.96 KB
Del
OK
win_shadow.py
3.03 KB
Del
OK
win_shortcut.py
16.49 KB
Del
OK
win_smtp_server.py
17.67 KB
Del
OK
win_snmp.py
13.38 KB
Del
OK
win_status.py
16.94 KB
Del
OK
win_system.py
40.61 KB
Del
OK
win_task.py
79.17 KB
Del
OK
win_timezone.py
13.3 KB
Del
OK
win_useradd.py
27.39 KB
Del
OK
win_wua.py
38.29 KB
Del
OK
win_wusa.py
5.88 KB
Del
OK
winrepo.py
6.09 KB
Del
OK
wordpress.py
4.71 KB
Del
OK
x509.py
63.1 KB
Del
OK
x509_v2.py
74.15 KB
Del
OK
xapi_virt.py
24.07 KB
Del
OK
xbpspkg.py
15.84 KB
Del
OK
xfs.py
15.35 KB
Del
OK
xml.py
2.14 KB
Del
OK
xmpp.py
5.28 KB
Del
OK
yaml.py
1.94 KB
Del
OK
yumpkg.py
116.5 KB
Del
OK
zabbix.py
97.55 KB
Del
OK
zcbuildout.py
28.16 KB
Del
OK
zenoss.py
5.64 KB
Del
OK
zfs.py
34.44 KB
Del
OK
zk_concurrency.py
11.16 KB
Del
OK
znc.py
2.26 KB
Del
OK
zoneadm.py
15.05 KB
Del
OK
zonecfg.py
21.85 KB
Del
OK
zookeeper.py
14.72 KB
Del
OK
zpool.py
44.02 KB
Del
OK
zypperpkg.py
94.87 KB
Del
OK
Edit: boto_ec2.py
""" Connection module for Amazon EC2 .. versionadded:: 2015.8.0 :configuration: This module accepts explicit EC2 credentials but can also utilize IAM roles assigned to the instance through Instance Profiles. Dynamic credentials are then automatically obtained from AWS API and no further configuration is necessary. More Information available here__. .. __: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html If IAM roles are not used you need to specify them either in a pillar or in the minion's config file: .. code-block:: yaml ec2.keyid: GKTADJGHEIQSXMKKRBJ08H ec2.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs A region may also be specified in the configuration: .. code-block:: yaml ec2.region: us-east-1 If a region is not specified, the default is us-east-1. It's also possible to specify key, keyid, and region via a profile, either as a passed in dict, or as a string to pull from pillars or minion config: .. code-block:: yaml myprofile: keyid: GKTADJGHEIQSXMKKRBJ08H key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs region: us-east-1 :depends: boto """ # keep lint from choking on _get_conn and _cache_id # pylint: disable=E0602 import logging import time import salt.utils.compat import salt.utils.data import salt.utils.json import salt.utils.versions from salt.exceptions import CommandExecutionError, SaltInvocationError try: # pylint: disable=unused-import import boto import boto.ec2 # pylint: enable=unused-import from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType from boto.ec2.networkinterface import ( NetworkInterfaceCollection, NetworkInterfaceSpecification, ) HAS_BOTO = True except ImportError: HAS_BOTO = False log = logging.getLogger(__name__) def __virtual__(): """ Only load if boto libraries exist and if boto libraries are greater than a given version. """ # the boto_ec2 execution module relies on the connect_to_region() method # which was added in boto 2.8.0 # https://github.com/boto/boto/commit/33ac26b416fbb48a60602542b4ce15dcc7029f12 has_boto_reqs = salt.utils.versions.check_boto_reqs( boto_ver="2.8.0", check_boto3=False ) if has_boto_reqs is True: __utils__["boto.assign_funcs"](__name__, "ec2", pack=__salt__) return has_boto_reqs def __init__(opts): if HAS_BOTO: __utils__["boto.assign_funcs"](__name__, "ec2") def _get_all_eip_addresses( addresses=None, allocation_ids=None, region=None, key=None, keyid=None, profile=None ): """ Get all EIP's associated with the current credentials. addresses (list) - Optional list of addresses. If provided, only those those in the list will be returned. allocation_ids (list) - Optional list of allocation IDs. If provided, only the addresses associated with the given allocation IDs will be returned. returns (list) - The requested Addresses as a list of :class:`boto.ec2.address.Address` """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: return conn.get_all_addresses( addresses=addresses, allocation_ids=allocation_ids ) except boto.exception.BotoServerError as e: log.error(e) return [] def get_all_eip_addresses( addresses=None, allocation_ids=None, region=None, key=None, keyid=None, profile=None ): """ Get public addresses of some, or all EIPs associated with the current account. addresses (list) - Optional list of addresses. If provided, only the addresses associated with those in the list will be returned. allocation_ids (list) - Optional list of allocation IDs. If provided, only the addresses associated with the given allocation IDs will be returned. returns (list) - A list of the requested EIP addresses CLI Example: .. code-block:: bash salt-call boto_ec2.get_all_eip_addresses .. versionadded:: 2016.3.0 """ return [ x.public_ip for x in _get_all_eip_addresses( addresses, allocation_ids, region, key, keyid, profile ) ] def get_unassociated_eip_address( domain="standard", region=None, key=None, keyid=None, profile=None ): """ Return the first unassociated EIP domain Indicates whether the address is an EC2 address or a VPC address (standard|vpc). CLI Example: .. code-block:: bash salt-call boto_ec2.get_unassociated_eip_address .. versionadded:: 2016.3.0 """ eip = None for address in get_all_eip_addresses( region=region, key=key, keyid=keyid, profile=profile ): address_info = get_eip_address_info( addresses=address, region=region, key=key, keyid=keyid, profile=profile )[0] if address_info["instance_id"]: log.debug( "%s is already associated with the instance %s", address, address_info["instance_id"], ) continue if address_info["network_interface_id"]: log.debug( "%s is already associated with the network interface %s", address, address_info["network_interface_id"], ) continue if address_info["domain"] == domain: log.debug( "The first unassociated EIP address in the domain '%s' is %s", domain, address, ) eip = address break if not eip: log.debug("No unassociated Elastic IP found!") return eip def get_eip_address_info( addresses=None, allocation_ids=None, region=None, key=None, keyid=None, profile=None ): """ Get 'interesting' info about some, or all EIPs associated with the current account. addresses (list) - Optional list of addresses. If provided, only the addresses associated with those in the list will be returned. allocation_ids (list) - Optional list of allocation IDs. If provided, only the addresses associated with the given allocation IDs will be returned. returns (list of dicts) - A list of dicts, each containing the info for one of the requested EIPs. CLI Example: .. code-block:: bash salt-call boto_ec2.get_eip_address_info addresses=52.4.2.15 .. versionadded:: 2016.3.0 """ if isinstance(addresses, str): addresses = [addresses] if isinstance(allocation_ids, str): allocation_ids = [allocation_ids] ret = _get_all_eip_addresses( addresses=addresses, allocation_ids=allocation_ids, region=region, key=key, keyid=keyid, profile=profile, ) interesting = [ "allocation_id", "association_id", "domain", "instance_id", "network_interface_id", "network_interface_owner_id", "public_ip", "private_ip_address", ] return [{x: getattr(address, x) for x in interesting} for address in ret] def allocate_eip_address(domain=None, region=None, key=None, keyid=None, profile=None): """ Allocate a new Elastic IP address and associate it with your account. domain (string) Optional param - if set to exactly 'vpc', the address will be allocated to the VPC. The default simply maps the EIP to your account container. returns (dict) dict of 'interesting' information about the newly allocated EIP, with probably the most interesting keys being 'public_ip'; and 'allocation_id' iff 'domain=vpc' was passed. CLI Example: .. code-block:: bash salt-call boto_ec2.allocate_eip_address domain=vpc .. versionadded:: 2016.3.0 """ if domain and domain != "vpc": raise SaltInvocationError( "The only permitted value for the 'domain' param is 'vpc'." ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: address = conn.allocate_address(domain=domain) except boto.exception.BotoServerError as e: log.error(e) return False interesting = [ "allocation_id", "association_id", "domain", "instance_id", "network_interface_id", "network_interface_owner_id", "public_ip", "private_ip_address", ] return {x: getattr(address, x) for x in interesting} def release_eip_address( public_ip=None, allocation_id=None, region=None, key=None, keyid=None, profile=None ): """ Free an Elastic IP address. Pass either a public IP address to release an EC2 Classic EIP, or an AllocationId to release a VPC EIP. public_ip (string) - The public IP address - for EC2 elastic IPs. allocation_id (string) - The Allocation ID - for VPC elastic IPs. returns (bool) - True on success, False on failure CLI Example: .. code-block:: bash salt myminion boto_ec2.release_eip_address allocation_id=eipalloc-ef382c8a .. versionadded:: 2016.3.0 """ if not salt.utils.data.exactly_one((public_ip, allocation_id)): raise SaltInvocationError( "Exactly one of 'public_ip' OR 'allocation_id' must be provided" ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: return conn.release_address(public_ip, allocation_id) except boto.exception.BotoServerError as e: log.error(e) return False def associate_eip_address( instance_id=None, instance_name=None, public_ip=None, allocation_id=None, network_interface_id=None, network_interface_name=None, private_ip_address=None, allow_reassociation=False, region=None, key=None, keyid=None, profile=None, ): """ Associate an Elastic IP address with a currently running instance or a network interface. This requires exactly one of either 'public_ip' or 'allocation_id', depending on whether you’re associating a VPC address or a plain EC2 address. instance_id (string) – ID of the instance to associate with (exclusive with 'instance_name') instance_name (string) – Name tag of the instance to associate with (exclusive with 'instance_id') public_ip (string) – Public IP address, for standard EC2 based allocations. allocation_id (string) – Allocation ID for a VPC-based EIP. network_interface_id (string) - ID of the network interface to associate the EIP with network_interface_name (string) - Name of the network interface to associate the EIP with private_ip_address (string) – The primary or secondary private IP address to associate with the Elastic IP address. allow_reassociation (bool) – Allow a currently associated EIP to be re-associated with the new instance or interface. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt myminion boto_ec2.associate_eip_address instance_name=bubba.ho.tep allocation_id=eipalloc-ef382c8a .. versionadded:: 2016.3.0 """ if not salt.utils.data.exactly_one( (instance_id, instance_name, network_interface_id, network_interface_name) ): raise SaltInvocationError( "Exactly one of 'instance_id', " "'instance_name', 'network_interface_id', " "'network_interface_name' must be provided" ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) if instance_name: try: instance_id = get_id( name=instance_name, region=region, key=key, keyid=keyid, profile=profile ) except boto.exception.BotoServerError as e: log.error(e) return False if not instance_id: log.error( "Given instance_name '%s' cannot be mapped to an instance_id", instance_name, ) return False if network_interface_name: try: network_interface_id = get_network_interface_id( network_interface_name, region=region, key=key, keyid=keyid, profile=profile, ) except boto.exception.BotoServerError as e: log.error(e) return False if not network_interface_id: log.error( "Given network_interface_name '%s' cannot be mapped to " "an network_interface_id", network_interface_name, ) return False try: return conn.associate_address( instance_id=instance_id, public_ip=public_ip, allocation_id=allocation_id, network_interface_id=network_interface_id, private_ip_address=private_ip_address, allow_reassociation=allow_reassociation, ) except boto.exception.BotoServerError as e: log.error(e) return False def disassociate_eip_address( public_ip=None, association_id=None, region=None, key=None, keyid=None, profile=None ): """ Disassociate an Elastic IP address from a currently running instance. This requires exactly one of either 'association_id' or 'public_ip', depending on whether you’re dealing with a VPC or EC2 Classic address. public_ip (string) – Public IP address, for EC2 Classic allocations. association_id (string) – Association ID for a VPC-bound EIP. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt myminion boto_ec2.disassociate_eip_address association_id=eipassoc-e3ba2d16 .. versionadded:: 2016.3.0 """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: return conn.disassociate_address(public_ip, association_id) except boto.exception.BotoServerError as e: log.error(e) return False def assign_private_ip_addresses( network_interface_name=None, network_interface_id=None, private_ip_addresses=None, secondary_private_ip_address_count=None, allow_reassignment=False, region=None, key=None, keyid=None, profile=None, ): """ Assigns one or more secondary private IP addresses to a network interface. network_interface_id (string) - ID of the network interface to associate the IP with (exclusive with 'network_interface_name') network_interface_name (string) - Name of the network interface to associate the IP with (exclusive with 'network_interface_id') private_ip_addresses (list) - Assigns the specified IP addresses as secondary IP addresses to the network interface (exclusive with 'secondary_private_ip_address_count') secondary_private_ip_address_count (int) - The number of secondary IP addresses to assign to the network interface. (exclusive with 'private_ip_addresses') allow_reassociation (bool) – Allow a currently associated EIP to be re-associated with the new instance or interface. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt myminion boto_ec2.assign_private_ip_addresses network_interface_name=my_eni private_ip_addresses=private_ip salt myminion boto_ec2.assign_private_ip_addresses network_interface_name=my_eni secondary_private_ip_address_count=2 .. versionadded:: 2017.7.0 """ if not salt.utils.data.exactly_one((network_interface_name, network_interface_id)): raise SaltInvocationError( "Exactly one of 'network_interface_name', " "'network_interface_id' must be provided" ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) if network_interface_name: try: network_interface_id = get_network_interface_id( network_interface_name, region=region, key=key, keyid=keyid, profile=profile, ) except boto.exception.BotoServerError as e: log.error(e) return False if not network_interface_id: log.error( "Given network_interface_name '%s' cannot be mapped to " "an network_interface_id", network_interface_name, ) return False try: return conn.assign_private_ip_addresses( network_interface_id=network_interface_id, private_ip_addresses=private_ip_addresses, secondary_private_ip_address_count=secondary_private_ip_address_count, allow_reassignment=allow_reassignment, ) except boto.exception.BotoServerError as e: log.error(e) return False def unassign_private_ip_addresses( network_interface_name=None, network_interface_id=None, private_ip_addresses=None, region=None, key=None, keyid=None, profile=None, ): """ Unassigns one or more secondary private IP addresses from a network interface network_interface_id (string) - ID of the network interface to associate the IP with (exclusive with 'network_interface_name') network_interface_name (string) - Name of the network interface to associate the IP with (exclusive with 'network_interface_id') private_ip_addresses (list) - Assigns the specified IP addresses as secondary IP addresses to the network interface. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt myminion boto_ec2.unassign_private_ip_addresses network_interface_name=my_eni private_ip_addresses=private_ip .. versionadded:: 2017.7.0 """ if not salt.utils.data.exactly_one((network_interface_name, network_interface_id)): raise SaltInvocationError( "Exactly one of 'network_interface_name', " "'network_interface_id' must be provided" ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) if network_interface_name: try: network_interface_id = get_network_interface_id( network_interface_name, region=region, key=key, keyid=keyid, profile=profile, ) except boto.exception.BotoServerError as e: log.error(e) return False if not network_interface_id: log.error( "Given network_interface_name '%s' cannot be mapped to " "an network_interface_id", network_interface_name, ) return False try: return conn.unassign_private_ip_addresses( network_interface_id=network_interface_id, private_ip_addresses=private_ip_addresses, ) except boto.exception.BotoServerError as e: log.error(e) return False def get_zones(region=None, key=None, keyid=None, profile=None): """ Get a list of AZs for the configured region. CLI Example: .. code-block:: bash salt myminion boto_ec2.get_zones """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) return [z.name for z in conn.get_all_zones()] def find_instances( instance_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None, return_objs=False, in_states=None, filters=None, ): """ Given instance properties, find and return matching instance ids CLI Examples: .. code-block:: bash salt myminion boto_ec2.find_instances # Lists all instances salt myminion boto_ec2.find_instances name=myinstance salt myminion boto_ec2.find_instances tags='{"mytag": "value"}' salt myminion boto_ec2.find_instances filters='{"vpc-id": "vpc-12345678"}' """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: filter_parameters = {"filters": {}} if instance_id: filter_parameters["instance_ids"] = [instance_id] if name: filter_parameters["filters"]["tag:Name"] = name if tags: for tag_name, tag_value in tags.items(): filter_parameters["filters"]["tag:{}".format(tag_name)] = tag_value if filters: filter_parameters["filters"].update(filters) reservations = conn.get_all_reservations(**filter_parameters) instances = [i for r in reservations for i in r.instances] log.debug( "The filters criteria %s matched the following instances:%s", filter_parameters, instances, ) if in_states: instances = [i for i in instances if i.state in in_states] log.debug( "Limiting instance matches to those in the requested states: %s", instances, ) if instances: if return_objs: return instances return [instance.id for instance in instances] else: return [] except boto.exception.BotoServerError as exc: log.error(exc) return [] def create_image( ami_name, instance_id=None, instance_name=None, tags=None, region=None, key=None, keyid=None, profile=None, description=None, no_reboot=False, dry_run=False, filters=None, ): """ Given instance properties that define exactly one instance, create AMI and return AMI-id. CLI Examples: .. code-block:: bash salt myminion boto_ec2.create_image ami_name instance_name=myinstance salt myminion boto_ec2.create_image another_ami_name tags='{"mytag": "value"}' description='this is my ami' """ instances = find_instances( instance_id=instance_id, name=instance_name, tags=tags, region=region, key=key, keyid=keyid, profile=profile, return_objs=True, filters=filters, ) if not instances: log.error("Source instance not found") return False if len(instances) > 1: log.error( "Multiple instances found, must match exactly only one instance to create" " an image from" ) return False instance = instances[0] try: return instance.create_image( ami_name, description=description, no_reboot=no_reboot, dry_run=dry_run ) except boto.exception.BotoServerError as exc: log.error(exc) return False def find_images( ami_name=None, executable_by=None, owners=None, image_ids=None, tags=None, region=None, key=None, keyid=None, profile=None, return_objs=False, ): """ Given image properties, find and return matching AMI ids CLI Examples: .. code-block:: bash salt myminion boto_ec2.find_images tags='{"mytag": "value"}' """ retries = 30 conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) while retries: try: filter_parameters = {"filters": {}} if image_ids: filter_parameters["image_ids"] = [image_ids] if executable_by: filter_parameters["executable_by"] = [executable_by] if owners: filter_parameters["owners"] = [owners] if ami_name: filter_parameters["filters"]["name"] = ami_name if tags: for tag_name, tag_value in tags.items(): filter_parameters["filters"]["tag:{}".format(tag_name)] = tag_value images = conn.get_all_images(**filter_parameters) log.debug( "The filters criteria %s matched the following images:%s", filter_parameters, images, ) if images: if return_objs: return images return [image.id for image in images] else: return False except boto.exception.BotoServerError as exc: if exc.error_code == "Throttling": log.debug("Throttled by AWS API, will retry in 5 seconds...") time.sleep(5) retries -= 1 continue log.error("Failed to convert AMI name `%s` to an AMI ID: %s", ami_name, exc) return False return False def terminate( instance_id=None, name=None, region=None, key=None, keyid=None, profile=None, filters=None, ): """ Terminate the instance described by instance_id or name. CLI Example: .. code-block:: bash salt myminion boto_ec2.terminate name=myinstance salt myminion boto_ec2.terminate instance_id=i-a46b9f """ instances = find_instances( instance_id=instance_id, name=name, region=region, key=key, keyid=keyid, profile=profile, return_objs=True, filters=filters, ) if instances in (False, None, []): return instances if len(instances) == 1: instances[0].terminate() return True else: log.warning("Refusing to terminate multiple instances at once") return False def get_id( name=None, tags=None, region=None, key=None, keyid=None, profile=None, in_states=None, filters=None, ): """ Given instance properties, return the instance id if it exists. CLI Example: .. code-block:: bash salt myminion boto_ec2.get_id myinstance """ instance_ids = find_instances( name=name, tags=tags, region=region, key=key, keyid=keyid, profile=profile, in_states=in_states, filters=filters, ) if instance_ids: log.info("Instance ids: %s", " ".join(instance_ids)) if len(instance_ids) == 1: return instance_ids[0] else: raise CommandExecutionError( "Found more than one instance matching the criteria." ) else: log.warning("Could not find instance.") return None def get_tags(instance_id=None, keyid=None, key=None, profile=None, region=None): """ Given an instance_id, return a list of tags associated with that instance. returns (list) - list of tags as key/value pairs CLI Example: .. code-block:: bash salt myminion boto_ec2.get_tags instance_id """ tags = [] client = _get_conn(key=key, keyid=keyid, profile=profile, region=region) result = client.get_all_tags(filters={"resource-id": instance_id}) if result: for tag in result: tags.append({tag.name: tag.value}) else: log.info("No tags found for instance_id %s", instance_id) return tags def exists( instance_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None, in_states=None, filters=None, ): """ Given an instance id, check to see if the given instance id exists. Returns True if the given instance with the given id, name, or tags exists; otherwise, False is returned. CLI Example: .. code-block:: bash salt myminion boto_ec2.exists myinstance """ instances = find_instances( instance_id=instance_id, name=name, tags=tags, region=region, key=key, keyid=keyid, profile=profile, in_states=in_states, filters=filters, ) if instances: log.info("Instance exists.") return True else: log.warning("Instance does not exist.") return False def _to_blockdev_map(thing): """ Convert a string, or a json payload, or a dict in the right format, into a boto.ec2.blockdevicemapping.BlockDeviceMapping as needed by instance_present(). The following YAML is a direct representation of what is expected by the underlying boto EC2 code. YAML example: .. code-block:: yaml device-maps: /dev/sdb: ephemeral_name: ephemeral0 /dev/sdc: ephemeral_name: ephemeral1 /dev/sdd: ephemeral_name: ephemeral2 /dev/sde: ephemeral_name: ephemeral3 /dev/sdf: size: 20 volume_type: gp2 """ if not thing: return None if isinstance(thing, BlockDeviceMapping): return thing if isinstance(thing, str): thing = salt.utils.json.loads(thing) if not isinstance(thing, dict): log.error( "Can't convert '%s' of type %s to a " "boto.ec2.blockdevicemapping.BlockDeviceMapping", thing, type(thing), ) return None bdm = BlockDeviceMapping() for d, t in thing.items(): bdt = BlockDeviceType( ephemeral_name=t.get("ephemeral_name"), no_device=t.get("no_device", False), volume_id=t.get("volume_id"), snapshot_id=t.get("snapshot_id"), status=t.get("status"), attach_time=t.get("attach_time"), delete_on_termination=t.get("delete_on_termination", False), size=t.get("size"), volume_type=t.get("volume_type"), iops=t.get("iops"), encrypted=t.get("encrypted"), ) bdm[d] = bdt return bdm def run( image_id, name=None, tags=None, key_name=None, security_groups=None, user_data=None, instance_type="m1.small", placement=None, kernel_id=None, ramdisk_id=None, monitoring_enabled=None, vpc_id=None, vpc_name=None, subnet_id=None, subnet_name=None, private_ip_address=None, block_device_map=None, disable_api_termination=None, instance_initiated_shutdown_behavior=None, placement_group=None, client_token=None, security_group_ids=None, security_group_names=None, additional_info=None, tenancy=None, instance_profile_arn=None, instance_profile_name=None, ebs_optimized=None, network_interface_id=None, network_interface_name=None, region=None, key=None, keyid=None, profile=None, network_interfaces=None, ): # TODO: support multi-instance reservations """ Create and start an EC2 instance. Returns True if the instance was created; otherwise False. CLI Example: .. code-block:: bash salt myminion boto_ec2.run ami-b80c2b87 name=myinstance image_id (string) – The ID of the image to run. name (string) - The name of the instance. tags (dict of key: value pairs) - tags to apply to the instance. key_name (string) – The name of the key pair with which to launch instances. security_groups (list of strings) – The names of the EC2 classic security groups with which to associate instances user_data (string) – The Base64-encoded MIME user data to be made available to the instance(s) in this reservation. instance_type (string) – The type of instance to run. Note that some image types (e.g. hvm) only run on some instance types. placement (string) – The Availability Zone to launch the instance into. kernel_id (string) – The ID of the kernel with which to launch the instances. ramdisk_id (string) – The ID of the RAM disk with which to launch the instances. monitoring_enabled (bool) – Enable detailed CloudWatch monitoring on the instance. vpc_id (string) - ID of a VPC to bind the instance to. Exclusive with vpc_name. vpc_name (string) - Name of a VPC to bind the instance to. Exclusive with vpc_id. subnet_id (string) – The subnet ID within which to launch the instances for VPC. subnet_name (string) – The name of a subnet within which to launch the instances for VPC. private_ip_address (string) – If you’re using VPC, you can optionally use this parameter to assign the instance a specific available IP address from the subnet (e.g. 10.0.0.25). block_device_map (boto.ec2.blockdevicemapping.BlockDeviceMapping) – A BlockDeviceMapping data structure describing the EBS volumes associated with the Image. (string) - A string representation of a BlockDeviceMapping structure (dict) - A dict describing a BlockDeviceMapping structure YAML example: .. code-block:: yaml device-maps: /dev/sdb: ephemeral_name: ephemeral0 /dev/sdc: ephemeral_name: ephemeral1 /dev/sdd: ephemeral_name: ephemeral2 /dev/sde: ephemeral_name: ephemeral3 /dev/sdf: size: 20 volume_type: gp2 disable_api_termination (bool) – If True, the instances will be locked and will not be able to be terminated via the API. instance_initiated_shutdown_behavior (string) – Specifies whether the instance stops or terminates on instance-initiated shutdown. Valid values are: stop, terminate placement_group (string) – If specified, this is the name of the placement group in which the instance(s) will be launched. client_token (string) – Unique, case-sensitive identifier you provide to ensure idempotency of the request. Maximum 64 ASCII characters. security_group_ids (list of strings) – The ID(s) of the VPC security groups with which to associate instances. security_group_names (list of strings) – The name(s) of the VPC security groups with which to associate instances. additional_info (string) – Specifies additional information to make available to the instance(s). tenancy (string) – The tenancy of the instance you want to launch. An instance with a tenancy of ‘dedicated’ runs on single-tenant hardware and can only be launched into a VPC. Valid values are:”default” or “dedicated”. NOTE: To use dedicated tenancy you MUST specify a VPC subnet-ID as well. instance_profile_arn (string) – The Amazon resource name (ARN) of the IAM Instance Profile (IIP) to associate with the instances. instance_profile_name (string) – The name of the IAM Instance Profile (IIP) to associate with the instances. ebs_optimized (bool) – Whether the instance is optimized for EBS I/O. This optimization provides dedicated throughput to Amazon EBS and an optimized configuration stack to provide optimal EBS I/O performance. This optimization isn’t available with all instance types. network_interfaces (boto.ec2.networkinterface.NetworkInterfaceCollection) – A NetworkInterfaceCollection data structure containing the ENI specifications for the instance. network_interface_id (string) - ID of the network interface to attach to the instance network_interface_name (string) - Name of the network interface to attach to the instance """ if all((subnet_id, subnet_name)): raise SaltInvocationError( "Only one of subnet_name or subnet_id may be provided." ) if subnet_name: r = __salt__["boto_vpc.get_resource_id"]( "subnet", subnet_name, region=region, key=key, keyid=keyid, profile=profile ) if "id" not in r: log.warning("Couldn't resolve subnet name %s.", subnet_name) return False subnet_id = r["id"] if all((security_group_ids, security_group_names)): raise SaltInvocationError( "Only one of security_group_ids or security_group_names may be provided." ) if security_group_names: security_group_ids = [] for sgn in security_group_names: r = __salt__["boto_secgroup.get_group_id"]( sgn, vpc_name=vpc_name, region=region, key=key, keyid=keyid, profile=profile, ) if not r: log.warning("Couldn't resolve security group name %s", sgn) return False security_group_ids += [r] network_interface_args = list( map( int, [ network_interface_id is not None, network_interface_name is not None, network_interfaces is not None, ], ) ) if sum(network_interface_args) > 1: raise SaltInvocationError( "Only one of network_interface_id, " "network_interface_name or " "network_interfaces may be provided." ) if network_interface_name: result = get_network_interface_id( network_interface_name, region=region, key=key, keyid=keyid, profile=profile ) network_interface_id = result["result"] if not network_interface_id: log.warning( "Given network_interface_name '%s' cannot be mapped to an " "network_interface_id", network_interface_name, ) if network_interface_id: interface = NetworkInterfaceSpecification( network_interface_id=network_interface_id, device_index=0 ) else: interface = NetworkInterfaceSpecification( subnet_id=subnet_id, groups=security_group_ids, device_index=0 ) if network_interfaces: interfaces_specs = [ NetworkInterfaceSpecification(**x) for x in network_interfaces ] interfaces = NetworkInterfaceCollection(*interfaces_specs) else: interfaces = NetworkInterfaceCollection(interface) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) reservation = conn.run_instances( image_id, key_name=key_name, security_groups=security_groups, user_data=user_data, instance_type=instance_type, placement=placement, kernel_id=kernel_id, ramdisk_id=ramdisk_id, monitoring_enabled=monitoring_enabled, private_ip_address=private_ip_address, block_device_map=_to_blockdev_map(block_device_map), disable_api_termination=disable_api_termination, instance_initiated_shutdown_behavior=instance_initiated_shutdown_behavior, placement_group=placement_group, client_token=client_token, additional_info=additional_info, tenancy=tenancy, instance_profile_arn=instance_profile_arn, instance_profile_name=instance_profile_name, ebs_optimized=ebs_optimized, network_interfaces=interfaces, ) if not reservation: log.warning("Instance could not be reserved") return False instance = reservation.instances[0] status = "pending" while status == "pending": time.sleep(5) status = instance.update() if status == "running": if name: instance.add_tag("Name", name) if tags: instance.add_tags(tags) return {"instance_id": instance.id} else: log.warning('Instance could not be started -- status is "%s"', status) def get_key(key_name, region=None, key=None, keyid=None, profile=None): """ Check to see if a key exists. Returns fingerprint and name if it does and False if it doesn't CLI Example: .. code-block:: bash salt myminion boto_ec2.get_key mykey """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: key = conn.get_key_pair(key_name) log.debug("the key to return is : %s", key) if key is None: return False return key.name, key.fingerprint except boto.exception.BotoServerError as e: log.debug(e) return False def create_key(key_name, save_path, region=None, key=None, keyid=None, profile=None): """ Creates a key and saves it to a given path. Returns the private key. CLI Example: .. code-block:: bash salt myminion boto_ec2.create_key mykey /root/ """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: key = conn.create_key_pair(key_name) log.debug("the key to return is : %s", key) key.save(save_path) return key.material except boto.exception.BotoServerError as e: log.debug(e) return False def import_key( key_name, public_key_material, region=None, key=None, keyid=None, profile=None ): """ Imports the public key from an RSA key pair that you created with a third-party tool. Supported formats: - OpenSSH public key format (e.g., the format in ~/.ssh/authorized_keys) - Base64 encoded DER format - SSH public key file format as specified in RFC4716 - DSA keys are not supported. Make sure your key generator is set up to create RSA keys. Supported lengths: 1024, 2048, and 4096. CLI Example: .. code-block:: bash salt myminion boto_ec2.import mykey publickey """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: key = conn.import_key_pair(key_name, public_key_material) log.debug("the key to return is : %s", key) return key.fingerprint except boto.exception.BotoServerError as e: log.debug(e) return False def delete_key(key_name, region=None, key=None, keyid=None, profile=None): """ Deletes a key. Always returns True CLI Example: .. code-block:: bash salt myminion boto_ec2.delete_key mykey """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: key = conn.delete_key_pair(key_name) log.debug("the key to return is : %s", key) return key except boto.exception.BotoServerError as e: log.debug(e) return False def get_keys( keynames=None, filters=None, region=None, key=None, keyid=None, profile=None ): """ Gets all keys or filters them by name and returns a list. keynames (list):: A list of the names of keypairs to retrieve. If not provided, all key pairs will be returned. filters (dict) :: Optional filters that can be used to limit the results returned. Filters are provided in the form of a dictionary consisting of filter names as the key and filter values as the value. The set of allowable filter names/values is dependent on the request being performed. Check the EC2 API guide for details. CLI Example: .. code-block:: bash salt myminion boto_ec2.get_keys """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: keys = conn.get_all_key_pairs(keynames, filters) log.debug("the key to return is : %s", keys) key_values = [] if keys: for key in keys: key_values.append(key.name) return key_values except boto.exception.BotoServerError as e: log.debug(e) return False def get_attribute( attribute, instance_name=None, instance_id=None, region=None, key=None, keyid=None, profile=None, filters=None, ): """ Get an EC2 instance attribute. CLI Example: .. code-block:: bash salt myminion boto_ec2.get_attribute sourceDestCheck instance_name=my_instance Available attributes: * instanceType * kernel * ramdisk * userData * disableApiTermination * instanceInitiatedShutdownBehavior * rootDeviceName * blockDeviceMapping * productCodes * sourceDestCheck * groupSet * ebsOptimized * sriovNetSupport """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) attribute_list = [ "instanceType", "kernel", "ramdisk", "userData", "disableApiTermination", "instanceInitiatedShutdownBehavior", "rootDeviceName", "blockDeviceMapping", "productCodes", "sourceDestCheck", "groupSet", "ebsOptimized", "sriovNetSupport", ] if not any((instance_name, instance_id)): raise SaltInvocationError( "At least one of the following must be specified: " "instance_name or instance_id." ) if instance_name and instance_id: raise SaltInvocationError( "Both instance_name and instance_id can not be specified in the same" " command." ) if attribute not in attribute_list: raise SaltInvocationError( "Attribute must be one of: {}.".format(attribute_list) ) try: if instance_name: instances = find_instances( name=instance_name, region=region, key=key, keyid=keyid, profile=profile, filters=filters, ) if len(instances) > 1: log.error("Found more than one EC2 instance matching the criteria.") return False elif not instances: log.error("Found no EC2 instance matching the criteria.") return False instance_id = instances[0] instance_attribute = conn.get_instance_attribute(instance_id, attribute) if not instance_attribute: return False return {attribute: instance_attribute[attribute]} except boto.exception.BotoServerError as exc: log.error(exc) return False def set_attribute( attribute, attribute_value, instance_name=None, instance_id=None, region=None, key=None, keyid=None, profile=None, filters=None, ): """ Set an EC2 instance attribute. Returns whether the operation succeeded or not. CLI Example: .. code-block:: bash salt myminion boto_ec2.set_attribute sourceDestCheck False instance_name=my_instance Available attributes: * instanceType * kernel * ramdisk * userData * disableApiTermination * instanceInitiatedShutdownBehavior * rootDeviceName * blockDeviceMapping * productCodes * sourceDestCheck * groupSet * ebsOptimized * sriovNetSupport """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) attribute_list = [ "instanceType", "kernel", "ramdisk", "userData", "disableApiTermination", "instanceInitiatedShutdownBehavior", "rootDeviceName", "blockDeviceMapping", "productCodes", "sourceDestCheck", "groupSet", "ebsOptimized", "sriovNetSupport", ] if not any((instance_name, instance_id)): raise SaltInvocationError( "At least one of the following must be specified: instance_name or" " instance_id." ) if instance_name and instance_id: raise SaltInvocationError( "Both instance_name and instance_id can not be specified in the same" " command." ) if attribute not in attribute_list: raise SaltInvocationError( "Attribute must be one of: {}.".format(attribute_list) ) try: if instance_name: instances = find_instances( name=instance_name, region=region, key=key, keyid=keyid, profile=profile, filters=filters, ) if len(instances) != 1: raise CommandExecutionError( "Found more than one EC2 instance matching the criteria." ) instance_id = instances[0] attribute = conn.modify_instance_attribute( instance_id, attribute, attribute_value ) if not attribute: return False return attribute except boto.exception.BotoServerError as exc: log.error(exc) return False def get_network_interface_id(name, region=None, key=None, keyid=None, profile=None): """ Get an Elastic Network Interface id from its name tag. .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt myminion boto_ec2.get_network_interface_id name=my_eni """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) r = {} try: enis = conn.get_all_network_interfaces(filters={"tag:Name": name}) if not enis: r["error"] = {"message": "No ENIs found."} elif len(enis) > 1: r["error"] = {"message": "Name specified is tagged on multiple ENIs."} else: eni = enis[0] r["result"] = eni.id except boto.exception.EC2ResponseError as e: r["error"] = __utils__["boto.get_error"](e) return r def get_network_interface( name=None, network_interface_id=None, region=None, key=None, keyid=None, profile=None, ): """ Get an Elastic Network Interface. .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt myminion boto_ec2.get_network_interface name=my_eni """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) r = {} result = _get_network_interface(conn, name, network_interface_id) if "error" in result: if result["error"]["message"] == "No ENIs found.": r["result"] = None return r return result eni = result["result"] r["result"] = _describe_network_interface(eni) return r def _get_network_interface(conn, name=None, network_interface_id=None): r = {} if not (name or network_interface_id): raise SaltInvocationError( "Either name or network_interface_id must be provided." ) try: if network_interface_id: enis = conn.get_all_network_interfaces([network_interface_id]) else: enis = conn.get_all_network_interfaces(filters={"tag:Name": name}) if not enis: r["error"] = {"message": "No ENIs found."} elif len(enis) > 1: r["error"] = {"message": "Name specified is tagged on multiple ENIs."} else: eni = enis[0] r["result"] = eni except boto.exception.EC2ResponseError as e: r["error"] = __utils__["boto.get_error"](e) return r def _describe_network_interface(eni): r = {} for attr in [ "status", "description", "availability_zone", "requesterId", "requester_managed", "mac_address", "private_ip_address", "vpc_id", "id", "source_dest_check", "owner_id", "tags", "subnet_id", "associationId", "publicDnsName", "owner_id", "ipOwnerId", "publicIp", "allocationId", ]: if hasattr(eni, attr): r[attr] = getattr(eni, attr) r["region"] = eni.region.name r["groups"] = [] for group in eni.groups: r["groups"].append({"name": group.name, "id": group.id}) r["private_ip_addresses"] = [] for address in eni.private_ip_addresses: r["private_ip_addresses"].append( { "private_ip_address": address.private_ip_address, "primary": address.primary, } ) r["attachment"] = {} for attr in [ "status", "attach_time", "device_index", "delete_on_termination", "instance_id", "instance_owner_id", "id", ]: if hasattr(eni.attachment, attr): r["attachment"][attr] = getattr(eni.attachment, attr) return r def create_network_interface( name, subnet_id=None, subnet_name=None, private_ip_address=None, description=None, groups=None, region=None, key=None, keyid=None, profile=None, ): """ Create an Elastic Network Interface. .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt myminion boto_ec2.create_network_interface my_eni subnet-12345 description=my_eni groups=['my_group'] """ if not salt.utils.data.exactly_one((subnet_id, subnet_name)): raise SaltInvocationError( "One (but not both) of subnet_id or subnet_name must be provided." ) if subnet_name: resource = __salt__["boto_vpc.get_resource_id"]( "subnet", subnet_name, region=region, key=key, keyid=keyid, profile=profile ) if "id" not in resource: log.warning("Couldn't resolve subnet name %s.", subnet_name) return False subnet_id = resource["id"] conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) r = {} result = _get_network_interface(conn, name) if "result" in result: r["error"] = {"message": "An ENI with this Name tag already exists."} return r vpc_id = __salt__["boto_vpc.get_subnet_association"]( [subnet_id], region=region, key=key, keyid=keyid, profile=profile ) vpc_id = vpc_id.get("vpc_id") if not vpc_id: msg = "subnet_id {} does not map to a valid vpc id.".format(subnet_id) r["error"] = {"message": msg} return r _groups = __salt__["boto_secgroup.convert_to_group_ids"]( groups, vpc_id=vpc_id, region=region, key=key, keyid=keyid, profile=profile ) try: eni = conn.create_network_interface( subnet_id, private_ip_address=private_ip_address, description=description, groups=_groups, ) eni.add_tag("Name", name) except boto.exception.EC2ResponseError as e: r["error"] = __utils__["boto.get_error"](e) return r r["result"] = _describe_network_interface(eni) return r def delete_network_interface( name=None, network_interface_id=None, region=None, key=None, keyid=None, profile=None, ): """ Create an Elastic Network Interface. .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt myminion boto_ec2.create_network_interface my_eni subnet-12345 description=my_eni groups=['my_group'] """ if not (name or network_interface_id): raise SaltInvocationError( "Either name or network_interface_id must be provided." ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) r = {} result = _get_network_interface(conn, name, network_interface_id) if "error" in result: return result eni = result["result"] try: info = _describe_network_interface(eni) network_interface_id = info["id"] except KeyError: r["error"] = {"message": "ID not found for this network interface."} return r try: r["result"] = conn.delete_network_interface(network_interface_id) except boto.exception.EC2ResponseError as e: r["error"] = __utils__["boto.get_error"](e) return r def attach_network_interface( device_index, name=None, network_interface_id=None, instance_name=None, instance_id=None, region=None, key=None, keyid=None, profile=None, ): """ Attach an Elastic Network Interface. .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt myminion boto_ec2.attach_network_interface my_eni instance_name=salt-master device_index=0 """ if not salt.utils.data.exactly_one((name, network_interface_id)): raise SaltInvocationError( "Exactly one (but not both) of 'name' or 'network_interface_id' " "must be provided." ) if not salt.utils.data.exactly_one((instance_name, instance_id)): raise SaltInvocationError( "Exactly one (but not both) of 'instance_name' or 'instance_id' " "must be provided." ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) r = {} result = _get_network_interface(conn, name, network_interface_id) if "error" in result: return result eni = result["result"] try: info = _describe_network_interface(eni) network_interface_id = info["id"] except KeyError: r["error"] = {"message": "ID not found for this network interface."} return r if instance_name: try: instance_id = get_id( name=instance_name, region=region, key=key, keyid=keyid, profile=profile ) except boto.exception.BotoServerError as e: log.error(e) return False try: r["result"] = conn.attach_network_interface( network_interface_id, instance_id, device_index ) except boto.exception.EC2ResponseError as e: r["error"] = __utils__["boto.get_error"](e) return r def detach_network_interface( name=None, network_interface_id=None, attachment_id=None, force=False, region=None, key=None, keyid=None, profile=None, ): """ Detach an Elastic Network Interface. .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt myminion boto_ec2.detach_network_interface my_eni """ if not (name or network_interface_id or attachment_id): raise SaltInvocationError( "Either name or network_interface_id or attachment_id must be provided." ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) r = {} if not attachment_id: result = _get_network_interface(conn, name, network_interface_id) if "error" in result: return result eni = result["result"] info = _describe_network_interface(eni) try: attachment_id = info["attachment"]["id"] except KeyError: r["error"] = {"message": "Attachment id not found for this ENI."} return r try: r["result"] = conn.detach_network_interface(attachment_id, force) except boto.exception.EC2ResponseError as e: r["error"] = __utils__["boto.get_error"](e) return r def modify_network_interface_attribute( name=None, network_interface_id=None, attr=None, value=None, region=None, key=None, keyid=None, profile=None, ): """ Modify an attribute of an Elastic Network Interface. .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt myminion boto_ec2.modify_network_interface_attribute my_eni attr=description value='example description' """ if not (name or network_interface_id): raise SaltInvocationError( "Either name or network_interface_id must be provided." ) if attr is None and value is None: raise SaltInvocationError("attr and value must be provided.") r = {} conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) result = _get_network_interface(conn, name, network_interface_id) if "error" in result: return result eni = result["result"] info = _describe_network_interface(eni) network_interface_id = info["id"] # munge attr into what the API requires if attr == "groups": _attr = "groupSet" elif attr == "source_dest_check": _attr = "sourceDestCheck" elif attr == "delete_on_termination": _attr = "deleteOnTermination" else: _attr = attr _value = value if info.get("vpc_id") and _attr == "groupSet": _value = __salt__["boto_secgroup.convert_to_group_ids"]( value, vpc_id=info.get("vpc_id"), region=region, key=key, keyid=keyid, profile=profile, ) if not _value: r["error"] = { "message": "Security groups do not map to valid security group ids" } return r _attachment_id = None if _attr == "deleteOnTermination": try: _attachment_id = info["attachment"]["id"] except KeyError: r["error"] = { "message": ( "No attachment id found for this ENI. The ENI must" " be attached before delete_on_termination can be" " modified" ) } return r try: r["result"] = conn.modify_network_interface_attribute( network_interface_id, _attr, _value, attachment_id=_attachment_id ) except boto.exception.EC2ResponseError as e: r["error"] = __utils__["boto.get_error"](e) return r def get_all_volumes( volume_ids=None, filters=None, return_objs=False, region=None, key=None, keyid=None, profile=None, ): """ Get a list of all EBS volumes, optionally filtered by provided 'filters' param .. versionadded:: 2016.11.0 volume_ids (list) - Optional list of volume_ids. If provided, only the volumes associated with those in the list will be returned. filters (dict) - Additional constraints on which volumes to return. Valid filters are: - attachment.attach-time - The time stamp when the attachment initiated. - attachment.delete-on-termination - Whether the volume is deleted on instance termination. - attachment.device - The device name that is exposed to the instance (for example, /dev/sda1). - attachment.instance-id - The ID of the instance the volume is attached to. - attachment.status - The attachment state (attaching | attached | detaching | detached). - availability-zone - The Availability Zone in which the volume was created. - create-time - The time stamp when the volume was created. - encrypted - The encryption status of the volume. - size - The size of the volume, in GiB. - snapshot-id - The snapshot from which the volume was created. - status - The status of the volume (creating | available | in-use | deleting | deleted | error). - tag:key=value - The key/value combination of a tag assigned to the resource. - volume-id - The volume ID. - volume-type - The Amazon EBS volume type. This can be ``gp2`` for General Purpose SSD, ``io1`` for Provisioned IOPS SSD, ``st1`` for Throughput Optimized HDD, ``sc1`` for Cold HDD, or ``standard`` for Magnetic volumes. return_objs (bool) - Changes the return type from list of volume IDs to list of boto.ec2.volume.Volume objects returns (list) - A list of the requested values: Either the volume IDs or, if return_objs is ``True``, boto.ec2.volume.Volume objects. CLI Example: .. code-block:: bash salt-call boto_ec2.get_all_volumes filters='{"tag:Name": "myVolume01"}' """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: ret = conn.get_all_volumes(volume_ids=volume_ids, filters=filters) return ret if return_objs else [r.id for r in ret] except boto.exception.BotoServerError as e: log.error(e) return [] def set_volumes_tags( tag_maps, authoritative=False, dry_run=False, region=None, key=None, keyid=None, profile=None, ): """ .. versionadded:: 2016.11.0 tag_maps (list) List of dicts of filters and tags, where 'filters' is a dict suitable for passing to the 'filters' argument of get_all_volumes() above, and 'tags' is a dict of tags to be set on volumes (via create_tags/delete_tags) as matched by the given filters. The filter syntax is extended to permit passing either a list of volume_ids or an instance_name (with instance_name being the Name tag of the instance to which the desired volumes are mapped). Each mapping in the list is applied separately, so multiple sets of volumes can be all tagged differently with one call to this function. If filtering by instance Name, You may additionally limit the instances matched by passing in a list of desired instance states. The default set of states is ('pending', 'rebooting', 'running', 'stopping', 'stopped'). YAML example fragment: .. code-block:: yaml - filters: attachment.instance_id: i-abcdef12 tags: Name: dev-int-abcdef12.aws-foo.com - filters: attachment.device: /dev/sdf tags: ManagedSnapshots: true BillingGroup: bubba.hotep@aws-foo.com in_states: - stopped - terminated - filters: instance_name: prd-foo-01.aws-foo.com tags: Name: prd-foo-01.aws-foo.com BillingGroup: infra-team@aws-foo.com - filters: volume_ids: [ vol-12345689, vol-abcdef12 ] tags: BillingGroup: infra-team@aws-foo.com authoritative (bool) If true, any existing tags on the matched volumes, and not explicitly requested here, will be removed. dry_run (bool) If true, don't change anything, just return a dictionary describing any changes which would have been applied. returns (dict) A dict describing status and any changes. """ ret = {"success": True, "comment": "", "changes": {}} running_states = ("pending", "rebooting", "running", "stopping", "stopped") ### First creeate a dictionary mapping all changes for a given volume to its volume ID... tag_sets = {} for tm in tag_maps: filters = dict(tm.get("filters", {})) tags = dict(tm.get("tags", {})) args = { "return_objs": True, "region": region, "key": key, "keyid": keyid, "profile": profile, } new_filters = {} log.debug("got filters: %s", filters) instance_id = None in_states = tm.get("in_states", running_states) try: for k, v in filters.items(): if k == "volume_ids": args["volume_ids"] = v elif k == "instance_name": instance_id = get_id( name=v, in_states=in_states, region=region, key=key, keyid=keyid, profile=profile, ) if not instance_id: msg = "Couldn't resolve instance Name {} to an ID.".format(v) raise CommandExecutionError(msg) new_filters["attachment.instance_id"] = instance_id else: new_filters[k] = v except CommandExecutionError as e: log.warning(e) continue # Hmme, abort or do what we can...? Guess the latter for now. args["filters"] = new_filters volumes = get_all_volumes(**args) log.debug("got volume list: %s", volumes) for vol in volumes: tag_sets.setdefault( vol.id.replace("-", "_"), {"vol": vol, "tags": tags.copy()} )["tags"].update(tags.copy()) log.debug("tag_sets after munging: %s", tag_sets) ### ...then loop through all those volume->tag pairs and apply them. changes = {"old": {}, "new": {}} for volume in tag_sets.values(): vol, tags = volume["vol"], volume["tags"] log.debug( "current tags on vol.id %s: %s", vol.id, dict(getattr(vol, "tags", {})) ) curr = set(dict(getattr(vol, "tags", {})).keys()) log.debug("requested tags on vol.id %s: %s", vol.id, tags) req = set(tags.keys()) add = list(req - curr) update = [r for r in (req & curr) if vol.tags[r] != tags[r]] remove = list(curr - req) if add or update or (authoritative and remove): changes["old"][vol.id] = dict(getattr(vol, "tags", {})) changes["new"][vol.id] = tags else: log.debug("No changes needed for vol.id %s", vol.id) if add: d = {k: tags[k] for k in add} log.debug("New tags for vol.id %s: %s", vol.id, d) if update: d = {k: tags[k] for k in update} log.debug("Updated tags for vol.id %s: %s", vol.id, d) if not dry_run: if not create_tags( vol.id, tags, region=region, key=key, keyid=keyid, profile=profile ): ret["success"] = False ret["comment"] = "Failed to set tags on vol.id {}: {}".format( vol.id, tags ) return ret if authoritative: if remove: log.debug("Removed tags for vol.id %s: %s", vol.id, remove) if not delete_tags( vol.id, remove, region=region, key=key, keyid=keyid, profile=profile, ): ret["success"] = False ret[ "comment" ] = "Failed to remove tags on vol.id {}: {}".format( vol.id, remove ) return ret if changes["old"] or changes["new"]: ret["changes"].update(changes) return ret def get_all_tags(filters=None, region=None, key=None, keyid=None, profile=None): """ Describe all tags matching the filter criteria, or all tags in the account otherwise. .. versionadded:: 2018.3.0 filters (dict) - Additional constraints on which volumes to return. Note that valid filters vary extensively depending on the resource type. When in doubt, search first without a filter and then use the returned data to help fine-tune your search. You can generally garner the resource type from its ID (e.g. `vol-XXXXX` is a volume, `i-XXXXX` is an instance, etc. CLI Example: .. code-block:: bash salt-call boto_ec2.get_all_tags '{"tag:Name": myInstanceNameTag, resource-type: instance}' """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: ret = conn.get_all_tags(filters) tags = {} for t in ret: if t.res_id not in tags: tags[t.res_id] = {} tags[t.res_id][t.name] = t.value return tags except boto.exception.BotoServerError as e: log.error(e) return {} def create_tags(resource_ids, tags, region=None, key=None, keyid=None, profile=None): """ Create new metadata tags for the specified resource ids. .. versionadded:: 2016.11.0 resource_ids (string) or (list) – List of resource IDs. A plain string will be converted to a list of one element. tags (dict) – Dictionary of name/value pairs. To create only a tag name, pass '' as the value. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt-call boto_ec2.create_tags vol-12345678 '{"Name": "myVolume01"}' """ if not isinstance(resource_ids, list): resource_ids = [resource_ids] conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: conn.create_tags(resource_ids, tags) return True except boto.exception.BotoServerError as e: log.error(e) return False def delete_tags(resource_ids, tags, region=None, key=None, keyid=None, profile=None): """ Delete metadata tags for the specified resource ids. .. versionadded:: 2016.11.0 resource_ids (string) or (list) – List of resource IDs. A plain string will be converted to a list of one element. tags (dict) or (list) – Either a dictionary containing name/value pairs or a list containing just tag names. If you pass in a dictionary, the values must match the actual tag values or the tag will not be deleted. If you pass in a value of None for the tag value, all tags with that name will be deleted. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt-call boto_ec2.delete_tags vol-12345678 '{"Name": "myVolume01"}' salt-call boto_ec2.delete_tags vol-12345678 '["Name","MountPoint"]' """ if not isinstance(resource_ids, list): resource_ids = [resource_ids] conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: conn.delete_tags(resource_ids, tags) return True except boto.exception.BotoServerError as e: log.error(e) return False def detach_volume( volume_id, instance_id=None, device=None, force=False, wait_for_detachement=False, region=None, key=None, keyid=None, profile=None, ): """ Detach an EBS volume from an EC2 instance. .. versionadded:: 2016.11.0 volume_id (string) – The ID of the EBS volume to be detached. instance_id (string) – The ID of the EC2 instance from which it will be detached. device (string) – The device on the instance through which the volume is exposted (e.g. /dev/sdh) force (bool) – Forces detachment if the previous detachment attempt did not occur cleanly. This option can lead to data loss or a corrupted file system. Use this option only as a last resort to detach a volume from a failed instance. The instance will not have an opportunity to flush file system caches nor file system meta data. If you use this option, you must perform file system check and repair procedures. wait_for_detachement (bool) - Whether or not to wait for volume detachement to complete. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt-call boto_ec2.detach_volume vol-12345678 i-87654321 """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: ret = conn.detach_volume(volume_id, instance_id, device, force) if ( ret and wait_for_detachement and not _wait_for_volume_available(conn, volume_id) ): timeout_msg = 'Timed out waiting for the volume status "available".' log.error(timeout_msg) return False return ret except boto.exception.BotoServerError as e: log.error(e) return False def delete_volume( volume_id, instance_id=None, device=None, force=False, region=None, key=None, keyid=None, profile=None, ): """ Detach an EBS volume from an EC2 instance. .. versionadded:: 2016.11.0 volume_id (string) – The ID of the EBS volume to be deleted. force (bool) – Forces deletion even if the device has not yet been detached from its instance. returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt-call boto_ec2.delete_volume vol-12345678 """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: return conn.delete_volume(volume_id) except boto.exception.BotoServerError as e: if not force: log.error(e) return False try: conn.detach_volume(volume_id, force=force) return conn.delete_volume(volume_id) except boto.exception.BotoServerError as e: log.error(e) return False def _wait_for_volume_available(conn, volume_id, retries=5, interval=5): i = 0 while True: i = i + 1 time.sleep(interval) vols = conn.get_all_volumes(volume_ids=[volume_id]) if len(vols) != 1: return False vol = vols[0] if vol.status == "available": return True if i > retries: return False def attach_volume( volume_id, instance_id, device, region=None, key=None, keyid=None, profile=None ): """ Attach an EBS volume to an EC2 instance. .. volume_id (string) – The ID of the EBS volume to be attached. instance_id (string) – The ID of the EC2 instance to attach the volume to. device (string) – The device on the instance through which the volume is exposed (e.g. /dev/sdh) returns (bool) - True on success, False on failure. CLI Example: .. code-block:: bash salt-call boto_ec2.attach_volume vol-12345678 i-87654321 /dev/sdh """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: return conn.attach_volume(volume_id, instance_id, device) except boto.exception.BotoServerError as error: log.error(error) return False def create_volume( zone_name, size=None, snapshot_id=None, volume_type=None, iops=None, encrypted=False, kms_key_id=None, wait_for_creation=False, region=None, key=None, keyid=None, profile=None, ): """ Create an EBS volume to an availability zone. .. zone_name (string) – The Availability zone name of the EBS volume to be created. size (int) – The size of the new volume, in GiB. If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size. snapshot_id (string) – The snapshot ID from which the new volume will be created. volume_type (string) - The type of the volume. Valid volume types for AWS can be found here: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html iops (int) - The provisioned IOPS you want to associate with this volume. encrypted (bool) - Specifies whether the volume should be encrypted. kms_key_id (string) - If encrypted is True, this KMS Key ID may be specified to encrypt volume with this key e.g.: arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef wait_for_creation (bool) - Whether or not to wait for volume creation to complete. returns (string) - created volume id on success, error message on failure. CLI Example: .. code-block:: bash salt-call boto_ec2.create_volume us-east-1a size=10 salt-call boto_ec2.create_volume us-east-1a snapshot_id=snap-0123abcd """ if size is None and snapshot_id is None: raise SaltInvocationError("Size must be provided if not created from snapshot.") ret = {} conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) try: vol = conn.create_volume( size=size, zone=zone_name, snapshot=snapshot_id, volume_type=volume_type, iops=iops, encrypted=encrypted, kms_key_id=kms_key_id, ) if wait_for_creation and not _wait_for_volume_available(conn, vol.id): timeout_msg = 'Timed out waiting for the volume status "available".' log.error(timeout_msg) ret["error"] = timeout_msg else: ret["result"] = vol.id except boto.exception.BotoServerError as error: ret["error"] = __utils__["boto.get_error"](error) return ret
Save