knife-cfn 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/lib/chef/knife/cfn_base.rb +101 -16
 - data/lib/chef/knife/cfn_create.rb +125 -125
 - data/lib/chef/knife/cfn_delete.rb +61 -21
 - data/lib/chef/knife/cfn_describe.rb +40 -0
 - data/lib/chef/knife/cfn_events.rb +53 -13
 - data/lib/chef/knife/cfn_outputs.rb +148 -108
 - data/lib/chef/knife/cfn_resources.rb +126 -86
 - data/lib/chef/knife/cfn_update.rb +66 -26
 - data/lib/chef/knife/cfn_validate.rb +55 -16
 - data/lib/knife-cfn/version.rb +3 -3
 - metadata +13 -19
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: ed956b7bf7624fb88560a3aec0e5bc243b8a0169
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 770c634481f6a69b773fa4602c521f0633b3664b
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: d307cc10dd135f22c375397678232228331ae59cb9429dffc3b0a346169a0c6e7cc74029942ae9f067906715beafeaa5905de0093fecea7a222a7f8ac67dd92b
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 67be89dad9b22c72d132529c8baefaaa9cf430305125e0415405bc959c6918e155d6d409f6358b5464d5747da878c4edeb0085426d5b5c1728a0534f5f17210c
         
     | 
    
        data/lib/chef/knife/cfn_base.rb
    CHANGED
    
    | 
         @@ -1,4 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Author:: Seth Chisamore (<schisamo@chef.io>)
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Copyright:: Copyright (c) 2011-2015 Chef Software, Inc.
         
     | 
| 
      
 4 
     | 
    
         
            +
            # License:: Apache License, Version 2.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
       2 
6 
     | 
    
         
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
       3 
7 
     | 
    
         
             
            # you may not use this file except in compliance with the License.
         
     | 
| 
       4 
8 
     | 
    
         
             
            # You may obtain a copy of the License at
         
     | 
| 
         @@ -30,6 +34,17 @@ class Chef 
     | 
|
| 
       30 
34 
     | 
    
         
             
                        require 'chef/json_compat'
         
     | 
| 
       31 
35 
     | 
    
         
             
                      end
         
     | 
| 
       32 
36 
     | 
    
         | 
| 
      
 37 
     | 
    
         
            +
                      option :aws_credential_file,
         
     | 
| 
      
 38 
     | 
    
         
            +
                        :long => "--aws-credential-file FILE",
         
     | 
| 
      
 39 
     | 
    
         
            +
                        :description => "File containing AWS credentials as used by aws cmdline tools",
         
     | 
| 
      
 40 
     | 
    
         
            +
                        :proc => Proc.new { |key| Chef::Config[:knife][:aws_credential_file] = key }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                      option :aws_profile,
         
     | 
| 
      
 43 
     | 
    
         
            +
                        :long => "--aws-profile PROFILE",
         
     | 
| 
      
 44 
     | 
    
         
            +
                        :description => "AWS profile, from credential file, to use",
         
     | 
| 
      
 45 
     | 
    
         
            +
                        :default => 'default',
         
     | 
| 
      
 46 
     | 
    
         
            +
                        :proc => Proc.new { |key| Chef::Config[:knife][:aws_profile] = key }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
       33 
48 
     | 
    
         
             
                      option :aws_access_key_id,
         
     | 
| 
       34 
49 
     | 
    
         
             
                        :short => "-A ID",
         
     | 
| 
       35 
50 
     | 
    
         
             
                        :long => "--aws-access-key-id KEY",
         
     | 
| 
         @@ -42,27 +57,45 @@ class Chef 
     | 
|
| 
       42 
57 
     | 
    
         
             
                        :description => "Your AWS API Secret Access Key",
         
     | 
| 
       43 
58 
     | 
    
         
             
                        :proc => Proc.new { |key| Chef::Config[:knife][:aws_secret_access_key] = key }
         
     | 
| 
       44 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
                      option :aws_session_token,
         
     | 
| 
      
 61 
     | 
    
         
            +
                        :long => "--aws-session-token TOKEN",
         
     | 
| 
      
 62 
     | 
    
         
            +
                        :description => "Your AWS Session Token, for use with AWS STS Federation or Session Tokens",
         
     | 
| 
      
 63 
     | 
    
         
            +
                        :proc => Proc.new { |key| Chef::Config[:knife][:aws_session_token] = key }
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
       45 
65 
     | 
    
         
             
                      option :region,
         
     | 
| 
       46 
66 
     | 
    
         
             
                        :long => "--region REGION",
         
     | 
| 
       47 
67 
     | 
    
         
             
                        :description => "Your AWS region",
         
     | 
| 
       48 
     | 
    
         
            -
                        :default => "us-east-1",
         
     | 
| 
       49 
68 
     | 
    
         
             
                        :proc => Proc.new { |key| Chef::Config[:knife][:region] = key }
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                      option :use_iam_profile,
         
     | 
| 
      
 71 
     | 
    
         
            +
                        :long => "--use-iam-profile",
         
     | 
