diff --git a/.gitignore b/.gitignore index 38a3f24..7cea72e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,10 @@ quick.sh *~ *.swp +.bundle/ + +# for a library or gem, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +Gemfile.lock +.ruby-version +.ruby-gemset diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..2578726 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,28 @@ +Metrics/ClassLength: + Description: 'Avoid classes longer than 100 lines of code.' + Max: 165 + +Metrics/LineLength: + Description: 'Limit lines to 80 characters.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits' + Enabled: true + Max: 250 + Exclude: + - site-cookbooks/b_kibana/spec/configure_service_spec.rb + +Metrics/MethodLength: + Description: 'Avoid methods longer than 10 lines of code.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods' + Enabled: true + Max: 15 + +Style/Documentation: + Description: 'Document classes and non-namespace modules.' + Enabled: false + +Style/FileName: + Description: 'Use snake_case for source file names.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files' + Enabled: true + Exclude: + - lib/aws-cache.rb diff --git a/.travis.yml b/.travis.yml index 3780c1f..2220260 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,10 @@ language: ruby rvm: -- 1.9.3 -cache: -- bundler -script: bundle exec rspec spec + - 2.0.0 + - 2.2.3 +sudo: false +cache: bundler +script: bundle exec rake deploy: provider: rubygems api_key: diff --git a/Gemfile b/Gemfile index 63c3506..fa75df1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,14 +1,3 @@ source 'https://rubygems.org' -gem 'aws-sdk' -gem 'redis' -group :development do - gem 'awesome_print' - gem 'travis' -end - -group :test do - gem 'rspec' - gem 'rspec-given' - gem 'ploy' -end +gemspec diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index bac3cc4..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,128 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - addressable (2.3.8) - arr-pm (0.0.9) - cabin (> 0) - awesome_print (1.6.1) - aws-sdk (2.0.38) - aws-sdk-resources (= 2.0.38) - aws-sdk-core (2.0.38) - builder (~> 3.0) - jmespath (~> 1.0) - multi_json (~> 1.0) - aws-sdk-resources (2.0.38) - aws-sdk-core (= 2.0.38) - aws-sdk-v1 (1.64.0) - json (~> 1.4) - nokogiri (>= 1.4.4) - backports (3.6.4) - builder (3.2.2) - cabin (0.7.1) - childprocess (0.5.6) - ffi (~> 1.0, >= 1.0.11) - clamp (0.6.4) - coderay (1.1.0) - diff-lcs (1.2.5) - ethon (0.7.3) - ffi (>= 1.3.0) - faraday (0.9.1) - multipart-post (>= 1.2, < 3) - faraday_middleware (0.9.1) - faraday (>= 0.7.4, < 0.10) - ffi (1.9.8) - fpm (1.3.3) - arr-pm (~> 0.0.9) - backports (>= 2.6.2) - cabin (>= 0.6.0) - childprocess - clamp (~> 0.6) - ffi - json (>= 1.7.7) - gh (0.14.0) - addressable - backports - faraday (~> 0.8) - multi_json (~> 1.0) - net-http-persistent (>= 2.7) - net-http-pipeline - given_core (3.7.0) - sorcerer (>= 0.3.7) - highline (1.7.1) - jmespath (1.0.2) - multi_json (~> 1.0) - json (1.8.2) - launchy (2.4.3) - addressable (~> 2.3) - method_source (0.8.2) - mini_portile (0.6.2) - multi_json (1.11.0) - multipart-post (2.0.0) - net-http-persistent (2.9.4) - net-http-pipeline (1.0.1) - nokogiri (1.6.6.2) - mini_portile (~> 0.6.0) - ploy (0.0.33) - aws-sdk-v1 - fpm - sinatra - pry (0.9.12.6) - coderay (~> 1.0) - method_source (~> 0.8) - slop (~> 3.4) - pusher-client (0.6.0) - json - websocket (~> 1.0) - rack (1.6.0) - rack-protection (1.5.3) - rack - redis (3.2.1) - rspec (3.2.0) - rspec-core (~> 3.2.0) - rspec-expectations (~> 3.2.0) - rspec-mocks (~> 3.2.0) - rspec-core (3.2.3) - rspec-support (~> 3.2.0) - rspec-expectations (3.2.1) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.2.0) - rspec-given (3.7.0) - given_core (= 3.7.0) - rspec (>= 2.14.0) - rspec-mocks (3.2.1) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.2.0) - rspec-support (3.2.2) - sinatra (1.4.6) - rack (~> 1.4) - rack-protection (~> 1.4) - tilt (>= 1.3, < 3) - slop (3.6.0) - sorcerer (1.0.2) - tilt (2.0.1) - travis (1.7.6) - addressable (~> 2.3) - backports - faraday (~> 0.9) - faraday_middleware (~> 0.9, >= 0.9.1) - gh (~> 0.13) - highline (~> 1.6) - launchy (~> 2.1) - pry (~> 0.9, < 0.10) - pusher-client (~> 0.4) - typhoeus (~> 0.6, >= 0.6.8) - typhoeus (0.7.1) - ethon (>= 0.7.1) - websocket (1.2.1) - -PLATFORMS - ruby - -DEPENDENCIES - awesome_print - aws-sdk - ploy - redis - rspec - rspec-given - travis diff --git a/README.md b/README.md index 14b00fe..3b5a463 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # aws-cache [![Build Status](https://travis-ci.org/mantacode/aws-cache.png?branch=master)](https://travis-ci.org/mantacode/aws-cache) +[![Gem Version](http://img.shields.io/gem/v/aws-cache.svg)](https://rubygems.org/gems/aws-cache) ## Why diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..c405b96 --- /dev/null +++ b/Rakefile @@ -0,0 +1,21 @@ +require 'bundler/gem_tasks' +require 'rubocop/rake_task' + +desc 'Run all linters on the codebase' +task :linters do + Rake::Task['rubocop'].invoke +end + +desc 'rubocop compliancy checks' +RuboCop::RakeTask.new(:rubocop) do |t| + t.patterns = %w( + aws-cache.gemspec + bin/* + lib/**/*.rb + lib/*.rb + Rakefile + spec/*.rb + ) +end + +task default: [:rubocop] diff --git a/aws-cache.gemspec b/aws-cache.gemspec index 40a12ea..4688e3e 100644 --- a/aws-cache.gemspec +++ b/aws-cache.gemspec @@ -1,17 +1,23 @@ lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'aws-cache-version' +require 'aws-cache/version' Gem::Specification.new do |s| s.name = 'aws-cache' s.homepage = 'https://github.com/mantacode/aws-cache' - s.version = AwsCacheVersion::VERSION + s.version = AwsCache::VERSION s.summary = 'AWS api access layer that caches via Redis.' s.description = 'You know, to avoid api throttling errors.' s.licenses = ['MIT'] - s.authors = ["Stephen J. Smith", "Brian J. Schrock"] + s.authors = ['Stephen J. Smith', 'Brian J. Schrock'] s.email = 'stsmith@manta.com' s.files += Dir['lib/**/*.rb'] s.add_runtime_dependency 'aws-sdk' s.add_runtime_dependency 'redis' + + s.add_development_dependency 'awesome_print' + s.add_development_dependency 'rake' + s.add_development_dependency 'rspec' + s.add_development_dependency 'rubocop' + s.add_development_dependency 'travis' end diff --git a/bin/proto.rb b/bin/proto.rb index 5ffc979..2860d23 100755 --- a/bin/proto.rb +++ b/bin/proto.rb @@ -4,50 +4,47 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) require 'awesome_print' -require 'yaml' - require 'aws-cache' -require 'redis' host = 'redis.aws.ecnext.net' port = 6379 keyspace = ARGV[0] || 'debug' -cache = AwsCache.new({'keyspace' => keyspace, 'host' => host, 'port' => port}) +cache = AwsCache.new('keyspace' => keyspace, 'host' => host, 'port' => port) ############################################################## -#To get all instances associated with a given auto scaling group -#you can do something like this. +# To get all instances associated with a given auto scaling group +# you can do something like this. ############################################################## -#placeHolder = Array.new() -#cache.get_asg_instances( "manta-site-e2e-smoketest-AdminServiceNestedStack-1LB9D75MS2SUE-AdminServiceAutoScalingGroup-1I2AY0INI3GH").each do |instances| +# placeHolder = Array.new() +# cache.get_asg_instances( "manta-site-e2e-smoketest-AdminServiceNestedStack-1LB9D75MS2SUE-AdminServiceAutoScalingGroup-1I2AY0INI3GH").each do |instances| # placeHolder.push(instances[:instance_id]) -#end -#cache.describe_instances().each do |instance| +# end +# cache.describe_instances().each do |instance| # instance[:instances].each do |stuff| # if placeHolder.include?(stuff[:instance_id]) then # ap instance # end # end -#end +# end ############################################################## ############################################################## -#To get all instances in a stack with substacks do this. +# To get all instances in a stack with substacks do this. ############################################################## -#cache.stack_auto_scaling_groups('manta-site--main--production').each do |asg| +# cache.stack_auto_scaling_groups('manta-site--main--production').each do |asg| # ap cache.get_asg_instances(asg[:physical_resource_id]) -#end -# -#cache.get_sub_stacks('manta-site--main--production').each do |stack| +# end + +# cache.get_sub_stacks('manta-site--main--production').each do |stack| # ap stack[:stack_name] # cache.stack_auto_scaling_groups(stack[:stack_name]).each do |asg| # ap cache.get_asg_instances(asg[:physical_resource_id]) # end -#end +# end ############################################################## -cache.describe_instance("i-5f1824a0") +cache.describe_instance('i-5f1824a0') puts AwsCache::VERSION diff --git a/lib/aws-cache.rb b/lib/aws-cache.rb index ecace84..5b7fe78 100644 --- a/lib/aws-cache.rb +++ b/lib/aws-cache.rb @@ -1,18 +1,12 @@ require 'redis' -require 'json' require 'aws-sdk' require 'yaml' -require 'pry' -require 'aws-cache-version' -require 'awesome_print' +require 'aws-cache/version' class AwsCache - # Please follow semantic versioning (semver.org). - VERSION = AwsCacheVersion::VERSION - def initialize(opts) - unless opts.has_key?('port') then opts['port'] = 6379 end - unless opts.has_key?('host') then opts['host'] = 'aws-cache' end + opts['port'] = 6379 unless opts.key?('port') + opts['host'] = 'aws-cache' unless opts.key?('host') @redis = optional_element(opts, ['redis']) if @redis.nil? @redis = Redis.new(url: "redis://#{opts['host']}:#{opts['port']}/0") @@ -21,172 +15,160 @@ def initialize(opts) @region = optional_element(opts, ['region'], 'us-east-1') end - #Returns a hash describing the instance requested. - def describe_instance( instance_id) - instances = self.describe_instances() + # Returns a hash describing the instance requested. + def describe_instance(instance_id) + instances = describe_instances instance = instances.select do |entry| entry[:instances][0][:instance_id] == instance_id end - return instance[0] + instance[0] end - #Returns an array of hashes describing the autoscaling groups for the selected stack. + # Returns an array of hashes describing the autoscaling groups for the selected stack. def stack_auto_scaling_groups(stack_name) - auto_scaling_groups = Array.new() - stack_resources = self.list_stack_resources(stack_name) + auto_scaling_groups = [] + stack_resources = list_stack_resources(stack_name) asg_groups = stack_resources.select do |record| - record[:resource_type] == "AWS::AutoScaling::AutoScalingGroup" + record[:resource_type] == 'AWS::AutoScaling::AutoScalingGroup' end auto_scaling_groups.concat(asg_groups) substacks = stack_resources.select do |record| - record[:resource_type] == "AWS::CloudFormation::Stack" + record[:resource_type] == 'AWS::CloudFormation::Stack' end - if substacks.length > 0 then + unless substacks.empty? substacks.each do |stack| - auto_scaling_groups.concat(self.stack_auto_scaling_groups(stack[:physical_resource_id])) + auto_scaling_groups.concat(stack_auto_scaling_groups(stack[:physical_resource_id])) end end - return auto_scaling_groups + auto_scaling_groups end - #Returns an array of hashes describing the substacks for the selected stack. - def get_sub_stacks( stack_name) - substacks = Array.new() - stacks = self.list_stack_resources(stack_name) + # Returns an array of hashes describing the substacks for the selected stack. + def get_sub_stacks(stack_name) + substacks = [] + stacks = list_stack_resources(stack_name) stacks.each do |entry| - if entry[:resource_type] == "AWS::CloudFormation::Stack" - self.describe_stacks.each do |stack| - if entry[:physical_resource_id] == stack[:stack_id] - substacks.push(stack) - end + next unless entry[:resource_type] == 'AWS::CloudFormation::Stack' + describe_stacks.each do |stack| + if entry[:physical_resource_id] == stack[:stack_id] + substacks.push(stack) end end end - return substacks + substacks end - - #Returns a hash describing the stack requested. + + # Returns a hash describing the stack requested. def describe_stack(stack_name) - stacks = self.describe_stacks + stacks = describe_stacks stacks.each do |stack| - if stack[:stack_name] == stack_name - return stack - end + return stack if stack[:stack_name] == stack_name end - return nil + nil end - #Returns an array of hashes of instances. + # Returns an array of hashes of instances. def get_asg_instances(asg) - instances = Array.new() - asg_instances = self.describe_auto_scaling_group(asg) + instances = [] + asg_instances = describe_auto_scaling_group(asg) asg_instances[:instances].each do |instance| instances.push(instance) end - return instances + instances end - #Returns Aws::AutoScaling::Types::AutoScalingGroup + # Returns Aws::AutoScaling::Types::AutoScalingGroup def describe_auto_scaling_group(asg) - asgroups = self.describe_autoscaling_groups() + asgroups = describe_autoscaling_groups target_asg = asgroups.select do |record| record[:auto_scaling_group_name] == asg end - if target_asg then - return target_asg[0] - end - return nil + return target_asg[0] if target_asg + nil end - def describe_snapshots() + def describe_snapshots output = cache_get('get_snapshots', 300) do aws_object = Aws::EC2::Client.new(region: @region) pages = aws_object.describe_snapshots - output = process_page( 'snapshots', pages) + output = process_page('snapshots', pages) end - return output + output end - def list_stack_resources( stack_name) + def list_stack_resources(stack_name) output = cache_get("list_stack_resources-#{stack_name}", 300) do aws_object = Aws::CloudFormation::Client.new(region: @region) pages = aws_object.list_stack_resources(stack_name: stack_name) - output = process_page( 'stack_resource_summaries', pages) + output = process_page('stack_resource_summaries', pages) end - return output + output end - def describe_stacks() + def describe_stacks output = cache_get('get_stacks', 300) do aws_object = Aws::CloudFormation::Client.new(region: @region) pages = aws_object.describe_stacks - output = process_page( 'stacks', pages) + output = process_page('stacks', pages) end - return output + output end - - def describe_auto_scaling_instances() - output = cache_get("describe_auto_scaling_instances", 300) do + def describe_auto_scaling_instances + output = cache_get('describe_auto_scaling_instances', 300) do aws_object = Aws::AutoScaling::Client.new(region: @region) - pages = aws_object.describe_auto_scaling_instances() - output = process_page( 'auto_scaling_instances', pages) + pages = aws_object.describe_auto_scaling_instances + output = process_page('auto_scaling_instances', pages) end - return output + output end - - #Returns an Array of Hashes containing auto scaling group structures - def describe_autoscaling_groups() + # Returns an Array of Hashes containing auto scaling group structures + def describe_autoscaling_groups output = cache_get('get_autoscaling_groups', 300) do - aws_object = Aws::AutoScaling::Client.new(region: @region) + aws_object = Aws::AutoScaling::Client.new(region: @region) pages = aws_object.describe_auto_scaling_groups - output = process_page( 'auto_scaling_groups', pages) + output = process_page('auto_scaling_groups', pages) end - return output + output end - #Returns an Array of Hashes containing instance structures - def describe_instances() + # Returns an Array of Hashes containing instance structures + def describe_instances output = cache_get('describe_instances', 300) do aws_object = Aws::EC2::Client.new(region: @region) pages = aws_object.describe_instances - output = process_page( 'reservations', pages) + output = process_page('reservations', pages) end - return output + output end - def process_page( key, pages) - output = Array.new() + def process_page(key, pages) + output = [] pages.each do |page| - data = page.send( key) + data = page.send(key) data.each do |asg| output.push(asg) end end - return output + output end private - def optional_element(hash, keys, default=nil) + + def optional_element(hash, keys, default = nil) keys.each do |key| - if !has_key?(hash, key) - return default - end + return default unless key?(hash, key) hash = hash[key] end - return hash + hash end - def has_key?(hash_or_struct, key) + def key?(hash_or_struct, key) hos = hash_or_struct - if hos.is_a?(Hash) && hos.has_key?(key) - return true - end - if hos.is_a?(Struct) && hos.members.any? { |m| m == key } - return true - end - return false + return true if hos.is_a?(Hash) && hos.key?(key) + return true if hos.is_a?(Struct) && hos.members.any? { |m| m == key } + false end def cache_get(key, ttl) @@ -195,12 +177,11 @@ def cache_get(key, ttl) if output.nil? output = yield output = Psych.dump(output) - @redis.setex(vkey, ttl, output ) + @redis.setex(vkey, ttl, output) end - return Psych.load(output) + Psych.load(output) end - def list_to_hash!(src, keys, by_key) hash = {} last_key = keys.pop diff --git a/lib/aws-cache-version.rb b/lib/aws-cache/version.rb similarity index 56% rename from lib/aws-cache-version.rb rename to lib/aws-cache/version.rb index ac66a01..6dc26d0 100644 --- a/lib/aws-cache-version.rb +++ b/lib/aws-cache/version.rb @@ -1,4 +1,4 @@ -module AwsCacheVersion +class AwsCache # Please follow semantic versioning (semver.org). - VERSION = '0.0.11' + VERSION = '0.0.11'.freeze end