Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support in memory cache - Need to be implemented #822

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
26 changes: 26 additions & 0 deletions libraries/aws_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ def initialize(params)

def aws_client(klass)
# TODO: make this a dict with keys of klass.to_s.to_sym such that we can send different args per client in cases such as EC2 instance that use multiple different clients

# @client_args[:stub_data][:client] ||= klass if @client_args[:stub_data].present?
if @client_args && @client_args[:resource_data] && !@client_args[:resource_data].empty?
return AwsMockResource.new(@client_args[:resource_data])
end
return @cache[klass.to_s.to_sym] ||= klass.new(@client_args) if @client_args
@cache[klass.to_s.to_sym] ||= klass.new
end
Expand Down Expand Up @@ -331,6 +336,20 @@ def waf_client
end
end

class AwsMockResource
def initialize(opts)
@opts = opts
end

private

attr_reader :opts

def method_missing(_symbol, *_args)
[opts[:resource_data]]
end
end

# Base class for AWS resources
#
class AwsResourceBase < Inspec.resource(1)
Expand All @@ -354,6 +373,13 @@ def initialize(opts)
client_args[:client_args][:retry_limit] = opts[:aws_retry_limit] if opts[:aws_retry_limit]
client_args[:client_args][:retry_backoff] = "lambda { |c| sleep(#{opts[:aws_retry_backoff]}) }" if opts[:aws_retry_backoff]
# this catches the stub_data true option for unit testing - and others that could be useful for consumers
if @opts.key?(:resource_data)
@opts[:resource_data] = @opts[:resource_data].to_h
end
if @opts[:resource_data] && !@opts[:resource_data].empty?
client_args[:client_args][:stub_responses] = true
client_args[:client_args][:resource_data] = @opts[:resource_data]
end
client_args[:client_args].update(opts[:client_args]) if opts[:client_args]

@resource_data = opts[:resource_data].presence&.to_h
Expand Down
24 changes: 13 additions & 11 deletions libraries/aws_ec2_instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,23 @@ def initialize(opts = {})
super(opts)
validate_parameters(require_any_of: %i(instance_id name))

if opts[:instance_id] && !opts[:instance_id].empty? # Use instance_id, if provided
if !opts[:instance_id].is_a?(String) || opts[:instance_id] !~ /(^i-[0-9a-f]{8})|(^i-[0-9a-f]{17})$/
raise ArgumentError, "#{@__resource_name__}: `instance_id` must be a string in the format of 'i-' followed by 8 or 17 hexadecimal characters."
if !opts[:resource_data]
if opts[:instance_id] && !opts[:instance_id].empty? # Use instance_id, if provided
if !opts[:instance_id].is_a?(String) || opts[:instance_id] !~ /(^i-[0-9a-f]{8})|(^i-[0-9a-f]{17})$/
raise ArgumentError, "#{@__resource_name__}: `instance_id` must be a string in the format of 'i-' followed by 8 or 17 hexadecimal characters."
end
@display_name = opts[:instance_id]
instance_arguments = { instance_ids: [opts[:instance_id]] }
elsif opts[:name] && !opts[:name].empty? # Otherwise use name, if provided
@display_name = opts[:name]
instance_arguments = { filters: [{ name: 'tag:Name', values: [opts[:name]] }] }
else
raise ArgumentError, "#{@__resource_name__}: either instance_id or name must be provided."
end
@display_name = opts[:instance_id]
instance_arguments = { instance_ids: [opts[:instance_id]] }
elsif opts[:name] && !opts[:name].empty? # Otherwise use name, if provided
@display_name = opts[:name]
instance_arguments = { filters: [{ name: 'tag:Name', values: [opts[:name]] }] }
else
raise ArgumentError, "#{@__resource_name__}: either instance_id or name must be provided."
end

catch_aws_errors do
resp = @aws.compute_client.describe_instances(instance_arguments)
resp = opts[:resource_data] || @aws.compute_client.describe_instances(instance_arguments)
if resp.reservations.first.nil? || resp.reservations.first.instances.first.nil?
empty_response_warn
return
Expand Down