leap_cli 1.7.3 → 1.7.4
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 +4 -4
- data/bin/leap +3 -12
- data/lib/leap_cli/commands/compile.rb +122 -11
- data/lib/leap_cli/commands/deploy.rb +2 -2
- data/lib/leap_cli/commands/facts.rb +4 -4
- data/lib/leap_cli/commands/list.rb +6 -3
- data/lib/leap_cli/commands/pre.rb +4 -0
- data/lib/leap_cli/commands/vagrant.rb +17 -8
- data/lib/leap_cli/config/filter.rb +3 -0
- data/lib/leap_cli/config/manager.rb +11 -3
- data/lib/leap_cli/config/object.rb +7 -3
- data/lib/leap_cli/config/secrets.rb +2 -0
- data/lib/leap_cli/log.rb +1 -1
- data/lib/leap_cli/remote/leap_plugin.rb +4 -2
- data/lib/leap_cli/version.rb +2 -2
- data/lib/leap_cli.rb +1 -1
- metadata +12 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: fde4e852d415bcc30ed9d48a65e5b264ac999d4f
         | 
| 4 | 
            +
              data.tar.gz: a3658cdc96431cf991509bbd48e0d3aa4afdadc3
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 5ab70f0f7a3a39e09ccac39dd3fb69d7dd6a5b47366f1251b24dbfc283ada437ceed72ce1a9e5a27b96d620e7206da597e1c482c0722aca3d2116db115b5f9e5
         | 