| 
      
 72 
     | 
    
         
            +
                        :description => "Use IAM profile assigned to current machine",
         
     | 
| 
      
 73 
     | 
    
         
            +
                        :boolean => true,
         
     | 
| 
      
 74 
     | 
    
         
            +
                        :default => false,
         
     | 
| 
      
 75 
     | 
    
         
            +
                        :proc => Proc.new { |key| Chef::Config[:knife][:use_iam_profile] = key }
         
     | 
| 
       50 
76 
     | 
    
         
             
                    end
         
     | 
| 
       51 
77 
     | 
    
         
             
                  end
         
     | 
| 
       52 
78 
     | 
    
         | 
| 
       53 
79 
     | 
    
         
             
                  def connection
         
     | 
| 
      
 80 
     | 
    
         
            +
                    connection_settings = {
         
     | 
| 
      
 81 
     | 
    
         
            +
            #          :provider => 'AWS',
         
     | 
| 
      
 82 
     | 
    
         
            +
                      :region => locate_config_value(:region)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    }
         
     | 
| 
      
 84 
     | 
    
         
            +
                    if locate_config_value(:use_iam_profile)
         
     | 
| 
      
 85 
     | 
    
         
            +
                      connection_settings[:use_iam_profile] = true
         
     | 
| 
      
 86 
     | 
    
         
            +
                    else
         
     | 
| 
      
 87 
     | 
    
         
            +
                      connection_settings[:aws_access_key_id] = locate_config_value(:aws_access_key_id)
         
     | 
| 
      
 88 
     | 
    
         
            +
                      connection_settings[:aws_secret_access_key] = locate_config_value(:aws_secret_access_key)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      connection_settings[:aws_session_token] = locate_config_value(:aws_session_token)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
       54 
91 
     | 
    
         
             
                    @connection ||= begin
         
     | 
| 
       55 
     | 
    
         
            -
                      connection = 
     | 
| 
       56 
     | 
    
         
            -
                        :aws_access_key_id => Chef::Config[:knife][:aws_access_key_id],
         
     | 
| 
       57 
     | 
    
         
            -
                        :aws_secret_access_key => Chef::Config[:knife][:aws_secret_access_key],
         
     | 
| 
       58 
     | 
    
         
            -
                        :region => locate_config_value(:region)
         
     | 
| 
       59 
     | 
    
         
            -
                      )
         
     | 
| 
      
 92 
     | 
    
         
            +
                      connection = Fog::AWS::CloudFormation.new(connection_settings)
         
     | 
| 
       60 
93 
     | 
    
         
             
                    end
         
     | 
| 
       61 
94 
     | 
    
         
             
                  end
         
     | 
| 
       62 
95 
     | 
    
         | 
| 
       63 
96 
     | 
    
         
             
                  def locate_config_value(key)
         
     | 
| 
       64 
97 
     | 
    
         
             
                    key = key.to_sym
         
     | 
| 
       65 
     | 
    
         
            -
                    Chef::Config[:knife][key] 
     | 
| 
      
 98 
     | 
    
         
            +
                    config[key] || Chef::Config[:knife][key]
         
     | 
| 
       66 
99 
     | 
    
         
             
                  end
         
     | 
| 
       67 
100 
     | 
    
         | 
| 
       68 
101 
     | 
    
         
             
                  def msg_pair(label, value, color=:cyan)
         
     | 
| 
         @@ -71,23 +104,75 @@ class Chef 
     | 
|
| 
       71 
104 
     | 
    
         
             
                    end
         
     | 
| 
       72 
105 
     | 
    
         
             
                  end
         
     | 
| 
       73 
106 
     | 
    
         | 
| 
      
 107 
     | 
    
         
            +
                  def is_image_windows?
         
     | 
| 
      
 108 
     | 
    
         
            +
                    image_info = connection.images.get(@server.image_id)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    return image_info.platform == 'windows'
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
       74 
112 
     | 
    
         
             
                  def validate!(keys=[:aws_access_key_id, :aws_secret_access_key])
         
     | 
| 
       75 
113 
     | 
    
         
             
                    errors = []
         
     | 
| 
       76 
114 
     | 
    
         | 
| 
       77 
     | 
    
         
            -
                     
     | 
| 
       78 
     | 
    
         
            -
                       
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
      
 115 
     | 
    
         
            +
                    unless locate_config_value(:use_iam_profile)
         
     | 
| 
      
 116 
     | 
    
         
            +
                      unless Chef::Config[:knife][:aws_credential_file].nil?
         
     | 
| 
      
 117 
     | 
    
         
            +
                        unless (Chef::Config[:knife].keys & [:aws_access_key_id, :aws_secret_access_key]).empty?
         
     | 
| 
      
 118 
     | 
    
         
            +
                          errors << "Either provide a credentials file or the access key and secret keys but not both."
         
     | 
| 
      
 119 
     | 
    
         
            +
                        end
         
     | 
| 
      
 120 
     | 
    
         
            +
                        # File format:
         
     | 
| 
      
 121 
     | 
    
         
            +
                        # AWSAccessKeyId=somethingsomethingdarkside
         
     | 
