Skip to content

Commit

Permalink
simplify code publishing
Browse files Browse the repository at this point in the history
  • Loading branch information
terrywbrady committed Aug 27, 2024
1 parent fd79cca commit 0ef478a
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 128 deletions.
70 changes: 67 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,68 @@
Metrics/ClassLength:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/AbcSize:
Enabled: false
Metrics/CyclomaticComplexity:
Enabled: false
Metrics/PerceivedComplexity:
Enabled: false
Metrics/BlockNesting:
Enabled: false
Metrics/ParameterLists:
Enabled: false

Naming/AccessorMethodName:
Enabled: false
Style/NestedTernaryOperator:
Enabled: false
Naming/PredicateName:
Enabled: false

Layout/MultilineMethodCallIndentation:
EnforcedStyle: indented
Layout/ParameterAlignment:
EnforcedStyle: with_fixed_indentation
Layout/ArgumentAlignment:
EnforcedStyle: with_fixed_indentation
Naming/MethodParameterName:
Enabled: false
Layout/MultilineOperationIndentation:
Enabled: false
Style/GlobalVars:
Enabled: false
Style/ConditionalAssignment:
Enabled: false
Style/ClassVars:
Enabled: false
Style/HashSyntax:
Enabled: false

Layout/FirstArrayElementIndentation:
Enabled: true
Layout/FirstArrayElementLineBreak:
Enabled: true
Layout/ArrayAlignment:
EnforcedStyle: with_fixed_indentation
Layout/MultilineArrayBraceLayout:
EnforcedStyle: new_line

Layout/FirstHashElementIndentation:
Enabled: true
EnforcedStyle: consistent
Layout/MultilineHashKeyLineBreaks:
Enabled: true
Layout/MultilineHashBraceLayout:
EnforcedStyle: new_line

Style/OpenStructUse:
Enabled: false
Naming/VariableName:
Enabled: false

AllCops:
# We're using Ruby 2.4 right now. So force that version or higher.
# The version listed here should match whatever is specified in the gemspec
TargetRubyVersion: 2.4
NewCops: enable

8 changes: 6 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@

source 'https://rubygems.org'

# Specify your gem's dependencies in the gemspec
gemspec
gem 'aws-sdk-ssm'
gem 'byebug'
gem 'logger'
gem 'rspec'
gem 'rubocop'
gem 'yaml'
67 changes: 33 additions & 34 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
PATH
remote: .
specs:
uc3-ssm (0.3.10)
aws-sdk-ssm (~> 1.84)
logger (~> 1.4)
yaml (~> 0.2.1)

GEM
remote: https://rubygems.org/
specs:
Expand All @@ -25,6 +17,8 @@ GEM
byebug (11.1.3)
diff-lcs (1.5.1)
jmespath (1.6.2)
json (2.7.2)
language_server-protocol (3.17.0.3)
logger (1.6.0)
parallel (1.26.3)
parser (3.3.4.2)
Expand All @@ -35,44 +29,49 @@ GEM
regexp_parser (2.9.2)
rexml (3.3.6)
strscan
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.3)
rspec-support (~> 3.9.3)
rspec-expectations (3.9.4)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.0)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.4)
rubocop (0.88.0)
rspec-support (~> 3.13.0)
rspec-support (3.13.1)
rubocop (1.65.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 2.7.1.1)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.1.0, < 1.0)
regexp_parser (>= 2.4, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.8.0)
parser (>= 2.7.1.5)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.32.1)
parser (>= 3.3.1.0)
ruby-progressbar (1.13.0)
strscan (3.1.0)
unicode-display_width (1.8.0)
yaml (0.2.1)
unicode-display_width (2.5.0)
yaml (0.3.0)

PLATFORMS
arm64-darwin-22
arm64-darwin-23
x86_64-linux

DEPENDENCIES
byebug (= 11.1.3)
rspec (= 3.9.0)
rubocop (= 0.88.0)
uc3-ssm!
aws-sdk-ssm
byebug
logger
rspec
rubocop
yaml

BUNDLED WITH
2.3.25
2.4.19
37 changes: 15 additions & 22 deletions lib/uc3-ssm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ def initialize(msg)
end

# This code is designed to mimic https://github.com/terrywbrady/yaml/blob/master/config.yml
# rubocop:disable Metrics/ClassLength
class ConfigResolver
# def_value - value to return if no default is configured.
# This prevents an exception from being thrown.
Expand All @@ -26,7 +25,6 @@ class ConfigResolver
# we search for keys under each path sequentially, returning the value
# of the first matching key found. Example:
# ssm_root_path: '/prog/srvc/subsrvc/env:/prod/srvc/subsrvc/default'
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def initialize(**options)
# see issue #9 - @regex should not be a user definable option
dflt_regex = '^(.*)\\{!(ENV|SSM):\\s*([^\\}!]*)(!DEFAULT:\\s([^\\}]*))?\\}(.*)$'
Expand All @@ -43,7 +41,7 @@ def initialize(**options)
@region = options.fetch(:region, dflt_region)
@ssm_root_path = sanitize_root_path(options.fetch(:ssm_root_path, dflt_ssm_root_path))
@def_value = options.fetch(:def_value, '')
@logger = options.fetch(:logger, Logger.new(STDOUT))
@logger = options.fetch(:logger, Logger.new($stdout))
@client = Aws::SSM::Client.new(region: @region) unless @ssm_skip_resolution
rescue Aws::Errors::MissingRegionError
raise ConfigResolverError, 'No AWS region defined. Either set ENV["AWS_REGION"] or pass in `region: [region]`'
Expand All @@ -57,7 +55,7 @@ def resolve_file_values(file:, resolve_key: nil, return_key: nil)
raise ConfigResolverError, "Config file #{file} not found!" unless File.exist?(file)
raise ConfigResolverError, "Config file #{file} is empty!" unless File.size(file).positive?