| 7 | 
            +
              data.tar.gz: 9838e7df5040c85caae31cb394edad4da7f4f809c15c3e5046707e8d4ea97195c75f49d0947df289c91bfaad3fe1549249bf1409b2bce07d49ecae0bfdb9ddd7
         | 
    
        data/bin/leap
    CHANGED
    
    | @@ -18,20 +18,11 @@ LEAP_CLI_BASE_DIR = File.expand_path('..', File.dirname(File.symlink?(__FILE__) | |
| 18 18 | 
             
            ORIGINAL_ARGV = ARGV.dup
         | 
| 19 19 |  | 
| 20 20 | 
             
            begin
         | 
| 21 | 
            +
              # First, try to load the leap_cli code that is local to this `leap` command.
         | 
| 22 | 
            +
              # If that fails, then we try to load leap_cli as a gem.
         | 
| 23 | 
            +
              require File.join(LEAP_CLI_BASE_DIR, 'lib','leap_cli','load_paths')
         | 
| 21 24 | 
             
              require 'leap_cli'
         | 
| 22 25 | 
             
            rescue LoadError
         | 
| 23 | 
            -
              #
         | 
| 24 | 
            -
              # When developing a gem with a command, you normally use `bundle exec bin/command-name`
         | 
| 25 | 
            -
              # to run your app. At install-time, RubyGems will make sure lib, etc. are in the load path,
         | 
| 26 | 
            -
              # so that you can run the command directly.
         | 
| 27 | 
            -
              #
         | 
| 28 | 
            -
              # However, I don't like using 'bundle exec'. It is slow, and limits which directory you can
         | 
| 29 | 
            -
              # run in. So, instead, we fall back to some path manipulation hackery.
         | 
| 30 | 
            -
              #
         | 
| 31 | 
            -
              # This allows you to run the command directly while developing the gem, and also lets you
         | 
| 32 | 
            -
              # run from anywhere (I like to link 'bin/leap' to /usr/local/bin/leap).
         | 
| 33 | 
            -
              #
         | 
| 34 | 
            -
              require File.join(LEAP_CLI_BASE_DIR, 'lib','leap_cli','load_paths')
         | 
| 35 26 | 
             
              require 'leap_cli'
         | 
| 36 27 | 
             
            end
         | 
| 37 28 |  | 
| @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            require 'socket'
         | 
| 1 2 |  | 
| 2 3 | 
             
            module LeapCli
         | 
| 3 4 | 
             
              module Commands
         | 
| @@ -14,12 +15,16 @@ module LeapCli | |
| 14 15 | 
             
                      end
         | 
| 15 16 | 
             
                      if environment
         | 
| 16 17 | 
             
                        if manager.environment_names.include?(environment)
         | 
| 17 | 
            -
                          compile_hiera_files(manager.filter([environment]))
         | 
| 18 | 
            +
                          compile_hiera_files(manager.filter([environment]), false)
         | 
| 18 19 | 
             
                        else
         | 
| 19 20 | 
             
                          bail! "There is no environment named `#{environment}`."
         | 
| 20 21 | 
             
                        end
         | 
| 21 22 | 
             
                      else
         | 
| 22 | 
            -
                         | 
| 23 | 
            +
                        clean_export = LeapCli.leapfile.environment.nil?
         | 
| 24 | 
            +
                        compile_hiera_files(manager.filter, clean_export)
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
                      if file_exists?(:static_web_readme)
         | 
| 27 | 
            +
                        compile_provider_json(environment)
         | 
| 23 28 | 
             
                      end
         | 
| 24 29 | 
             
                    end
         | 
| 25 30 | 
             
                  end
         | 
| @@ -31,20 +36,26 @@ module LeapCli | |
| 31 36 | 
             
                    end
         | 
| 32 37 | 
             
                  end
         | 
| 33 38 |  | 
| 39 | 
            +
                  c.desc "Compile provider.json bootstrap files for your provider."
         | 
| 40 | 
            +
                  c.command 'provider.json' do |provider|
         | 
| 41 | 
            +
                    provider.action do |global_options, options, args|
         | 
| 42 | 
            +
                      compile_provider_json
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 34 46 | 
             
                  c.default_command :all
         | 
| 35 47 | 
             
                end
         | 
| 36 48 |  | 
| 37 49 | 
             
                protected
         | 
| 38 50 |  | 
| 39 | 
            -
                 | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 51 | 
            +
                #
         | 
| 52 | 
            +
                # a "clean" export of secrets will also remove keys that are no longer used,
         | 
| 53 | 
            +
                # but this should not be done if we are not examining all possible nodes.
         | 
| 54 | 
            +
                #
         | 
| 55 | 
            +
                def compile_hiera_files(nodes, clean_export)
         | 
| 56 | 
            +
                  update_compiled_ssh_configs # must come first
         | 
| 57 | 
            +
                  sanity_check(nodes)
         | 
| 44 58 | 
             
                  manager.export_nodes(nodes)
         | 
| 45 | 
            -
                  # a "clean" export of secrets will also remove keys that are no longer used,
         | 
| 46 | 
            -
                  # but this should not be done if we are not examining all possible nodes.
         | 
| 47 | 
            -
                  clean_export = nodes.nil?
         | 
| 48 59 | 
             
                  manager.export_secrets(clean_export)
         | 
| 49 60 | 
             
                end
         | 
| 50 61 |  | 
| @@ -54,6 +65,34 @@ module LeapCli | |
| 54 65 | 
             
                  update_known_hosts
         | 
| 55 66 | 
             
                end
         | 
| 56 67 |  | 
| 68 | 
            +
                def sanity_check(nodes)
         | 
| 69 | 
            +
                  # confirm that every node has a unique ip address
         | 
| 70 | 
            +
                  ips = {}
         | 
| 71 | 
            +
                  nodes.pick_fields('ip_address').each do |name, ip_address|
         | 
| 72 | 
            +
                    if ips.key?(ip_address)
         | 
| 73 | 
            +
                      bail! {
         | 
| 74 | 
            +
                        log(:fatal_error, "Every node must have its own IP address.") {
         | 
| 75 | 
            +
                          log "Nodes `#{name}` and `#{ips[ip_address]}` are both configured with `#{ip_address}`."
         | 
| 76 | 
            +
                        }
         | 
| 77 | 
            +
                      }
         | 
| 78 | 
            +
                    else
         | 
| 79 | 
            +
                      ips[ip_address] = name
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                  # confirm that the IP address of this machine is not also used for a node.
         | 
| 83 | 
            +
                  Socket.ip_address_list.each do |addrinfo|
         | 
| 84 | 
            +
                    if !addrinfo.ipv4_private? && ips.key?(addrinfo.ip_address)
         | 
| 85 | 
            +
                      ip = addrinfo.ip_address
         | 
| 86 | 
            +
                      name = ips[ip]
         | 
| 87 | 
            +
                      bail! {
         | 
| 88 | 
            +
                        log(:fatal_error, "Something is very wrong. The `leap` command must only be run on your sysadmin machine, not on a provider node.") {
         | 
| 89 | 
            +
                          log "This machine has the same IP address (#{ip}) as node `#{name}`."
         | 
| 90 | 
            +
                        }
         | 
| 91 | 
            +
                      }
         | 
| 92 | 
            +
                    end
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 57 96 | 
             
                ##
         | 
| 58 97 | 
             
                ## SSH
         | 
| 59 98 | 
             
                ##
         | 
| @@ -132,6 +171,78 @@ module LeapCli | |
| 132 171 | 
             
                  write_file!(:known_hosts, buffer.string)
         | 
| 133 172 | 
             
                end
         | 
| 134 173 |  | 
| 174 | 
            +
                ##
         | 
| 175 | 
            +
                ## provider.json
         | 
| 176 | 
            +
                ##
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                #
         | 
| 179 | 
            +
                # generates static provider.json files that can put into place
         | 
| 180 | 
            +
                # (e.g. https://domain/provider.json) for the cases where the
         | 
| 181 | 
            +
                # webapp domain does not match the provider's domain.
         | 
| 182 | 
            +
                #
         | 
| 183 | 
            +
                def compile_provider_json(environments=nil)
         | 
| 184 | 
            +
                  webapp_nodes = manager.nodes[:services => 'webapp']
         | 
| 185 | 
            +
                  write_file!(:static_web_readme, STATIC_WEB_README)
         | 
| 186 | 
            +
                  environments ||= manager.environment_names
         | 
| 187 | 
            +
                  environments.each do |env|
         | 
| 188 | 
            +
                    node = webapp_nodes[:environment => env].values.first
         | 
| 189 | 
            +
                    if node
         | 
| 190 | 
            +
                      env ||= 'default'
         | 
| 191 | 
            +
                      write_file!(
         | 
| 192 | 
            +
                        [:static_web_provider_json, env],
         | 
| 193 | 
            +
                        node['definition_files']['provider']
         | 
| 194 | 
            +
                      )
         | 
| 195 | 
            +
                      write_file!(
         | 
| 196 | 
            +
                        [:static_web_htaccess, env],
         | 
| 197 | 
            +
                        HTACCESS_FILE % {:min_version => manager.env(env).provider.client_version['min']}
         | 
| 198 | 
            +
                      )
         | 
| 199 | 
            +
                    end
         | 
| 200 | 
            +
                  end
         | 
| 201 | 
            +
                end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                HTACCESS_FILE = %[
         | 
| 204 | 
            +
              <Location /provider.json>
         | 
| 205 | 
            +
                Header set X-Minimum-Client-Version %{min_version}
         | 
| 206 | 
            +
              </Location>
         | 
| 207 | 
            +
            ]
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                STATIC_WEB_README = %[
         | 
| 210 | 
            +
            This directory contains statically rendered copies of the `provider.json` file
         | 
| 211 | 
            +
            used by the client to "bootstrap" configure itself for use with your service
         | 
| 212 | 
            +
            provider.
         | 
| 213 | 
            +
             | 
| 214 | 
            +
            There is a separate provider.json file for each environment, although you
         | 
| 215 | 
            +
            should only need 'production/provider.json' or, if you have no environments
         | 
| 216 | 
            +
            configured, 'default/provider.json'.
         | 
| 217 | 
            +
             | 
| 218 | 
            +
            To clarify, this is the public `provider.json` file used by the client, not the
         | 
| 219 | 
            +
            `provider.json` file that is used to configure the provider.
         | 
| 220 | 
            +
             | 
| 221 | 
            +
            The provider.json file must be available at `https://domain/provider.json`
         | 
| 222 | 
            +
            (unless this provider is included in the list of providers which are pre-
         | 
| 223 | 
            +
            seeded in client).
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            This provider.json file can be served correctly in one of three ways:
         | 
| 226 | 
            +
             | 
| 227 | 
            +
            (1) If the property webapp.domain is not configured, then the web app will be
         | 
| 228 | 
            +
                installed at https://domain/ and it will handle serving the provider.json file.
         | 
| 229 | 
            +
             | 
| 230 | 
            +
            (2) If one or more nodes have the 'static' service configured for the provider's
         | 
| 231 | 
            +
                domain, then these 'static' nodes will correctly serve provider.json.
         | 
| 232 | 
            +
             | 
| 233 | 
            +
            (3) Otherwise, you must copy the provider.json file to your web
         | 
| 234 | 
            +
                server and make it available at '/provider.json'. The example htaccess
         | 
| 235 | 
            +
                file shows what header options should be sent by the web server
         | 
| 236 | 
            +
                with the response.
         | 
| 237 | 
            +
             | 
| 238 | 
            +
            This directory is needed for method (3), but not for methods (1) or (2).
         | 
| 239 | 
            +
             | 
| 240 | 
            +
            This directory has been created by the command `leap compile provider.json`.
         | 
| 241 | 
            +
            Once created, it will be kept up to date everytime you compile. You may safely
         | 
| 242 | 
            +
            remove this directory if you don't use it.
         | 
| 243 | 
            +
            ]
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                ##
         | 
| 135 246 | 
             
                ##
         | 
| 136 247 | 
             
                ## ZONE FILE
         | 
| 137 248 | 
             
                ##
         | 
| @@ -183,7 +294,7 @@ module LeapCli | |
| 183 294 | 
             
                      if node.dns['aliases']
         | 
| 184 295 | 
             
                        node.dns.aliases.each do |host_alias|
         | 
| 185 296 | 
             
                          if host_alias != node.domain.full && host_alias != provider.domain
         | 
| 186 | 
            -
                            put_line.call relative_hostname(host_alias), "IN  | 
| 297 | 
            +
                            put_line.call relative_hostname(host_alias), "IN A      #{node.ip_address}"
         | 
| 187 298 | 
             
                          end
         | 
| 188 299 | 
             
                        end
         | 
| 189 300 | 
             
                      end
         | 
| @@ -34,7 +34,7 @@ module LeapCli | |
| 34 34 | 
             
                      init_submodules
         | 
| 35 35 | 
             
                    end
         | 
| 36 36 |  | 
| 37 | 
            -
                    nodes = manager.filter!(args)
         | 
| 37 | 
            +
                    nodes = manager.filter!(args, :disabled => false)
         | 
| 38 38 | 
             
                    if nodes.size > 1
         | 
| 39 39 | 
             
                      say "Deploying to these nodes: #{nodes.keys.join(', ')}"
         | 
| 40 40 | 
             
                      if !global[:yes] && !agree("Continue? ")
         | 
| @@ -51,7 +51,7 @@ module LeapCli | |
| 51 51 | 
             
                    end
         | 
| 52 52 | 
             
                    # compile hiera files for all the nodes in every environment that is
         | 
| 53 53 | 
             
                    # being deployed and only those environments.
         | 
| 54 | 
            -
                    compile_hiera_files(manager.filter(environments))
         | 
| 54 | 
            +
                    compile_hiera_files(manager.filter(environments), false)
         | 
| 55 55 | 
             
                    # update server certificates if needed
         | 
| 56 56 | 
             
                    update_certificates(nodes)
         | 
| 57 57 |  | 
| @@ -49,7 +49,7 @@ module LeapCli; module Commands | |
| 49 49 | 
             
                  if overwrite || content.nil? || content.empty?
         | 
| 50 50 | 
             
                    old_facts = {}
         | 
| 51 51 | 
             
                  else
         | 
| 52 | 
            -
                    old_facts =  | 
| 52 | 
            +
                    old_facts = manager.facts
         | 
| 53 53 | 
             
                  end
         | 
| 54 54 | 
             
                  facts = old_facts.merge(new_facts)
         | 
| 55 55 | 
             
                  facts.each do |name, value|
         | 
| @@ -57,7 +57,7 @@ module LeapCli; module Commands | |
| 57 57 | 
             
                      if value == ""
         | 
| 58 58 | 
             
                        value = nil
         | 
| 59 59 | 
             
                      else
         | 
| 60 | 
            -
                        value = JSON.parse(value)
         | 
| 60 | 
            +
                        value = JSON.parse(value) rescue JSON::ParserError
         | 
| 61 61 | 
             
                      end
         | 
| 62 62 | 
             
                    end
         | 
| 63 63 | 
             
                    if value.is_a? Hash
         | 
| @@ -69,7 +69,7 @@ module LeapCli; module Commands | |
| 69 69 | 
             
                    value.nil? || value.empty?
         | 
| 70 70 | 
             
                  end
         | 
| 71 71 | 
             
                  if facts.empty?
         | 
| 72 | 
            -
                     | 
| 72 | 
            +
                    "{}\n"
         | 
| 73 73 | 
             
                  else
         | 
| 74 74 | 
             
                    JSON.sorted_generate(facts) + "\n"
         | 
| 75 75 | 
             
                  end
         | 
| @@ -79,7 +79,7 @@ module LeapCli; module Commands | |
| 79 79 | 
             
              private
         | 
| 80 80 |  | 
| 81 81 | 
             
              def update_facts(global_options, options, args)
         | 
| 82 | 
            -
                nodes = manager.filter(args, :local => false)
         | 
| 82 | 
            +
                nodes = manager.filter(args, :local => false, :disabled => false)
         | 
| 83 83 | 
             
                new_facts = {}
         | 
| 84 84 | 
             
                ssh_connect(nodes) do |ssh|
         | 
| 85 85 | 
             
                  ssh.leap.run_with_progress(facter_cmd) do |response|
         | 
| @@ -46,12 +46,15 @@ module LeapCli; module Commands | |
| 46 46 | 
             
                max_width = nodes.keys.inject(0) {|max,i| [i.size,max].max}
         | 
| 47 47 | 
             
                nodes.each_node do |node|
         | 
| 48 48 | 
             
                  value = properties.collect{|prop|
         | 
| 49 | 
            -
                     | 
| 49 | 
            +
                    prop_value = node[prop]
         | 
| 50 | 
            +
                    if prop_value.nil?
         | 
| 50 51 | 
             
                      "null"
         | 
| 51 | 
            -
                    elsif  | 
| 52 | 
            +
                    elsif prop_value == ""
         | 
| 52 53 | 
             
                      "empty"
         | 
| 54 | 
            +
                    elsif prop_value.is_a? LeapCli::Config::Object
         | 
| 55 | 
            +
                      node[prop].dump_json(:compact) # TODO: add option of getting pre-evaluation values.
         | 
| 53 56 | 
             
                    else
         | 
| 54 | 
            -
                       | 
| 57 | 
            +
                      prop_value.to_s
         | 
| 55 58 | 
             
                    end
         | 
| 56 59 | 
             
                  }.join(', ')
         | 
| 57 60 | 
             
                  printf("%#{max_width}s  %s\n", node.name, value)
         | 
| @@ -47,6 +47,10 @@ module LeapCli; module Commands | |
| 47 47 | 
             
              #  :color   -- true or false, to log in color or not.
         | 
| 48 48 | 
             
              #
         | 
| 49 49 | 
             
              def initialize_leap_cli(require_provider, options={})
         | 
| 50 | 
            +
                if Process::Sys.getuid == 0
         | 
| 51 | 
            +
                  bail! "`leap` should not be run as root."
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 50 54 | 
             
                # set verbosity
         | 
| 51 55 | 
             
                options[:verbose] ||= 1
         | 
| 52 56 | 
             
                LeapCli.set_log_level(options[:verbose].to_i)
         | 
| @@ -9,8 +9,15 @@ module LeapCli; module Commands | |
| 9 9 | 
             
                local.desc 'Starts up the virtual machine(s)'
         | 
| 10 10 | 
             
                local.arg_name 'FILTER', :optional => true #, :multiple => false
         | 
| 11 11 | 
             
                local.command :start do |start|
         | 
| 12 | 
            +
                  start.flag(:basebox,
         | 
| 13 | 
            +
                    :desc => "The basebox to use. This value is passed to vagrant as the "+
         | 
| 14 | 
            +
                      "`config.vm.box` option. The value here should be the name of an installed box or a "+
         | 
| 15 | 
            +
                      "shorthand name of a box in HashiCorp's Atlas.",
         | 
| 16 | 
            +
                    :arg_name => 'BASEBOX',
         | 
| 17 | 
            +
                    :default_value => 'LEAP/wheezy'
         | 
| 18 | 
            +
                  )
         | 
| 12 19 | 
             
                  start.action do |global_options,options,args|
         | 
| 13 | 
            -
                    vagrant_command(["up", "sandbox on"], args)
         | 
| 20 | 
            +
                    vagrant_command(["up", "sandbox on"], args, options)
         | 
| 14 21 | 
             
                  end
         | 
| 15 22 | 
             
                end
         | 
| 16 23 |  | 
| @@ -84,8 +91,8 @@ module LeapCli; module Commands | |
| 84 91 |  | 
| 85 92 | 
             
              protected
         | 
| 86 93 |  | 
| 87 | 
            -
              def vagrant_command(cmds, args)
         | 
| 88 | 
            -
                vagrant_setup
         | 
| 94 | 
            +
              def vagrant_command(cmds, args, options={})
         | 
| 95 | 
            +
                vagrant_setup(options)
         | 
| 89 96 | 
             
                cmds = cmds.to_a
         | 
| 90 97 | 
             
                if args.empty?
         | 
| 91 98 | 
             
                  nodes = [""]
         | 
| @@ -108,7 +115,7 @@ module LeapCli; module Commands | |
| 108 115 |  | 
| 109 116 | 
             
              private
         | 
| 110 117 |  | 
| 111 | 
            -
              def vagrant_setup
         | 
| 118 | 
            +
              def vagrant_setup(options)
         | 
| 112 119 | 
             
                assert_bin! 'vagrant', 'Vagrant is required for running local virtual machines. Run "sudo apt-get install vagrant".'
         | 
| 113 120 |  | 
| 114 121 | 
             
                if vagrant_version <= Gem::Version.new('1.0.0')
         | 
| @@ -123,7 +130,7 @@ module LeapCli; module Commands | |
| 123 130 | 
             
                    assert_run! 'vagrant plugin install sahara'
         | 
| 124 131 | 
             
                  end
         | 
| 125 132 | 
             
                end
         | 
| 126 | 
            -
                create_vagrant_file
         | 
| 133 | 
            +
                create_vagrant_file(options)
         | 
| 127 134 | 
             
              end
         | 
| 128 135 |  | 
| 129 136 | 
             
              def vagrant_version
         | 
| @@ -135,16 +142,18 @@ module LeapCli; module Commands | |
| 135 142 | 
             
                exec cmd
         | 
| 136 143 | 
             
              end
         | 
| 137 144 |  | 
| 138 | 
            -
              def create_vagrant_file
         | 
| 145 | 
            +
              def create_vagrant_file(options)
         | 
| 139 146 | 
             
                lines = []
         | 
| 140 147 | 
             
                netmask = IPAddr.new('255.255.255.255').mask(LeapCli.leapfile.vagrant_network.split('/').last).to_s
         | 
| 141 148 |  | 
| 149 | 
            +
                basebox = options[:basebox] || 'LEAP/wheezy'
         | 
| 150 | 
            +
             | 
| 142 151 | 
             
                if vagrant_version <= Gem::Version.new('1.1.0')
         | 
| 143 152 | 
             
                  lines << %[Vagrant::Config.run do |config|]
         | 
| 144 153 | 
             
                  manager.each_node do |node|
         | 
| 145 154 | 
             
                    if node.vagrant?
         | 
| 146 155 | 
             
                      lines << %[  config.vm.define :#{node.name} do |config|]
         | 
| 147 | 
            -
                      lines << %[    config.vm.box = " | 
| 156 | 
            +
                      lines << %[    config.vm.box = "#{basebox}"]
         | 
| 148 157 | 
             
                      lines << %[    config.vm.network :hostonly, "#{node.ip_address}", :netmask => "#{netmask}"]
         | 
| 149 158 | 
             
                      lines << %[    config.vm.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]]
         | 
| 150 159 | 
             
                      lines << %[    config.vm.customize ["modifyvm", :id, "--name", "#{node.name}"]]
         | 
| @@ -157,7 +166,7 @@ module LeapCli; module Commands | |
| 157 166 | 
             
                  manager.each_node do |node|
         | 
| 158 167 | 
             
                    if node.vagrant?
         | 
| 159 168 | 
             
                      lines << %[  config.vm.define :#{node.name} do |config|]
         | 
| 160 | 
            -
                      lines << %[    config.vm.box = " | 
| 169 | 
            +
                      lines << %[    config.vm.box = "#{basebox}"]
         | 
| 161 170 | 
             
                      lines << %[    config.vm.network :private_network, ip: "#{node.ip_address}"]
         | 
| 162 171 | 
             
                      lines << %[    config.vm.provider "virtualbox" do |v|]
         | 
| 163 172 | 
             
                      lines << %[      v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]]
         | 
| @@ -43,7 +43,15 @@ module LeapCli | |
| 43 43 | 
             
                  # returns the Hash of the contents of facts.json
         | 
| 44 44 | 
             
                  #
         | 
| 45 45 | 
             
                  def facts
         | 
| 46 | 
            -
                    @facts ||=  | 
| 46 | 
            +
                    @facts ||= begin
         | 
| 47 | 
            +
                      content = Util.read_file(:facts)
         | 
| 48 | 
            +
                      if !content || content.empty?
         | 
| 49 | 
            +
                        content = "{}"
         | 
| 50 | 
            +
                      end
         | 
| 51 | 
            +
                      JSON.parse(content)
         | 
| 52 | 
            +
                    rescue SyntaxError, JSON::ParserError => exc
         | 
| 53 | 
            +
                      Util::bail! "Could not parse facts.json -- #{exc}"
         | 
| 54 | 
            +
                    end
         | 
| 47 55 | 
             
                  end
         | 
| 48 56 |  | 
| 49 57 | 
             
                  #
         | 
| @@ -247,8 +255,8 @@ module LeapCli | |
| 247 255 | 
             
                  #
         | 
| 248 256 | 
             
                  # same as filter(), but exits if there is no matching nodes
         | 
| 249 257 | 
             
                  #
         | 
| 250 | 
            -
                  def filter!(filters)
         | 
| 251 | 
            -
                    node_list = filter(filters)
         | 
| 258 | 
            +
                  def filter!(filters, options={})
         | 
| 259 | 
            +
                    node_list = filter(filters, options)
         | 
| 252 260 | 
             
                    Util::assert! node_list.any?, "Could not match any nodes from '#{filters.join ' '}'"
         | 
| 253 261 | 
             
                    return node_list
         | 
| 254 262 | 
             
                  end
         | 
| @@ -85,9 +85,13 @@ module LeapCli | |
| 85 85 | 
             
                  #
         | 
| 86 86 | 
             
                  # export JSON
         | 
| 87 87 | 
             
                  #
         | 
| 88 | 
            -
                  def dump_json
         | 
| 88 | 
            +
                  def dump_json(*options)
         | 
| 89 89 | 
             
                    evaluate(@node)
         | 
| 90 | 
            -
                     | 
| 90 | 
            +
                    if options.include? :compact
         | 
| 91 | 
            +
                      self.to_json
         | 
| 92 | 
            +
                    else
         | 
| 93 | 
            +
                      JSON.sorted_generate(self)
         | 
| 94 | 
            +
                    end
         | 
| 91 95 | 
             
                  end
         | 
| 92 96 |  | 
| 93 97 | 
             
                  def evaluate(context=@node)
         | 
| @@ -143,7 +147,7 @@ module LeapCli | |
| 143 147 | 
             
                    elsif key =~ /\./
         | 
| 144 148 | 
             
                      # for keys with with '.' in them, we start from the root object (@node).
         | 
| 145 149 | 
             
                      keys = key.split('.')
         | 
| 146 | 
            -
                      value =  | 
| 150 | 
            +
                      value = self.get!(keys.first)
         | 
| 147 151 | 
             
                      if value.is_a? Config::Object
         | 
| 148 152 | 
             
                        value.get!(keys[1..-1].join('.'))
         | 
| 149 153 | 
             
                      else
         | 
| @@ -15,6 +15,7 @@ module LeapCli; module Config | |
| 15 15 |  | 
| 16 16 | 
             
                # we can't use fetch() or get(), since those already have special meanings
         | 
| 17 17 | 
             
                def retrieve(key, environment)
         | 
| 18 | 
            +
                  environment ||= 'default'
         | 
| 18 19 | 
             
                  self.fetch(environment, {})[key.to_s]
         | 
| 19 20 | 
             
                end
         | 
| 20 21 |  | 
| @@ -31,6 +32,7 @@ module LeapCli; module Config | |
| 31 32 | 
             
                end
         | 
| 32 33 |  | 
| 33 34 | 
             
                def set_with_block(key, environment, &block)
         | 
| 35 | 
            +
                  environment ||= 'default'
         | 
| 34 36 | 
             
                  key = key.to_s
         | 
| 35 37 | 
             
                  @discovered_keys[environment] ||= {}
         | 
| 36 38 | 
             
                  @discovered_keys[environment][key] = true
         | 
    
        data/lib/leap_cli/log.rb
    CHANGED
    
    | @@ -80,7 +80,7 @@ module LeapCli | |
| 80 80 | 
             
                  if title
         | 
| 81 81 | 
             
                    prefix_options = case title
         | 
| 82 82 | 
             
                      when :error     then ['error', :red, :bold]
         | 
| 83 | 
            -
                      when :fatal_error then ['fatal error', :red, :bold]
         | 
| 83 | 
            +
                      when :fatal_error then ['fatal error:', :red, :bold]
         | 
| 84 84 | 
             
                      when :warning   then ['warning:', :yellow, :bold]
         | 
| 85 85 | 
             
                      when :info      then ['info', :cyan, :bold]
         | 
| 86 86 | 
             
                      when :updated   then ['updated', :cyan, :bold]
         | 
| @@ -36,7 +36,8 @@ module LeapCli; module Remote; module LeapPlugin | |
| 36 36 | 
             
                rescue Capistrano::CommandError => exc
         | 
| 37 37 | 
             
                  LeapCli::Util.bail! do
         | 
| 38 38 | 
             
                    exc.hosts.each do |host|
         | 
| 39 | 
            -
                       | 
| 39 | 
            +
                      node = host.to_s.split('.').first
         | 
| 40 | 
            +
                      LeapCli::Util.log :error, "running deploy: node not initialized. Run 'leap node init #{node}'", :host => host
         | 
| 40 41 | 
             
                    end
         | 
| 41 42 | 
             
                  end
         | 
| 42 43 | 
             
                end
         | 
| @@ -184,7 +185,8 @@ module LeapCli; module Remote; module LeapPlugin | |
| 184 185 | 
             
              private
         | 
| 185 186 |  | 
| 186 187 | 
             
              def progress(str='.')
         | 
| 187 | 
            -
                 | 
| 188 | 
            +
                print str
         | 
| 189 | 
            +
                STDOUT.flush
         | 
| 188 190 | 
             
              end
         | 
| 189 191 |  | 
| 190 192 | 
             
              #def mkdir(dir)
         | 
    
        data/lib/leap_cli/version.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            module LeapCli
         | 
| 2 2 | 
             
              unless defined?(LeapCli::VERSION)
         | 
| 3 | 
            -
                VERSION = '1.7. | 
| 4 | 
            -
                COMPATIBLE_PLATFORM_VERSION = '0.7'..'0.99'
         | 
| 3 | 
            +
                VERSION = '1.7.4'
         | 
| 4 | 
            +
                COMPATIBLE_PLATFORM_VERSION = '0.7.1'..'0.99'
         | 
| 5 5 | 
             
                SUMMARY = 'Command line interface to the LEAP platform'
         | 
| 6 6 | 
             
                DESCRIPTION = 'The command "leap" can be used to manage a bevy of servers running the LEAP platform from the comfort of your own home.'
         | 
| 7 7 | 
             
                LOAD_PATHS = ['lib', 'vendor/certificate_authority/lib', 'vendor/rsync_command/lib']
         | 
    
        data/lib/leap_cli.rb
    CHANGED
    
    | @@ -11,7 +11,7 @@ $:.unshift(File.expand_path('../leap_cli/override',__FILE__)) | |
| 11 11 | 
             
            # for a few gems, things will break if using earlier versions.
         | 
| 12 12 | 
             
            # enforce the compatible versions here:
         | 
| 13 13 | 
             
            require 'rubygems'
         | 
| 14 | 
            -
            gem 'net-ssh', '~> 2.7 | 
| 14 | 
            +
            gem 'net-ssh', '~> 2.7'
         | 
| 15 15 | 
             
            gem 'gli', '~> 2.12', '>= 2.12.0'
         | 
| 16 16 |  | 
| 17 17 | 
             
            require 'leap/platform'
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: leap_cli
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.7. | 
| 4 | 
            +
              version: 1.7.4
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - LEAP Encryption Access Project
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015- | 
| 11 | 
            +
            date: 2015-07-29 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: minitest
         | 
| @@ -92,28 +92,28 @@ dependencies: | |
| 92 92 | 
             
                requirements:
         | 
| 93 93 | 
             
                - - "~>"
         | 
| 94 94 | 
             
                  - !ruby/object:Gem::Version
         | 
| 95 | 
            -
                    version: 2.7 | 
| 95 | 
            +
                    version: '2.7'
         | 
| 96 96 | 
             
              type: :runtime
         | 
| 97 97 | 
             
              prerelease: false
         | 
| 98 98 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 99 99 | 
             
                requirements:
         | 
| 100 100 | 
             
                - - "~>"
         | 
| 101 101 | 
             
                  - !ruby/object:Gem::Version
         | 
| 102 | 
            -
                    version: 2.7 | 
| 102 | 
            +
                    version: '2.7'
         | 
| 103 103 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 104 104 | 
             
              name: capistrano
         | 
| 105 105 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 106 106 | 
             
                requirements:
         | 
| 107 107 | 
             
                - - "~>"
         | 
| 108 108 | 
             
                  - !ruby/object:Gem::Version
         | 
| 109 | 
            -
                    version: 2.15 | 
| 109 | 
            +
                    version: '2.15'
         | 
| 110 110 | 
             
              type: :runtime
         | 
| 111 111 | 
             
              prerelease: false
         | 
| 112 112 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 113 113 | 
             
                requirements:
         | 
| 114 114 | 
             
                - - "~>"
         | 
| 115 115 | 
             
                  - !ruby/object:Gem::Version
         | 
| 116 | 
            -
                    version: 2.15 | 
| 116 | 
            +
                    version: '2.15'
         | 
| 117 117 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 118 118 | 
             
              name: ya2yaml
         | 
| 119 119 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -160,6 +160,9 @@ dependencies: | |
| 160 160 | 
             
              name: activemodel
         | 
| 161 161 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 162 162 | 
             
                requirements:
         | 
| 163 | 
            +
                - - "~>"
         | 
| 164 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 165 | 
            +
                    version: '3.0'
         | 
| 163 166 | 
             
                - - ">="
         | 
| 164 167 | 
             
                  - !ruby/object:Gem::Version
         | 
| 165 168 | 
             
                    version: 3.0.6
         | 
| @@ -167,6 +170,9 @@ dependencies: | |
| 167 170 | 
             
              prerelease: false
         | 
| 168 171 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 169 172 | 
             
                requirements:
         | 
| 173 | 
            +
                - - "~>"
         | 
| 174 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 175 | 
            +
                    version: '3.0'
         | 
| 170 176 | 
             
                - - ">="
         | 
| 171 177 | 
             
                  - !ruby/object:Gem::Version
         | 
| 172 178 | 
             
                    version: 3.0.6
         |