Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
e21f61d6
Commit
e21f61d6
authored
Mar 28, 2014
by
Michael DeHaan
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6616 from willthames/ec2_vol_allow_delete
Allow state=absent for ec2_vol
parents
37efa164
c0ac615a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
119 additions
and
75 deletions
+119
-75
library/cloud/ec2_vol
+119
-75
No files found.
library/cloud/ec2_vol
View file @
e21f61d6
...
...
@@ -55,7 +55,7 @@ options:
version_added: "1.6"
id:
description:
- volume id if you wish to attach an existing volume (requires instance)
- volume id if you wish to attach an existing volume (requires instance)
or remove an existing volume
required: false
default: null
aliases: []
...
...
@@ -63,7 +63,7 @@ options:
volume_size:
description:
- size of volume (in GB) to create.
required:
tru
e
required:
fals
e
default: null
aliases: []
iops:
...
...
@@ -118,7 +118,13 @@ options:
default: null
aliases: []
version_added: "1.6"
state:
description:
- whether to ensure the volume is present or absent
required: false
default: present
choices: ['absent', 'present']
version_added: "1.6"
requirements: [ "boto" ]
author: Lester Wade
'''
...
...
@@ -173,6 +179,7 @@ EXAMPLES = '''
wait: yes
count: 1
register: ec2
- local_action:
module: ec2_vol
instance: "{{ item.id }}"
...
...
@@ -180,6 +187,12 @@ EXAMPLES = '''
device_name: /dev/xvdf
with_items: ec2.instances
register: ec2_vol
# Remove a volume
- location: action
module: ec2_vol
id: vol-XXXXXXXX
state: absent
'''
# Note: this module needs to be made idempotent. Possible solution is to use resource tags with the volumes.
...
...
@@ -196,57 +209,50 @@ except ImportError:
print
"failed=True msg='boto required for this module'"
sys
.
exit
(
1
)
def
main
():
argument_spec
=
ec2_argument_spec
()
argument_spec
.
update
(
dict
(
instance
=
dict
(),
id
=
dict
(),
name
=
dict
(),
volume_size
=
dict
(),
iops
=
dict
(),
device_name
=
dict
(),
zone
=
dict
(
aliases
=
[
'availability_zone'
,
'aws_zone'
,
'ec2_zone'
]),
snapshot
=
dict
(),
)
)
module
=
AnsibleModule
(
argument_spec
=
argument_spec
)
def
get_volume
(
module
,
ec2
):
name
=
module
.
params
.
get
(
'name'
)
id
=
module
.
params
.
get
(
'id'
)
zone
=
module
.
params
.
get
(
'zone'
)
filters
=
{}
volume_ids
=
None
if
zone
:
filters
[
'availability_zone'
]
=
zone
if
name
:
filters
=
{
'tag:Name'
:
name
}
if
id
:
volume_ids
=
[
id
]
try
:
vols
=
ec2
.
get_all_volumes
(
volume_ids
=
volume_ids
,
filters
=
filters
)
except
boto
.
exception
.
BotoServerError
,
e
:
module
.
fail_json
(
msg
=
"
%
s:
%
s"
%
(
e
.
error_code
,
e
.
error_message
))
if
not
vols
:
module
.
fail_json
(
msg
=
"Could not find volume in zone (if specified):
%
s"
%
name
or
id
)
if
len
(
vols
)
>
1
:
module
.
fail_json
(
msg
=
"Found more than one volume in zone (if specified) with name:
%
s"
%
name
)
return
vols
[
0
]
def
delete_volume
(
module
,
ec2
):
vol
=
get_volume
(
module
,
ec2
)
if
not
vol
:
module
.
exit_json
(
changed
=
False
)
else
:
if
vol
.
attachment_state
()
is
not
None
:
adata
=
vol
.
attach_data
module
.
fail_json
(
msg
=
"Volume
%
s is attached to an instance
%
s."
%
(
vol
.
id
,
adata
.
instance_id
))
ec2
.
delete_volume
(
vol
.
id
)
module
.
exit_json
(
changed
=
True
)
def
create_volume
(
module
,
ec2
,
zone
):
name
=
module
.
params
.
get
(
'name'
)
id
=
module
.
params
.
get
(
'id'
)
instance
=
module
.
params
.
get
(
'instance'
)
volume_size
=
module
.
params
.
get
(
'volume_size'
)
iops
=
module
.
params
.
get
(
'iops'
)
device_name
=
module
.
params
.
get
(
'device_name'
)
zone
=
module
.
params
.
get
(
'zone'
)
volume_size
=
module
.
params
.
get
(
'volume_size'
)
snapshot
=
module
.
params
.
get
(
'snapshot'
)
ec2
=
ec2_connect
(
module
)
if
id
and
name
:
module
.
fail_json
(
msg
=
"Both id and name cannot be specified"
)
if
not
(
id
or
name
or
volume_size
):
module
.
fail_json
(
msg
=
"Cannot specify volume_size and either one of name or id"
)
# Here we need to get the zone info for the instance. This covers situation where
# instance is specified but zone isn't.
# Useful for playbooks chaining instance launch with volume create + attach and where the
# zone doesn't matter to the user.
if
instance
:
reservation
=
ec2
.
get_all_instances
(
instance_ids
=
instance
)
inst
=
reservation
[
0
]
.
instances
[
0
]
zone
=
inst
.
placement
# Check if there is a volume already mounted there.
if
device_name
:
if
device_name
in
inst
.
block_device_mapping
:
module
.
exit_json
(
msg
=
"Volume mapping for
%
s already exists on instance
%
s"
%
(
device_name
,
instance
),
volume_id
=
inst
.
block_device_mapping
[
device_name
]
.
volume_id
,
device
=
device_name
,
changed
=
False
)
# If custom iops is defined we use volume_type "io1" rather than the default of "standard"
if
iops
:
volume_type
=
'io1'
else
:
...
...
@@ -259,26 +265,7 @@ def main():
if
iops
or
volume_size
:
module
.
fail_json
(
msg
=
"Parameters are not compatible: [id or name] and [iops or volume_size]"
)
filters
=
{}
volume_ids
=
None
if
zone
:
filters
[
'availability_zone'
]
=
zone
if
name
:
filters
=
{
'tag:Name'
:
name
}
if
id
:
volume_ids
=
[
id
]
try
:
vols
=
ec2
.
get_all_volumes
(
volume_ids
=
volume_ids
,
filters
=
filters
)
except
boto
.
exception
.
BotoServerError
,
e
:
module
.
fail_json
(
msg
=
"
%
s:
%
s"
%
(
e
.
error_code
,
e
.
error_message
))
if
not
vols
:
module
.
fail_json
(
msg
=
"Could not find volume in zone (if specified):
%
s"
%
name
or
id
)
if
len
(
vols
)
>
1
:
module
.
fail_json
(
msg
=
"Found more than one volume in zone (if specified) with name:
%
s"
%
name
)
volume
=
vols
.
pop
()
volume
=
get_volume
(
module
,
ec2
)
if
volume
.
attachment_state
()
is
not
None
:
adata
=
volume
.
attach_data
if
adata
.
instance_id
!=
instance
:
...
...
@@ -298,12 +285,15 @@ def main():
volume
.
update
()
except
boto
.
exception
.
BotoServerError
,
e
:
module
.
fail_json
(
msg
=
"
%
s:
%
s"
%
(
e
.
error_code
,
e
.
error_message
))
return
volume
# Attach the created volume.
def
attach_volume
(
module
,
ec2
,
volume
,
instance
):
device_name
=
module
.
params
.
get
(
'device_name'
)
if
device_name
and
instance
:
try
:
attach
=
volume
.
attach
(
inst
.
id
,
device_name
)
attach
=
volume
.
attach
(
inst
ance
.
id
,
device_name
)
while
volume
.
attachment_state
()
!=
'attached'
:
time
.
sleep
(
3
)
volume
.
update
()
...
...
@@ -334,11 +324,65 @@ def main():
except
boto
.
exception
.
BotoServerError
,
e
:
module
.
fail_json
(
msg
=
"
%
s:
%
s"
%
(
e
.
error_code
,
e
.
error_message
))
print
json
.
dumps
({
"volume_id"
:
volume
.
id
,
"device"
:
device_name
})
sys
.
exit
(
0
)
def
main
():
argument_spec
=
ec2_argument_spec
()
argument_spec
.
update
(
dict
(
instance
=
dict
(),
id
=
dict
(),
name
=
dict
(),
volume_size
=
dict
(),
iops
=
dict
(),
device_name
=
dict
(),
zone
=
dict
(
aliases
=
[
'availability_zone'
,
'aws_zone'
,
'ec2_zone'
]),
snapshot
=
dict
(),
state
=
dict
(
choices
=
[
'absent'
,
'present'
],
default
=
'present'
)
)
)
module
=
AnsibleModule
(
argument_spec
=
argument_spec
)
id
=
module
.
params
.
get
(
'id'
)
name
=
module
.
params
.
get
(
'name'
)
instance
=
module
.
params
.
get
(
'instance'
)
volume_size
=
module
.
params
.
get
(
'volume_size'
)
iops
=
module
.
params
.
get
(
'iops'
)
device_name
=
module
.
params
.
get
(
'device_name'
)
zone
=
module
.
params
.
get
(
'zone'
)
snapshot
=
module
.
params
.
get
(
'snapshot'
)
state
=
module
.
params
.
get
(
'state'
)
ec2
=
ec2_connect
(
module
)
if
id
and
name
:
module
.
fail_json
(
msg
=
"Both id and name cannot be specified"
)
if
not
(
id
or
name
or
volume_size
):
module
.
fail_json
(
msg
=
"Cannot specify volume_size and either one of name or id"
)
# Here we need to get the zone info for the instance. This covers situation where
# instance is specified but zone isn't.
# Useful for playbooks chaining instance launch with volume create + attach and where the
# zone doesn't matter to the user.
if
instance
:
reservation
=
ec2
.
get_all_instances
(
instance_ids
=
instance
)
inst
=
reservation
[
0
]
.
instances
[
0
]
zone
=
inst
.
placement
# Check if there is a volume already mounted there.
if
device_name
:
if
device_name
in
inst
.
block_device_mapping
:
module
.
exit_json
(
msg
=
"Volume mapping for
%
s already exists on instance
%
s"
%
(
device_name
,
instance
),
volume_id
=
inst
.
block_device_mapping
[
device_name
]
.
volume_id
,
device
=
device_name
,
changed
=
False
)
if
state
==
'absent'
:
delete_volume
(
module
,
ec2
)
else
:
volume
=
create_volume
(
module
,
ec2
,
zone
)
if
instance
:
attach_volume
(
module
,
ec2
,
volume
,
inst
)
module
.
exit_json
(
volume_id
=
volume
.
id
,
device
=
device_name
)
# import module snippets
from
ansible.module_utils.basic
import
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment