Class: Panoramix::Plugin::CloudFormation

Inherits:
Base
  • Object
show all
Defined in:
lib/panoramix/plugin/cfn.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#shell

Constructor Details

#initialize(dst, src, parameters, stage, owner, version) ⇒ CloudFormation



20
21
22
23
24
25
26
27
28
# File 'lib/panoramix/plugin/cfn.rb', line 20

def initialize(dst, src, parameters, stage, owner, version)
  @dst = dst
  @src = src
  @stage = stage
  @owner = owner
  @version = version

  @params = TOML.load_file(parameters)
end

Instance Attribute Details

#dstObject (readonly)

Returns the value of attribute dst.



13
14
15
# File 'lib/panoramix/plugin/cfn.rb', line 13

def dst
  @dst
end

#ownerObject (readonly)

Returns the value of attribute owner.



17
18
19
# File 'lib/panoramix/plugin/cfn.rb', line 17

def owner
  @owner
end

#paramsObject (readonly)

Returns the value of attribute params.



16
17
18
# File 'lib/panoramix/plugin/cfn.rb', line 16

def params
  @params
end

#srcObject (readonly)

Returns the value of attribute src.



14
15
16
# File 'lib/panoramix/plugin/cfn.rb', line 14

def src
  @src
end

#stageObject (readonly)

Returns the value of attribute stage.



15
16
17
# File 'lib/panoramix/plugin/cfn.rb', line 15

def stage
  @stage
end

#versionObject (readonly)

Returns the value of attribute version.



18
19
20
# File 'lib/panoramix/plugin/cfn.rb', line 18

def version
  @version
end

Instance Method Details

#ask_proObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/panoramix/plugin/cfn.rb', line 40

def ask_pro
  choose do |menu|
    menu.prompt = "Would you like to delete the stack #{gen_stack_name}? "

    menu.choice(:No)  do
      say("Don't do it again!")
      return false
    end
    menu.choices(:Yes) do
      resp = ask("Warning, this action can not be reversed. Do you want to continue? (Yes/No)".red, String) do |q|
        q.default = "No"
      end
      return resp == "Yes"
    end
  end
end

#created?Boolean

Has this stacks already been created



82
83
84
85
86
87
88
89
90
# File 'lib/panoramix/plugin/cfn.rb', line 82

def created?
  # Get a list af all created Stacks
  query = shell("aws cloudformation describe-stacks --query 'Stacks[*].{StackName:StackName, CreationTime:CreationTime}'", true)[:out]
  parsed_stacks = JSON.parse query

  # Check wether the stacks has already been created
  info = parsed_stacks.select { |s| s["StackName"] == gen_stack_name }
  @created = info.empty? ? nil: info.first
end

#deleteObject

Action delete for this task



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/panoramix/plugin/cfn.rb', line 93

def delete
  return unless created?
  return unless question

  cmd = "aws cloudformation delete-stack \
  --stack-name #{gen_stack_name}"

  shell(cmd)
  # Wait until the stack is being deleted
  loop do
    break if !created?
  end
end

#fill_env(path) ⇒ Object

Match every parameter with an environment variable



114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/panoramix/plugin/cfn.rb', line 114

def fill_env path
  file = File.read path
  json = JSON.parse file

  env = Hash.new
  json["Parameters"].each do |k,v|
    env[k] = @params["default"][k] ? @params["default"][k] : nil
    env[k] = @params[@stage][k] ? @params[@stage][k] : env[k]
    env[k] = ENV[k] ? ENV[k] : env[k]
    raise "Parameter or environment variable #{k} not defined" unless env[k]
  end
  env
end

#gen_stack_nameObject

Final Cloud Formation stack name



31
32
33
# File 'lib/panoramix/plugin/cfn.rb', line 31

def gen_stack_name
  @version ? "#{@stage}-#{@dst}-#{@version}-#{owner}" : "#{@stage}-#{@dst}-#{owner}"
end

#needed?(timestamps) ⇒ Boolean

When this instance needs to be executed



108
109
110
111
# File 'lib/panoramix/plugin/cfn.rb', line 108

def needed? timestamps
  this_time = timestamp
  timestamps.any? { |t| t > this_time }
end

#psObject



174
175
176
177
178
# File 'lib/panoramix/plugin/cfn.rb', line 174

def ps
  if created?
    shell("aws cloudformation describe-stacks --stack-name #{gen_stack_name}")
  end
end

#questionObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/panoramix/plugin/cfn.rb', line 57

def question
  case @stage
  when "pro"
    return true if ENV['CFN_FORCE_DELETE']
    return ask_pro
  when "pre"
    return true if ENV['CFN_FORCE_DELETE']
    return ask_pro
  when "test"
    return true
  when "dev"
    return true
  else
    return false
  end
end

#run_defaultObject

Deafult task



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/panoramix/plugin/cfn.rb', line 148

def run_default
  if created?
    puts "WARNING: #{gen_stack_name} already exists!".red
    return
  end
  env = fill_env @src

  params = ""
  env.each {|k,v| params = params + "ParameterKey=#{k},ParameterValue=#{v} "}

  validate_file @src
  template = "file://#{@src}"

  cmd = "aws cloudformation create-stack \
  --query StackId \
  --stack-name #{gen_stack_name} \
  --template-body #{template} \
  --disable-rollback \
  --parameters #{params}"

  result = shell(cmd, true)[:out]
  stack_id = result.strip

  wait_for_creation stack_id
end

#stack_nameObject

Return stack name



36
37
38
# File 'lib/panoramix/plugin/cfn.rb', line 36

def stack_name
  puts gen_stack_name
end

#timestampObject

Return the stack creation time



75
76
77
78
79
# File 'lib/panoramix/plugin/cfn.rb', line 75

def timestamp
  return Time.at(0) unless @created

  return Time.parse(@created["CreationTime"])
end

#validate_file(path) ⇒ Object

Check wether the file exists



139
140
141
142
143
144
145
# File 'lib/panoramix/plugin/cfn.rb', line 139

def validate_file path
  # Raise error if the file does not exist
  unless File.exists? path
    message = I18n.t('errors.cfn.template_not_found', {:path => path})
    raise(Panoramix::Plugin::DockerUpExceptionError, message)
  end
end

#wait_for_creation(stack_id) ⇒ Object

Wait until the stack is being created



129
130
131
132
133
134
135
136
# File 'lib/panoramix/plugin/cfn.rb', line 129

def wait_for_creation stack_id
  loop do
    status = shell("aws cloudformation describe-stacks --stack #{stack_id} --query Stacks[0].StackStatus --output text", true)[:out].strip
    raise "Creation Failed" if status == "CREATE_FAILED"
    break if status != "CREATE_IN_PROGRESS"
    sleep 30
  end
end