| 
      
 122 
     | 
    
         
            +
                        # AWSSecretKey=somethingsomethingcomplete
         
     | 
| 
      
 123 
     | 
    
         
            +
                        #               OR
         
     | 
| 
      
 124 
     | 
    
         
            +
                        # [default]
         
     | 
| 
      
 125 
     | 
    
         
            +
                        # aws_access_key_id = somethingsomethingdarkside
         
     | 
| 
      
 126 
     | 
    
         
            +
                        # aws_secret_access_key = somethingsomethingdarkside
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                        aws_creds = ini_parse(File.read(Chef::Config[:knife][:aws_credential_file]))
         
     | 
| 
      
 129 
     | 
    
         
            +
                        profile = Chef::Config[:knife][:aws_profile] || 'default'
         
     | 
| 
      
 130 
     | 
    
         
            +
                        entries = aws_creds.values.first.has_key?("AWSAccessKeyId") ? aws_creds.values.first : aws_creds[profile]
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                        Chef::Config[:knife][:aws_access_key_id] = entries['AWSAccessKeyId'] || entries['aws_access_key_id']
         
     | 
| 
      
 133 
     | 
    
         
            +
                        Chef::Config[:knife][:aws_secret_access_key] = entries['AWSSecretKey'] || entries['aws_secret_access_key']
         
     | 
| 
      
 134 
     | 
    
         
            +
                      end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                      keys.each do |k|
         
     | 
| 
      
 137 
     | 
    
         
            +
                        pretty_key = k.to_s.gsub(/_/, ' ').gsub(/\w+/){ |w| (w =~ /(ssh)|(aws)/i) ? w.upcase  : w.capitalize }
         
     | 
| 
      
 138 
     | 
    
         
            +
                        if Chef::Config[:knife][k].nil?
         
     | 
| 
      
 139 
     | 
    
         
            +
                          errors << "You did not provide a valid '#{pretty_key}' value."
         
     | 
| 
      
 140 
     | 
    
         
            +
                        end
         
     | 
| 
       81 
141 
     | 
    
         
             
                      end
         
     | 
| 
       82 
     | 
    
         
            -
                    end
         
     | 
| 
       83 
142 
     | 
    
         | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
      
 143 
     | 
    
         
            +
                      if errors.each{|e| ui.error(e)}.any?
         
     | 
| 
      
 144 
     | 
    
         
            +
                        exit 1
         
     | 
| 
      
 145 
     | 
    
         
            +
                      end
         
     | 
| 
       86 
146 
     | 
    
         
             
                    end
         
     | 
| 
       87 
147 
     | 
    
         
             
                  end
         
     | 
| 
       88 
148 
     | 
    
         | 
| 
       89 
149 
     | 
    
         
             
                end
         
     | 
| 
       90 
     | 
    
         
            -
              end
         
     | 
| 
       91 
     | 
    
         
            -
            end
         
     | 
| 
       92 
150 
     | 
    
         | 
| 
      
 151 
     | 
    
         
            +
                def iam_name_from_profile(profile)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  # The IAM profile object only contains the name as part of the arn
         
     | 
| 
      
 153 
     | 
    
         
            +
                  if profile && profile.key?('arn')
         
     | 
| 
      
 154 
     | 
    
         
            +
                    name = profile['arn'].split('/')[-1]
         
     | 
| 
      
 155 
     | 
    
         
            +
                  end
         
     | 
| 
      
 156 
     | 
    
         
            +
                  name ||= ''
         
     | 
| 
      
 157 
     | 
    
         
            +
                end
         
     | 
| 
       93 
158 
     | 
    
         | 
| 
      
 159 
     | 
    
         
            +
                def ini_parse(file)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  current_section = {}
         
     | 
| 
      
 161 
     | 
    
         
            +
                  map = {}
         
     | 
| 
      
 162 
     | 
    
         
            +
                  file.each_line do |line|
         
     | 
| 
      
 163 
     | 
    
         
            +
                    line = line.split(/^|\s;/).first # remove comments
         
     | 
| 
      
 164 
     | 
    
         
            +
                    section = line.match(/^\s*\[([^\[\]]+)\]\s*$/) unless line.nil?
         
     | 
| 
      
 165 
     | 
    
         
            +
                    if section
         
     | 
| 
      
 166 
     | 
    
         
            +
                      current_section = section[1]
         
     | 
| 
      
 167 
     | 
    
         
            +
                    elsif current_section
         
     | 
| 
      
 168 
     | 
    
         
            +
                      item = line.match(/^\s*(.+?)\s*=\s*(.+?)\s*$/) unless line.nil?
         
     | 
| 
      
 169 
     | 
    
         
            +
                      if item
         
     | 
| 
      
 170 
     | 
    
         
            +
                        map[current_section] ||= {}
         
     | 
| 
      
 171 
     | 
    
         
            +
                        map[current_section][item[1]] = item[2]
         
     | 
| 
      
 172 
     | 
    
         
            +
                      end
         
     | 
| 
      
 173 
     | 
    
         
            +
                    end
         
     | 
| 
      
 174 
     | 
    
         
            +
                  end
         
     | 