config = YAML.safe_load(File.read(file), aliases: true)
config = YAML.safe_load_file(file, aliases: true)
resolve_hash_values(hash: config, resolve_key: resolve_key, return_key: return_key)
end

Expand All @@ -77,27 +75,25 @@ def resolve_hash_values(hash:, resolve_key: nil, return_key: nil)
# Retrieve all key+values for a path (using the ssm_root_path if none is specified)
# See https://docs.aws.amazon.com/sdk-for-ruby/v2/api/Aws/SSM/Client.html#get_parameters_by_path-instance_method
# details on available `options`
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
# rubocop:disable Metrics/MethodLength
def parameters_for_path(**options)
return [] if @ssm_skip_resolution

param_list = []
path_list = options[:path].nil? ? @ssm_root_path : sanitize_parameter_key(options[:path])
path_list.each do |root_path|
begin
options[:path] = root_path
param_list += fetch_param_list(**options)
rescue Aws::SSM::Errors::ParameterNotFound
@logger.debug "ParameterNotFound for path '#{root_path}' in parameters_by_path"
next
end
options[:path] = root_path
param_list += fetch_param_list(**options)
rescue Aws::SSM::Errors::ParameterNotFound
@logger.debug "ParameterNotFound for path '#{root_path}' in parameters_by_path"
next
end

param_list
rescue Aws::Errors::MissingCredentialsError
raise ConfigResolverError, 'No AWS credentials available. Make sure the server has access to the aws-sdk'
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
# rubocop:enable Metrics/MethodLength

# Retrieve a value for a single key
def parameter_for_key(key)
Expand All @@ -121,7 +117,7 @@ def sanitize_root_path(root_path)
root_path.split(':').each do |path|
raise ConfigResolverError, 'ssm_root_path must start with forward slash' unless path.start_with?('/')

root_path_list.push(path.end_with?('/') ? path : path + '/')
root_path_list.push(path.end_with?('/') ? path : "#{path}/")
end
root_path_list
end
Expand Down Expand Up @@ -154,11 +150,11 @@ def resolve_array(obj)
def resolve_hash(obj)
return {} if obj.nil?

obj.map { |k, v| [k, resolve_value(v)] }.to_h
obj.transform_values { |v| resolve_value(v) }
end

# Retrieve value for the string
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def resolve_string(obj)
matched = obj.match(@regex)
return obj unless matched
Expand Down Expand Up @@ -217,17 +213,15 @@ def sanitize_parameter_key(key)
key_not_qualified_msg = 'SSM parameter name is not fully qualified and no ssm_root_path defined.'
raise ConfigResolverError, key_not_qualified_msg.to_s if @ssm_root_path.empty?

keylist = []
@ssm_root_path.each do |root_path|
keylist.push("#{root_path}#{key}")
@ssm_root_path.map do |root_path|
"#{root_path}#{key}"
end

keylist
end

# Attempt to retrieve the value from AWS SSM
def retrieve_ssm_value(key)
return key if @ssm_skip_resolution

@client.get_parameter(name: key, with_decryption: true)[:parameter][:value]
rescue Aws::SSM::Errors::ParameterNotFound
@logger.debug "ParameterNotFound for key '#{key}' in retrieve_ssm_value"
Expand All @@ -249,7 +243,6 @@ def fetch_param_list(**options)
param_list += fetch_param_list(**options) if options[:next_token].present?
param_list
end

end
# rubocop:enable Metrics/ClassLength
end
Expand Down
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# frozen_string_literal: true

require 'byebug'
require 'uc3-ssm'
17 changes: 8 additions & 9 deletions spec/test/initialize_resolver_object_spec.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# frozen_string_literal: true

require 'spec_helper.rb'
require 'spec_helper'
require 'aws-sdk-ssm'

# rubocop:disable Metrics/BlockLength
RSpec.describe 'Test resolver object initialization. ', type: :feature do

context 'ConfigResolver.new' do
describe 'with no user provided options' do
myResolver = Uc3Ssm::ConfigResolver.new
Expand Down Expand Up @@ -44,14 +42,14 @@
expect(myResolver.instance_variable_get(:@def_value)).to eq('NOT_APPLICABLE')
end
# see issue #10 - @ssm_skip_resolution only settable as ENV var
#it 'sets @ssm_skip_resolution to true.' do
# it 'sets @ssm_skip_resolution to true.' do
# expect(myResolver.instance_variable_get(:@ssm_skip_resolution)).to be true
#end
# end
end

describe 'where ssm_root_path is list of colon separated paths' do
myResolver = Uc3Ssm::ConfigResolver.new(
ssm_root_path: '/root/path/:/no/trailing/slash',
ssm_root_path: '/root/path/:/no/trailing/slash'
)
it '@ssm_root_path is array with 2 paths.' do
expect(myResolver.instance_variable_get(:@ssm_root_path).length).to eq(2)
Expand All @@ -63,9 +61,9 @@

describe 'when ssm_root_path does not start with forward slash.' do
it 'raises exception.' do
expect {
expect do
Uc3Ssm::ConfigResolver.new(ssm_root_path: 'no/starting/slash/')
}.to raise_exception(Uc3Ssm::ConfigResolverError)
end.to raise_exception(Uc3Ssm::ConfigResolverError)
end
end

Expand All @@ -88,4 +86,5 @@
end
end
end
end
end
# rubocop:enable Metrics/BlockLength
Loading

0 comments on commit 0ef478a

Please sign in to comment.