Class: KnifeCloudformation::Provider
- Inherits:
-
Object
- Object
- KnifeCloudformation::Provider
- Includes:
- Utils::AnimalStrings
- Defined in:
- lib/knife-cloudformation/provider.rb
Overview
Remote provider interface
Constant Summary collapse
- STACK_EXPAND_INTERVAL =
Minimum number of seconds to wait before re-expanding in progress stack
45- STACK_LIST_INTERVAL =
Default interval for refreshing stack list in cache
120
Instance Attribute Summary collapse
-
#async ⇒ TrueClass, FalseClass
readonly
Async updates.
- #cache ⇒ Cache readonly
- #connection ⇒ Miasma::Models::Orchestration readonly
-
#logger ⇒ Logger, NilClass
readonly
Logger in use.
-
#stack_expansion_interval ⇒ Numeric
readonly
Interval between stack expansions.
-
#stack_list_interval ⇒ Numeric
readonly
Interval between stack list updates.
-
#updater ⇒ Thread, NilClass
Stack list updater.
Instance Method Summary collapse
-
#cached_stacks ⇒ String
Json representation of cached stacks.
-
#expand_stack(stack) ⇒ Object
Expand all lazy loaded attributes within stack.
-
#fetch_stacks ⇒ TrueClass
Request stack information and store in cache.
-
#initialize(args = {}) ⇒ Provider
constructor
Create new instance.
-
#remove_stack(stack_id) ⇒ TrueClass, FalseClass
Remove stack from the cache.
-
#save_expanded_stack(stack_id, stack_attributes) ⇒ TrueClass
Store stack attribute changes.
-
#service_for(service) ⇒ Miasma::Model
Build API connection for service type.
- #stack(stack_id) ⇒ Miasma::Orchestration::Stack, NilClass
- #stacks ⇒ Miasma::Orchestration::Stacks
-
#update_stack_list! ⇒ TrueClass, FalseClass
Start async stack list update.
Methods included from Utils::AnimalStrings
Constructor Details
#initialize(args = {}) ⇒ Provider
Create new instance
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/knife-cloudformation/provider.rb', line 43 def initialize(args={}) unless(args[:miasma][:provider]) best_guess = args[:miasma].keys.group_by do |key| key.to_s.split('_').first end.sort do |x, y| y.size <=> x.size end.first if(best_guess) provider = best_guess.first.to_sym else raise ArgumentError.new 'Cannot auto determine :provider value for credentials' end else provider = args[:miasma].delete(:provider).to_sym end if(provider == :aws) if(args[:miasma][:region]) args[:miasma][:aws_region] = args[:miasma].delete(:region) end end if(ENV['DEBUG'].to_s.downcase == 'true') log_to = STDOUT else if(Gem.win_platform?) log_to = 'NUL' else log_to = '/dev/null' end end @logger = args.fetch(:logger, Logger.new(log_to)) @stack_expansion_interval = args.fetch(:stack_expansion_interval, STACK_EXPAND_INTERVAL) @stack_list_interval = args.fetch(:stack_list_interval, STACK_LIST_INTERVAL) @connection = Miasma.api( :provider => provider, :type => :orchestration, :credentials => args[:miasma] ) @cache = args.fetch(:cache, Cache.new(:local)) @async = args.fetch(:async, true) @miamsa_args = args[:miasma].dup cache.init(:stacks_lock, :lock, :timeout => 0.1) cache.init(:stacks, :stamped) cache.init(:stack_expansion_lock, :lock, :timeout => 0.1) if(args.fetch(:fetch, false)) async ? update_stack_list! : fetch_stacks end end |
Instance Attribute Details
#async ⇒ TrueClass, FalseClass (readonly)
Returns async updates.
26 27 28 |
# File 'lib/knife-cloudformation/provider.rb', line 26 def async @async end |
#cache ⇒ Cache (readonly)
22 23 24 |
# File 'lib/knife-cloudformation/provider.rb', line 22 def cache @cache end |
#connection ⇒ Miasma::Models::Orchestration (readonly)
20 21 22 |
# File 'lib/knife-cloudformation/provider.rb', line 20 def connection @connection end |
#logger ⇒ Logger, NilClass (readonly)
Returns logger in use.
28 29 30 |
# File 'lib/knife-cloudformation/provider.rb', line 28 def logger @logger end |
#stack_expansion_interval ⇒ Numeric (readonly)
Returns interval between stack expansions.
30 31 32 |
# File 'lib/knife-cloudformation/provider.rb', line 30 def stack_expansion_interval @stack_expansion_interval end |
#stack_list_interval ⇒ Numeric (readonly)
Returns interval between stack list updates.
32 33 34 |
# File 'lib/knife-cloudformation/provider.rb', line 32 def stack_list_interval @stack_list_interval end |
#updater ⇒ Thread, NilClass
Returns stack list updater.
24 25 26 |
# File 'lib/knife-cloudformation/provider.rb', line 24 def updater @updater end |
Instance Method Details
#cached_stacks ⇒ String
Returns json representation of cached stacks.
97 98 99 100 101 |
# File 'lib/knife-cloudformation/provider.rb', line 97 def cached_stacks fetch_stacks unless @initial_fetch_complete value = cache[:stacks].value value ? MultiJson.dump(MultiJson.load(value).values) : '[]' end |
#expand_stack(stack) ⇒ Object
Expand all lazy loaded attributes within stack
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/knife-cloudformation/provider.rb', line 141 def (stack) logger.info "Stack expansion requested (#{stack.id})" if((stack.in_progress? && Time.now.to_i - stack.attributes['Cached'].to_i > stack_expansion_interval) || !stack.attributes['Cached']) begin = false cache.locked_action(:stack_expansion_lock) do = true stack.reload stack.data['Cached'] = Time.now.to_i end if() (stack.id, stack.to_json) end rescue => e logger.error "Stack expansion failed (#{stack.id}) - #{e.class}: #{e}" end else logger.info "Stack has been cached within expand interval. Expansion prevented. (#{stack.id})" end end |
#fetch_stacks ⇒ TrueClass
Request stack information and store in cache
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/knife-cloudformation/provider.rb', line 166 def fetch_stacks cache.locked_action(:stacks_lock) do logger.info "Lock aquired for stack update. Requesting stacks from upstream. (#{Thread.current})" stacks = Hash[ connection.stacks.reload.all.map do |stack| [stack.id, stack.attributes] end ] if(cache[:stacks].value) existing_stacks = MultiJson.load(cache[:stacks].value) # Force common types stacks = MultiJson.load(MultiJson.dump(stacks)) # Remove stacks that have been deleted stale_ids = existing_stacks.keys - stacks.keys stacks = Chef::Mixin::DeepMerge.merge(existing_stacks, stacks) stale_ids.each do |stale_id| stacks.delete(stale_id) end end cache[:stacks].value = stacks.to_json logger.info 'Stack list has been updated from upstream and cached locally' end @initial_fetch_complete = true end |
#remove_stack(stack_id) ⇒ TrueClass, FalseClass
Remove stack from the cache
127 128 129 130 131 132 133 134 135 136 |
# File 'lib/knife-cloudformation/provider.rb', line 127 def remove_stack(stack_id) current_stacks = MultiJson.load(cached_stacks) logger.info "Attempting to remove stack from internal cache (#{stack_id})" cache.locked_action(:stacks_lock) do val = current_stacks.delete(stack_id) logger.info "Successfully removed stack from internal cache (#{stack_id})" cache[:stacks].value = MultiJson.dump(current_stacks) !!val end end |
#save_expanded_stack(stack_id, stack_attributes) ⇒ TrueClass
Store stack attribute changes
113 114 115 116 117 118 119 120 121 |
# File 'lib/knife-cloudformation/provider.rb', line 113 def (stack_id, stack_attributes) current_stacks = MultiJson.load(cached_stacks) cache.locked_action(:stacks_lock) do logger.info "Saving expanded stack attributes in cache (#{stack_id})" current_stacks[stack_id] = stack_attributes.merge('Cached' => Time.now.to_i) cache[:stacks].value = MultiJson.dump(current_stacks) end true end |
#service_for(service) ⇒ Miasma::Model
Build API connection for service type
217 218 219 |
# File 'lib/knife-cloudformation/provider.rb', line 217 def service_for(service) connection.api_for(service) end |
#stack(stack_id) ⇒ Miasma::Orchestration::Stack, NilClass
104 105 106 |
# File 'lib/knife-cloudformation/provider.rb', line 104 def stack(stack_id) stacks.get(stack_id) end |
#stacks ⇒ Miasma::Orchestration::Stacks
92 93 94 |
# File 'lib/knife-cloudformation/provider.rb', line 92 def stacks connection.stacks.from_json(cached_stacks) end |
#update_stack_list! ⇒ TrueClass, FalseClass
Start async stack list update. Creates thread that loops every ‘self.stack_list_interval` seconds and refreshes stack list in cache
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/knife-cloudformation/provider.rb', line 195 def update_stack_list! if(updater.nil? || !updater.alive?) self.updater = Thread.new{ loop do begin fetch_stacks sleep(stack_list_interval) rescue => e logger.error "Failure encountered on stack fetch: #{e.class} - #{e}" end end } true else false end end |