| 
      
 175 
     | 
    
         
            +
                  map
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
              end
         
     | 
| 
      
 178 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,125 +1,125 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #
         
     | 
| 
       2 
     | 
    
         
            -
            # Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
       3 
     | 
    
         
            -
            # you may not use this file except in compliance with the License.
         
     | 
| 
       4 
     | 
    
         
            -
            # You may obtain a copy of the License at
         
     | 
| 
       5 
     | 
    
         
            -
            #
         
     | 
| 
       6 
     | 
    
         
            -
            #     http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
       7 
     | 
    
         
            -
            #
         
     | 
| 
       8 
     | 
    
         
            -
            # Unless required by applicable law or agreed to in writing, software
         
     | 
| 
       9 
     | 
    
         
            -
            # distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
       10 
     | 
    
         
            -
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
       11 
     | 
    
         
            -
            # See the License for the specific language governing permissions and
         
     | 
| 
       12 
     | 
    
         
            -
            # limitations under the License.
         
     | 
| 
       13 
     | 
    
         
            -
            #
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            require 'chef/knife'
         
     | 
| 
       16 
     | 
    
         
            -
            require 'chef/knife/cfn_base'
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            class Chef
         
     | 
| 
       19 
     | 
    
         
            -
              class Knife
         
     | 
| 
       20 
     | 
    
         
            -
                class CfnCreate < Chef::Knife::CfnBase
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                  deps do
         
     | 
| 
       23 
     | 
    
         
            -
                    require 'fog'
         
     | 
| 
       24 
     | 
    
         
            -
                    require 'readline'
         
     | 
| 
       25 
     | 
    
         
            -
                    require 'chef/json_compat'
         
     | 
| 
       26 
     | 
    
         
            -
                    require 'chef/knife/bootstrap'
         
     | 
| 
       27 
     | 
    
         
            -
                    Chef::Knife::Bootstrap.load_deps
         
     | 
| 
       28 
     | 
    
         
            -
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  banner "knife cfn create <stack name> (options)"
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                  option :capabilities,
         
     | 
| 
       33 
     | 
    
         
            -
                    :short => "-C CAPABILITY..",
         
     | 
| 
       34 
     | 
    
         
            -
                    :long => "--capabilities CAPABILITY1,CAPABILITY2,CAPABILITY3..",
         
     | 
| 
       35 
     | 
    
         
            -
                    :description => "The explicitly approved capabilities that may be used during this stack creation",
         
     | 
| 
       36 
     | 
    
         
            -
                    :proc => Proc.new { |capabilities| capabilities.split(',') } 
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                  option :disable_rollback,
         
     | 
| 
       39 
     | 
    
         
            -
                    :short => "-d",
         
     | 
| 
       40 
     | 
    
         
            -
                    :long => "--disable-rollback",
         
     | 
| 
       41 
     | 
    
         
            -
                    :description => "Flag to disable rollback of created resources when failures are encountered during stack creation. The default value is 'false'",
         
     | 
| 
       42 
     | 
    
         
            -
                    :proc => Proc.new { |d| Chef::Config[:knife][:disable_rollback] = "true" }
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  option :template_file,
         
     | 
| 
       45 
     | 
    
         
            -
                    :short => "-f TEMPLATE_FILE",
         
     | 
| 
       46 
     | 
    
         
            -
                    :long => "--template-file TEMPLATE_FILE",
         
     | 
| 
       47 
     | 
    
         
            -
                    :description => "Path to the file that contains the template",
         
     | 
| 
       48 
     | 
    
         
            -
                    :proc => Proc.new { |f| Chef::Config[:knife][:template_file] = f }
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  option :notification_arns,
         
     | 
| 
       51 
     | 
    
         
            -
                    :short => "-n NOTIFICATION_ARN1,NOTIFICATION_ARN2,NOTIFICATION_ARN3..",
         
     | 
| 
       52 
     | 
    
         
            -
                    :long => "--notification-arns VALUE1,VALUE2,VALUE3..",
         
     | 
| 
       53 
     | 
    
         
            -
                    :description => "SNS ARNs to receive notification about the stack",
         
     | 
| 
       54 
     | 
    
         
            -
                    :proc => Proc.new { |notification_arns| notification_arns.split(',') }
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                  option :parameters,
         
     | 
| 
       57 
     | 
    
         
            -
                    :short => "-p 'key1=value1;key2=value2...'",
         
     | 
| 
       58 
     | 
    
         
            -
                    :long => "--parameters 'key1=value1;key2=value2...'",
         
     | 
| 
       59 
     | 
    
         
            -
                    :description => "Parameter values used to create the stack",
         
     | 
| 
       60 
     | 
    
         
            -
                    :proc => Proc.new { |parameters| parameters.split(';') }
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                  option :timeout,
         
     | 
| 
       63 
     | 
    
         
            -
                    :short => "-t TIMEOUT_VALUE",
         
     | 
| 
       64 
     | 
    
         
            -
                    :long => "--timeout TIMEOUT_VALUE",
         
     | 
