2019-06-11 22:24:35 +00:00
require " resource_support/aws/aws_singular_resource_mixin "
require " resource_support/aws/aws_backend_base "
require " aws-sdk-ec2 "
2019-05-25 08:33:26 +00:00
2018-09-21 15:49:28 +00:00
class AwsEbsVolume < Inspec . resource ( 1 )
2019-06-11 22:24:35 +00:00
name " aws_ebs_volume "
desc " Verifies settings for an EBS volume "
2018-09-21 15:49:28 +00:00
2019-03-19 14:17:32 +00:00
example << ~ EXAMPLE
2018-09-21 15:49:28 +00:00
describe aws_ebs_volume ( 'vol-123456' ) do
it { should be_encrypted }
its ( 'size' ) { should cmp 8 }
end
describe aws_ebs_volume ( name : 'my-volume' ) do
its ( 'encrypted' ) { should eq true }
its ( 'iops' ) { should cmp 100 }
end
2019-03-19 14:17:32 +00:00
EXAMPLE
2019-06-11 22:24:35 +00:00
supports platform : " aws "
2018-09-21 15:49:28 +00:00
# TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin
def initialize ( opts , conn = nil )
@opts = opts
@display_name = opts . is_a? ( Hash ) ? @opts [ :name ] : opts
@ec2_client = conn ? conn . ec2_client : inspec_runner . backend . aws_client ( Aws :: EC2 :: Client )
@ec2_resource = conn ? conn . ec2_resource : inspec_runner . backend . aws_resource ( Aws :: EC2 :: Resource , { } )
end
# TODO: DRY up, see https://github.com/chef/inspec/issues/2633
# Copied from resource_support/aws/aws_resource_mixin.rb
def catch_aws_errors
yield
rescue Aws :: Errors :: MissingCredentialsError
# The AWS error here is unhelpful:
# "unable to sign request without credentials set"
Inspec :: Log . error " It appears that you have not set your AWS credentials. You may set them using environment variables, or using the 'aws://region/aws_credentials_profile' target. See https://www.inspec.io/docs/reference/platforms for details. "
2019-06-11 22:24:35 +00:00
fail_resource ( " No AWS credentials available " )
2018-09-21 15:49:28 +00:00
rescue Aws :: Errors :: ServiceError = > e
fail_resource ( e . message )
end
# TODO: DRY up, see https://github.com/chef/inspec/issues/2633
# Copied from resource_support/aws/aws_singular_resource_mixin.rb
def inspec_runner
# When running under inspec-cli, we have an 'inspec' method that
# returns the runner. When running under unit tests, we don't
# have that, but we still have to call this to pass something
# (nil is OK) to the backend.
# TODO: remove with https://github.com/chef/inspec-aws/issues/216
# TODO: remove after rewrite to include AwsSingularResource
inspec if respond_to? ( :inspec )
end
def id
return @volume_id if defined? ( @volume_id )
2019-07-09 00:20:30 +00:00
2018-09-21 15:49:28 +00:00
catch_aws_errors do
if @opts . is_a? ( Hash )
first = @ec2_resource . volumes (
{
filters : [ {
2019-06-11 22:24:35 +00:00
name : " tag:Name " ,
2018-09-21 15:49:28 +00:00
values : [ @opts [ :name ] ] ,
} ] ,
2019-06-11 22:24:35 +00:00
}
2018-09-21 15:49:28 +00:00
) . first
# catch case where the volume is not known
@volume_id = first . id unless first . nil?
else
@volume_id = @opts
end
end
end
alias volume_id id
def exists?
! volume . nil?
end
def encrypted?
volume . encrypted
end
# attributes that we want to expose
%w{
availability_zone encrypted iops kms_key_id size snapshot_id state volume_type
} . each do | attribute |
define_method attribute do
catch_aws_errors do
volume . send ( attribute ) if volume
end
end
end
# Don't document this - it's a bit hard to use. Our current doctrine
# is to use dumb things, like arrays of strings - use security_group_ids instead.
def security_groups
catch_aws_errors do
2019-06-11 22:24:35 +00:00
@security_groups || = volume . security_groups . map do | sg |
2018-09-21 15:49:28 +00:00
{ id : sg . group_id , name : sg . group_name }
2019-06-11 22:24:35 +00:00
end
2018-09-21 15:49:28 +00:00
end
end
def security_group_ids
catch_aws_errors do
@security_group_ids || = volume . security_groups . map ( & :group_id )
end
end
def tags
catch_aws_errors do
@tags || = volume . tags . map { | tag | { key : tag . key , value : tag . value } }
end
end
def to_s
" EBS Volume #{ @display_name } "
end
private
def volume
catch_aws_errors { @volume || = @ec2_resource . volume ( id ) }
end
end