| 
       65 
     | 
    
         
            -
                    :description => " Stack creation timeout in minutes",
         
     | 
| 
       66 
     | 
    
         
            -
                    :proc => Proc.new { |t| Chef::Config[:knife][:timeout] = t } 
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                  option :template_url,
         
     | 
| 
       69 
     | 
    
         
            -
                    :short => "-u TEMPLATE_URL",
         
     | 
| 
       70 
     | 
    
         
            -
                    :long => "--template-file TEMPLATE_URL",
         
     | 
| 
       71 
     | 
    
         
            -
                    :description => "Path of the URL that contains the template. This must be a reference to a template in an S3 bucket in the same region that the stack will be created in",
         
     | 
| 
       72 
     | 
    
         
            -
                    :proc => Proc.new { |u| Chef::Config[:knife][:template_url] = u }
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                  def run
         
     | 
| 
       75 
     | 
    
         
            -
                    $stdout.sync = true
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                    validate!
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                    stack_name = @name_args[0]
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                      exit 1
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                    begin
         
     | 
| 
       88 
     | 
    
         
            -
                      response = connection.create_stack(stack_name, create_create_def)
         
     | 
| 
       89 
     | 
    
         
            -
                      rescue Excon::Errors::BadRequest => e
         
     | 
| 
       90 
     | 
    
         
            -
                        i= e.response.body.index("<Message>")
         
     | 
| 
       91 
     | 
    
         
            -
                        j = e.response.body.index("</Message>")
         
     | 
| 
       92 
     | 
    
         
            -
                        if !i.nil? and !j.nil?
         
     | 
| 
       93 
     | 
    
         
            -
                          ui.error(e.response.body[i+9,j-i-9])
         
     | 
| 
       94 
     | 
    
         
            -
                        else
         
     | 
| 
       95 
     | 
    
         
            -
                          print "\n#{e.response.body}"
         
     | 
| 
       96 
     | 
    
         
            -
                        end
         
     | 
| 
       97 
     | 
    
         
            -
                        exit 1
         
     | 
| 
       98 
     | 
    
         
            -
                      else
         
     | 
| 
       99 
     | 
    
         
            -
                        message = "Stack #{stack_name} creation started"
         
     | 
| 
       100 
     | 
    
         
            -
                        print "\n#{ui.color(message, :green)}\n"
         
     | 
| 
       101 
     | 
    
         
            -
                      end
         
     | 
| 
       102 
     | 
    
         
            -
                    end 
     | 
| 
       103 
     | 
    
         
            -
                  end 
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
                  def create_create_def
         
     | 
| 
       106 
     | 
    
         
            -
                    create_def = {} 
     | 
| 
       107 
     | 
    
         
            -
                    template_file = locate_config_value(:template_file)
         
     | 
| 
       108 
     | 
    
         
            -
                    if template_file != nil and template_file != ""
         
     | 
| 
       109 
     | 
    
         
            -
                      doc = File.open(template_file, 'rb') { |file| file.read }
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
                    create_def['DisableRollback'] = locate_config_value(:disable_rollback)
         
     | 
| 
       115 
     | 
    
         
            -
                    create_def['NotificationARNs'] = locate_config_value(:notification_arns)
         
     | 
| 
       116 
     | 
    
         
            -
                    hashed_parameters={}
         
     | 
| 
       117 
     | 
    
         
            -
                    parameters = locate_config_value(:parameters)
         
     | 
| 
       118 
     | 
    
         
            -
                    parameters.map{ |t| key,val=t.split('='); hashed_parameters[key]=val} unless parameters.nil?
         
     | 
| 
       119 
     | 
    
         
            -
                    create_def['Parameters'] = hashed_parameters
         
     | 
| 
       120 
     | 
    
         
            -
                    create_def['TimeoutInMinutes'] = locate_config_value(:timeout)
         
     | 
| 
       121 
     | 
    
         
            -
                    create_def
         
     | 
| 
       122 
     | 
    
         
            -
                  end
         
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
              end
         
     | 
| 
       125 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 3 
     | 
    
         
            +
            # you may not use this file except in compliance with the License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            # You may obtain a copy of the License at
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            #     http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 9 
     | 
    
         
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 10 
     | 
    
         
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 11 
     | 
    
         
            +
            # See the License for the specific language governing permissions and
         
     | 
| 
      
 12 
     | 
    
         
            +
            # limitations under the License.
         
     | 
| 
      
 13 
     | 
    
         
            +
            #
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            require 'chef/knife'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'chef/knife/cfn_base'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            class Chef
         
     | 
| 
      
 19 
     | 
    
         
            +
              class Knife
         
     | 
| 
      
 20 
     | 
    
         
            +
                class CfnCreate < Chef::Knife::CfnBase
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  deps do
         
     | 
| 
      
 23 
     | 
    
         
            +
                    require 'fog'
         
     | 
| 
      
 24 
     | 
    
         
            +
                    require 'readline'
         
     | 
| 
      
 25 
     | 
    
         
            +
                    require 'chef/json_compat'
         
     | 
| 
      
 26 
     | 
    
         
            +
                    require 'chef/knife/bootstrap'
         
     | 
| 
      
 27 
     | 
    
         
            +
                    Chef::Knife::Bootstrap.load_deps
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  banner "knife cfn create <stack name> (options)"
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  option :capabilities,
         
     | 
| 
      
 33 
     | 
    
         
            +
                    :short => "-C CAPABILITY..",
         
     | 
| 
      
 34 
     | 
    
         
            +
                    :long => "--capabilities CAPABILITY1,CAPABILITY2,CAPABILITY3..",
         
     | 
| 
      
 35 
     | 
    
         
            +
                    :description => "The explicitly approved capabilities that may be used during this stack creation",
         
     | 
| 
      
 36 
     | 
    
         
            +
                    :proc => Proc.new { |capabilities| capabilities.split(',') }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  option :disable_rollback,
         
     | 
| 
      
 39 
     | 
    
         
            +
                    :short => "-d",
         
     | 
| 
      
 40 
     | 
    
         
            +
                    :long => "--disable-rollback",
         
     | 
| 
      
 41 
     | 
    
         
            +
                    :description => "Flag to disable rollback of created resources when failures are encountered during stack creation. The default value is 'false'",
         
     | 
| 
      
 42 
     | 
    
         
            +
                    :proc => Proc.new { |d| Chef::Config[:knife][:disable_rollback] = "true" }
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  option :template_file,
         
     | 
| 
      
 45 
     | 
    
         
            +
                    :short => "-f TEMPLATE_FILE",
         
     | 
| 
      
 46 
     | 
    
         
            +
                    :long => "--template-file TEMPLATE_FILE",
         
     | 
| 
      
 47 
     | 
    
         
            +
                    :description => "Path to the file that contains the template",
         
     | 
| 
      
 48 
     | 
    
         
            +
                    :proc => Proc.new { |f| Chef::Config[:knife][:template_file] = f }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  option :notification_arns,
         
     | 
| 
      
 51 
     | 
    
         
            +
                    :short => "-n NOTIFICATION_ARN1,NOTIFICATION_ARN2,NOTIFICATION_ARN3..",
         
     | 
| 
      
 52 
     | 
    
         
            +
                    :long => "--notification-arns VALUE1,VALUE2,VALUE3..",
         
     | 
| 
      
 53 
     | 
    
         
            +
                    :description => "SNS ARNs to receive notification about the stack",
         
     | 
| 
      
 54 
     | 
    
         
            +
                    :proc => Proc.new { |notification_arns| notification_arns.split(',') }
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  option :parameters,
         
     | 
| 
      
 57 
     | 
    
         
            +
                    :short => "-p 'key1=value1;key2=value2...'",
         
     | 
| 
      
 58 
     | 
    
         
            +
                    :long => "--parameters 'key1=value1;key2=value2...'",
         
     | 
| 
      
 59 
     | 
    
         
            +
                    :description => "Parameter values used to create the stack",
         
     | 
| 
      
 60 
     | 
    
         
            +
                    :proc => Proc.new { |parameters| parameters.split(';') }
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  option :timeout,
         
     | 
| 
      
 63 
     | 
    
         
            +
                    :short => "-t TIMEOUT_VALUE",
         
     | 
| 
      
 64 
     | 
    
         
            +
                    :long => "--timeout TIMEOUT_VALUE",
         
     | 
| 
      
 65 
     | 
    
         
            +
                    :description => " Stack creation timeout in minutes",
         
     | 
| 
      
 66 
     | 
    
         
            +
                    :proc => Proc.new { |t| Chef::Config[:knife][:timeout] = t }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  option :template_url,
         
     | 
| 
      
 69 
     | 
    
         
            +
                    :short => "-u TEMPLATE_URL",
         
     | 
| 
      
 70 
     | 
    
         
            +
                    :long => "--template-file TEMPLATE_URL",
         
     | 
| 
      
 71 
     | 
    
         
            +
                    :description => "Path of the URL that contains the template. This must be a reference to a template in an S3 bucket in the same region that the stack will be created in",
         
     | 
| 
      
 72 
     | 
    
         
            +
                    :proc => Proc.new { |u| Chef::Config[:knife][:template_url] = u }
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 75 
     | 
    
         
            +
                    $stdout.sync = true
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    validate!
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    stack_name = @name_args[0]
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    if stack_name.nil?
         
     | 
| 
      
 82 
     | 
    
         
            +
                      show_usage
         
     | 
| 
      
 83 
     | 
    
         
            +
                      ui.error("You must specify a stack name")
         
     | 
| 
      
 84 
     | 
    
         
            +
                      exit 1
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 88 
     | 
    
         
            +
                      response = connection.create_stack(stack_name, create_create_def)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      rescue Excon::Errors::BadRequest => e
         
     | 
| 
      
 90 
     | 
    
         
            +
                        i= e.response.body.index("<Message>")
         
     | 
| 
      
 91 
     | 
    
         
            +
                        j = e.response.body.index("</Message>")
         
     | 
| 
      
 92 
     | 
    
         
            +
                        if !i.nil? and !j.nil?
         
     | 
| 
      
 93 
     | 
    
         
            +
                          ui.error(e.response.body[i+9,j-i-9])
         
     | 
| 
      
 94 
     | 
    
         
            +
                        else
         
     | 
| 
      
 95 
     | 
    
         
            +
                          print "\n#{e.response.body}"
         
     | 
| 
      
 96 
     | 
    
         
            +
                        end
         
     | 
| 
      
 97 
     | 
    
         
            +
                        exit 1
         
     | 
| 
      
 98 
     | 
    
         
            +
                      else
         
     | 
| 
      
 99 
     | 
    
         
            +
                        message = "Stack #{stack_name} creation started"
         
     | 
| 
      
 100 
     | 
    
         
            +
                        print "\n#{ui.color(message, :green)}\n"
         
     | 
| 
      
 101 
     | 
    
         
            +
                      end
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  def create_create_def
         
     | 
| 
      
 106 
     | 
    
         
            +
                    create_def = {}
         
     | 
| 
      
 107 
     | 
    
         
            +
                    template_file = locate_config_value(:template_file)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    if template_file != nil and template_file != ""
         
     | 
| 
      
 109 
     | 
    
         
            +
                      doc = File.open(template_file, 'rb') { |file| file.read }
         
     | 
| 
      
 110 
     | 
    
         
            +
                      create_def['TemplateBody'] = doc
         
     | 
| 
      
 111 
     | 
    
         
            +
                    end
         
     | 
| 
      
 112 
     | 
    
         
            +
                    create_def['TemplateURL'] = locate_config_value(:template_url)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    create_def['Capabilities'] = locate_config_value(:capabilities)
         
     | 
| 
      
 114 
     | 
    
         
            +
                    create_def['DisableRollback'] = locate_config_value(:disable_rollback)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    create_def['NotificationARNs'] = locate_config_value(:notification_arns)
         
     | 
| 
      
 116 
     | 
    
         
            +
                    hashed_parameters={}
         
     | 
| 
      
 117 
     | 
    
         
            +
                    parameters = locate_config_value(:parameters)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    parameters.map{ |t| key,val=t.split('='); hashed_parameters[key]=val} unless parameters.nil?
         
     | 
| 
      
 119 
     | 
    
         
            +
                    create_def['Parameters'] = hashed_parameters
         
     | 
| 
      
 120 
     | 
    
         
            +
                    create_def['TimeoutInMinutes'] = locate_config_value(:timeout)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    create_def
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -26,28 +26,68 @@ class Chef 
     | 
|
| 
       26 
26 
     | 
    
         
             
                    require 'chef/knife/bootstrap'
         
     | 
| 
       27 
27 
     | 
    
         
             
                    Chef::Knife::Bootstrap.load_deps
         
     | 
| 
       28 
28 
     | 
    
         
             
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       30 
30 
     | 
    
         
             
                  banner "knife cfn delete <stack name>"
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  option :aws_credential_file,
         
     | 
| 
      
 33 
     | 
    
         
            +
                    :long => "--aws-credential-file FILE",
         
     | 
| 
      
 34 
     | 
    
         
            +
                    :description => "File containing AWS credentials as used by aws cmdline tools",
         
     | 
| 
      
 35 
     | 
    
         
            +
                    :proc => Proc.new { |key| Chef::Config[:knife][:aws_credential_file] = key }
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  option :aws_profile,
         
     | 
| 
      
 38 
     | 
    
         
            +
                    :long => "--aws-profile PROFILE",
         
     | 
| 
      
 39 
     | 
    
         
            +
                    :description => "AWS profile, from credential file, to use",
         
     | 
| 
      
 40 
     | 
    
         
            +
                    :default => 'default',
         
     | 
| 
      
 41 
     | 
    
         
            +
                    :proc => Proc.new { |key| Chef::Config[:knife][:aws_profile] = key }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  option :aws_access_key_id,
         
     | 
| 
      
 44 
     | 
    
         
            +
                    :short => "-A ID",
         
     | 
| 
      
 45 
     | 
    
         
            +
                    :long => "--aws-access-key-id KEY",
         
     | 
| 
      
 46 
     | 
    
         
            +
                    :description => "Your AWS Access Key ID",
         
     | 
| 
      
 47 
     | 
    
         
            +
                    :proc => Proc.new { |key| Chef::Config[:knife][:aws_access_key_id] = key }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  option :aws_secret_access_key,
         
     | 
| 
      
 50 
     | 
    
         
            +
                    :short => "-K SECRET",
         
     | 
| 
      
 51 
     | 
    
         
            +
                    :long => "--aws-secret-access-key SECRET",
         
     | 
| 
      
 52 
     | 
    
         
            +
                    :description => "Your AWS API Secret Access Key",
         
     | 
| 
      
 53 
     | 
    
         
            +
                    :proc => Proc.new { |key| Chef::Config[:knife][:aws_secret_access_key] = key }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  option :aws_session_token,
         
     | 
| 
      
 56 
     | 
    
         
            +
                    :long => "--aws-session-token TOKEN",
         
     | 
| 
      
 57 
     | 
    
         
            +
                    :description => "Your AWS Session Token, for use with AWS STS Federation or Session Tokens",
         
     | 
| 
      
 58 
     | 
    
         
            +
                    :proc => Proc.new { |key| Chef::Config[:knife][:aws_session_token] = key }
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  option :region,
         
     | 
| 
      
 61 
     | 
    
         
            +
                    :long => "--region REGION",
         
     | 
| 
      
 62 
     | 
    
         
            +
                    :description => "Your AWS region",
         
     | 
| 
      
 63 
     | 
    
         
            +
                    :proc => Proc.new { |key| Chef::Config[:knife][:region] = key }
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  option :use_iam_profile,
         
     | 
| 
      
 66 
     | 
    
         
            +
                    :long => "--use-iam-profile",
         
     | 
| 
      
 67 
     | 
    
         
            +
                    :description => "Use IAM profile assigned to current machine",
         
     | 
| 
      
 68 
     | 
    
         
            +
                    :boolean => true,
         
     | 
| 
      
 69 
     | 
    
         
            +
                    :default => false,
         
     | 
| 
      
 70 
     | 
    
         
            +
                    :proc => Proc.new { |key| Chef::Config[:knife][:use_iam_profile] = key }
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
       32 
72 
     | 
    
         
             
                  def run
         
     | 
| 
       33 
73 
     | 
    
         
             
                    $stdout.sync = true
         
     | 
| 
       34 
74 
     | 
    
         | 
| 
       35 
75 
     | 
    
         
             
                    validate!
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
       37 
77 
     | 
    
         
             
                    stack_name = @name_args[0]
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    if stack_name.nil?
         
     | 
| 
      
 80 
     | 
    
         
            +
                      show_usage
         
     | 
| 
      
 81 
     | 
    
         
            +
                      ui.error("You must specify a stack name")
         
     | 
| 
      
 82 
     | 
    
         
            +
                      exit 1
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
       45 
85 
     | 
    
         
             
                    options = {}
         
     | 
| 
       46 
86 
     | 
    
         
             
                    options['StackName'] = stack_name
         
     | 
| 
       47 
87 
     | 
    
         
             
                    begin
         
     | 
| 
       48 
88 
     | 
    
         
             
                      response = connection.describe_stacks(options)
         
     | 
| 
       49 
     | 
    
         
            -
                    rescue Excon::Errors::BadRequest => e 
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
      
 89 
     | 
    
         
            +
                    rescue Excon::Errors::BadRequest => e
         
     | 
| 
      
 90 
     | 
    
         
            +
                      i= e.response.body.index("<Message>")
         
     | 
| 
       51 
91 
     | 
    
         
             
                      j = e.response.body.index("</Message>")
         
     | 
| 
       52 
92 
     | 
    
         
             
                      if !i.nil? and !j.nil?
         
     | 
| 
       53 
93 
     | 
    
         
             
                        ui.error(e.response.body[i+9,j-i-9])
         
     | 
| 
         @@ -55,15 +95,15 @@ class Chef 
     | 
|
| 
       55 
95 
     | 
    
         
             
                        print "\n#{e.response.body}"
         
     | 
| 
       56 
96 
     | 
    
         
             
                      end
         
     | 
| 
       57 
97 
     | 
    
         
             
                      exit 1
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
      
 98 
     | 
    
         
            +
                    end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                    puts "\n"
         
     | 
| 
      
 101 
     | 
    
         
            +
                    confirm("Do you really want to delete stack #{stack_name}")
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       63 
103 
     | 
    
         
             
                    begin
         
     | 
| 
       64 
104 
     | 
    
         
             
                      response = connection.delete_stack(stack_name)
         
     | 
| 
       65 
105 
     | 
    
         
             
                    rescue Excon::Errors::BadRequest => e
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
      
 106 
     | 
    
         
            +
                      i= e.response.body.index("<Message>")
         
     | 
| 
       67 
107 
     | 
    
         
             
                      j = e.response.body.index("</Message>")
         
     | 
| 
       68 
108 
     | 
    
         
             
                      if !i.nil? and !j.nil?
         
     | 
| 
       69 
109 
     | 
    
         
             
                        ui.error(e.response.body[i+9,j-i-9])
         
     | 
| 
         @@ -74,8 +114,8 @@ class Chef 
     | 
|
| 
       74 
114 
     | 
    
         
             
                    else
         
     | 
| 
       75 
115 
     | 
    
         
             
                      message = "Stack #{stack_name} delete started"
         
     | 
| 
       76 
116 
     | 
    
         
             
                      print "\n#{ui.color(message, :green)}"
         
     | 
| 
       77 
     | 
    
         
            -
                    end 
     | 
| 
       78 
     | 
    
         
            -
                  end 
     | 
| 
       79 
     | 
    
         
            -
                end 
     | 
| 
      
 117 
     | 
    
         
            +
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
                  end
         
     | 
| 
      
 119 
     | 
    
         
            +
                end
         
     | 
| 
       80 
120 
     | 
    
         
             
              end
         
     | 
| 
       81 
121 
     | 
    
         
             
            end
         
     |