diff options
author | elijah <elijah@riseup.net> | 2012-10-09 00:01:55 -0700 |
---|---|---|
committer | elijah <elijah@riseup.net> | 2012-10-09 00:01:55 -0700 |
commit | 578ac2f5dc7432317d7a022bed9d869ab89ee45c (patch) | |
tree | 3cf8d27c2e8059df33e33e9c39146e0b3db29599 | |
parent | 105fe22c2de06310e48c4827b47d38d18750ed32 (diff) | |
download | leap_cli-578ac2f5dc7432317d7a022bed9d869ab89ee45c.tar.gz leap_cli-578ac2f5dc7432317d7a022bed9d869ab89ee45c.tar.bz2 |
initial code commit
48 files changed, 1770 insertions, 0 deletions
diff --git a/cli/DEVNOTES b/cli/DEVNOTES new file mode 100644 index 0000000..eceac87 --- /dev/null +++ b/cli/DEVNOTES @@ -0,0 +1,97 @@ +Features to add +========================== + +templates +-------------------- + +templates for nodes and services stored in leap_platform + +commands: + + leap add-service # menu of services, adding copies the template + leap add-node # you pick a service, then it copies template + +deploy +--------------------- + +not yet working + + leap bootstrap + leap dryrun + leap deploy + +key management +------------------------- + +not yet working + + leap add-ssh-keypair + leap add-x509-keypair + +hiera logic +------------------------ + +leap_platform should be able insert ruby logic in the generation of hiera .yml files. for example, so say that a webapp node should get a list of all the couchdb nodes its config. + +this code might look like this + + node['couchdb_ips'] = @nodes[:services => :couchdb].map(&:ip_address) + +or + + node['couchdb_ips'] = @services[:couchdb].nodes.map(&:ip_address) + +maybe see http://blog.bigbinary.com/2008/10/17/under-the-hood-how-named-scope-works.html + + +json validation +------------------------ + +json validation +http://www.kuwata-lab.com/kwalify/ruby/users-guide.html + + +useful liberaries +================================ + +user interaction + + readline + highline + terminal-tables + rainbow + http://stackoverflow.com/questions/9577718/what-ruby-libraries-should-i-use-for-building-a-console-based-application + +testing + + aruba -- test for cli + +help + + gem-man -- install man pages with gems + ronn -- write man pages in markdown + +push examples + + https://github.com/net-ssh/net-ssh + + https://github.com/seattlerb/rake-remote_task + http://docs.seattlerb.org/rake-remote_task/ + https://github.com/seattlerb/rake-remote_task/blob/master/lib/rake/remote_task.rb + + https://github.com/davidwinter/sooty + push puppet with rake/remote_task + https://github.com/davidwinter/sooty/blob/master/lib/sooty.rb + + calling rsync from ruby + https://github.com/RichGuk/rrsync/blob/master/rrsync.rb + http://rubyforge.org/projects/six-rsync/ + + https://github.com/automateit/automateit + + http://www.jedi.be/blog/2009/11/17/shell-scripting-dsl-in-ruby/ + + parallel shell + https://github.com/delano/rye + https://github.com/adamwiggins/rush + diff --git a/cli/Gemfile b/cli/Gemfile new file mode 100644 index 0000000..e45e65f --- /dev/null +++ b/cli/Gemfile @@ -0,0 +1,2 @@ +source :rubygems +gemspec diff --git a/cli/Gemfile.lock b/cli/Gemfile.lock new file mode 100644 index 0000000..60ce6f8 --- /dev/null +++ b/cli/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: . + specs: + leap_cli (0.0.1) + gli (~> 2.3) + oj + terminal-table + +GEM + remote: http://rubygems.org/ + specs: + gli (2.3.0) + oj (1.3.7) + rake (0.9.2.2) + terminal-table (1.4.5) + +PLATFORMS + ruby + +DEPENDENCIES + leap_cli! + rake diff --git a/cli/README.md b/cli/README.md new file mode 100644 index 0000000..fccd6d1 --- /dev/null +++ b/cli/README.md @@ -0,0 +1,132 @@ +About LEAP command line interface +================================= + +This gem installs an executable 'leap' that allows you to manage servers using the leap platform. + +Installation +================================= + +To install the gem: + + gem install leap_cli + +To run from a clone of the git repo, see "Development", below. + +Usage +================================= + +This tool is incomplete, so most commands don't yet work. + +Run `leap help` for a usage instructions. + +Here is an example usage: + + leap init provider + cd provider + edit configuration files (see below) + leap compile + +Directories and Files +================================= + +The general structure of leap project looks like this: + + my_leap_project/ # the 'root' directory + leap_platform/ # a clone of the leap_platform puppet recipes + provider/ # your provider-specific configurations + +The "leap" command should be run from within the "provider" directory. + +You can name these directories whatever you like. The leap command will walk up the directory tree until it finds a directory that looks like a 'root' directory. + +Within the "provider" directory: + + nodes/ # one configuration file per node (i.e. server) + services/ # nodes inherit from these files if specified in node config. + tags/ # nodes inherit from these files if specified in node config. + files/ # text and binary files needed for services and nodes, including keypairs + users/ # crypto key material for sysadmins + common.yaml # all nodes inherit these options + provider.yaml # global service provider definition + +Configuration Files +================================= + +All configuration files are in JSON format. For example + + { + "key1": "value1", + "key2": "value2" + } + +Keys should match /[a-z0-9_]/ + +Unlike traditional JSON, comments are allowed. If the first non-whitespace character is '#' the line is treated as a comment. + + # this is a comment + { + # this is a comment + "key": "value" # this is an error + } + +Options in the configuration files might be nested. For example: + + { + "openvpn": { + "ip_address": "1.1.1.1" + } + } + +When compiled into hiera and made available in puppet, this becomes a Hash object with flattened keys: + + {"openvpn.ip_address" => "1.1.1.1"} + +Node Configuration +================================= + +The name of the file will be the hostname of the node. + +An example configuration "nodes/dns-europe.json" + + { + "services": "dns", + "tags": ["production", "europe"], + "ip_address": "1.1.1.1" + } + +This node will have hostname "dns-europe" and it will inherit from the following files (in this order): + + common.json + services/dns.json + tags/europe.json + tags/production.json + +Development +================================= + +prerequisites: + +* rubygems (``apt-get install rubygems``) +* bundler (``gem install bundler``) + +Install command line ``leap``: + + git clone git://leap.se/leap_cli # clone leap cli code + cd leap_cli + bundle # install required gems + ln -s `pwd`/bin/leap ~/bin # link executable somewhere in your bin path + +You can experiment using the example provider in the test directory + + cd test/provider + leap + +Alternately, you can create your own provider for testing: + + mkdir ~/dev/example.org + cd ~/dev/example.org + git clone git://leap.se/leap_platform + leap init provider + cd provider + leap + diff --git a/cli/Rakefile b/cli/Rakefile new file mode 100644 index 0000000..c97688b --- /dev/null +++ b/cli/Rakefile @@ -0,0 +1,44 @@ +require 'rake/clean' +require 'rubygems' +require 'rubygems/package_task' +require 'rdoc/task' +require 'cucumber' +require 'cucumber/rake/task' +Rake::RDocTask.new do |rd| + rd.main = "README.rdoc" + rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*") + rd.title = 'Your application title' +end + +spec = eval(File.read('leap_cli.gemspec')) + +Gem::PackageTask.new(spec) do |pkg| +end +CUKE_RESULTS = 'results.html' +CLEAN << CUKE_RESULTS +desc 'Run features' +Cucumber::Rake::Task.new(:features) do |t| + opts = "features --format html -o #{CUKE_RESULTS} --format progress -x" + opts += " --tags #{ENV['TAGS']}" if ENV['TAGS'] + t.cucumber_opts = opts + t.fork = false +end + +desc 'Run features tagged as work-in-progress (@wip)' +Cucumber::Rake::Task.new('features:wip') do |t| + tag_opts = ' --tags ~@pending' + tag_opts = ' --tags @wip' + t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}" + t.fork = false +end + +task :cucumber => :features +task 'cucumber:wip' => 'features:wip' +task :wip => 'features:wip' +require 'rake/testtask' +Rake::TestTask.new do |t| + t.libs << "test" + t.test_files = FileList['test/*_test.rb'] +end + +task :default => [:test,:features] diff --git a/cli/bin/leap b/cli/bin/leap new file mode 100755 index 0000000..4155b58 --- /dev/null +++ b/cli/bin/leap @@ -0,0 +1,64 @@ +#!/usr/bin/env ruby +begin + require 'leap_cli' +rescue LoadError + # + # When developing a gem with a command, you normally use `bundle exec bin/command-name` + # to run your app. At install-time, RubyGems will make sure lib, etc. are in the load path, + # so that you can run the command directly. + # + # However, I don't like using 'bundle exec'. It is slow, and limits which directory you can + # run in. So, instead, we fall back to some path manipulation hackery. + # + # This allows you to run the command directly while developing the gem, and also lets you + # run from anywhere (I like to link 'bin/leap' to /usr/local/bin/leap). + # + file = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__ + lib_dir = File.expand_path(File.dirname(file) + '/../lib') + $LOAD_PATH.unshift lib_dir unless $LOAD_PATH.include?(lib_dir) + require 'rubygems' + require 'leap_cli' +end + +require 'gli' +require 'highline' +require 'forwardable' +require 'terminal-table' + +# +# Typically, GLI and Highline methods are loaded into the global namespace. +# Instead, here we load these into the module LeapCli::Commands in order to +# ensure that the cli logic and code is kept isolated to leap_cli/commands/*.rb +# +# no cheating! +# +module LeapCli::Commands + extend GLI::App + extend Forwardable + extend Terminal::Table::TableHelper + + ENV['GLI_DEBUG'] = "true" + + # + # delegate highline methods to make them available to sub-commands + # + @terminal = HighLine.new + def_delegator :@terminal, :ask, 'self.ask' + def_delegator :@terminal, :agree, 'self.agree' + def_delegator :@terminal, :ask, 'self.ask' + def_delegator :@terminal, :choose, 'self.choose' + def_delegator :@terminal, :say, 'self.say' + + # + # info about leap command line suite + # + program_desc 'LEAP platform command line interface' + program_long_desc 'This is the long description. It is very interesting.' + version LeapCli::VERSION + + # + # load commands and run + # + commands_from('leap_cli/commands') + exit run(ARGV) +end diff --git a/cli/leap_cli.gemspec b/cli/leap_cli.gemspec new file mode 100644 index 0000000..208355d --- /dev/null +++ b/cli/leap_cli.gemspec @@ -0,0 +1,45 @@ +# +# Ensure we require the local version and not one we might have installed already +# +require File.join([File.dirname(__FILE__),'lib','leap_cli','version.rb']) + +spec = Gem::Specification.new do |s| + + ## + ## ABOUT THIS GEM + ## + s.name = 'leap_cli' + s.version = LeapCli::VERSION + s.author = 'LEAP' + s.email = 'root@leap.se' + s.homepage = 'https://leap.se' + s.platform = Gem::Platform::RUBY + s.summary = 'Command line interface to the leap platform.' + + ## + ## GEM FILES + ## + s.files = `find lib -name '*.rb'`.split("\n") << "bin/leap" + s.require_paths << 'lib' + + s.bindir = 'bin' + s.executables << 'leap' + + ## + ## DOCUMENTATION + ## + #s.has_rdoc = true + #s.extra_rdoc_files = ['README.rdoc','leap_cli.rdoc'] + #s.rdoc_options << '--title' << 'leap_cli' << '--main' << 'README.rdoc' << '-ri' + + ## + ## DEPENDENCIES + ## + s.add_development_dependency('rake') + #s.add_development_dependency('rdoc') + #s.add_development_dependency('aruba') + + s.add_runtime_dependency('gli','~> 2.3') + s.add_runtime_dependency('oj') + s.add_runtime_dependency('terminal-table') +end diff --git a/cli/leap_cli.rdoc b/cli/leap_cli.rdoc new file mode 100644 index 0000000..31d5deb --- /dev/null +++ b/cli/leap_cli.rdoc @@ -0,0 +1,5 @@ += leap_cli + +Generate this with + leap_cli rdoc +After you have described your command line interface
\ No newline at end of file diff --git a/cli/lib/leap_cli.rb b/cli/lib/leap_cli.rb new file mode 100644 index 0000000..b935e35 --- /dev/null +++ b/cli/lib/leap_cli.rb @@ -0,0 +1,19 @@ +module LeapCli; end + +unless defined?(LeapCli::VERSION) + # ^^ I am not sure why this is needed. + require 'leap_cli/version.rb' +end + +require 'leap_cli/init' +require 'leap_cli/path' +require 'leap_cli/log' +require 'leap_cli/config' +require 'leap_cli/config_list' +require 'leap_cli/config_manager' + +unless String.method_defined?(:to_a) + class String + def to_a; [self]; end + end +end
\ No newline at end of file diff --git a/cli/lib/leap_cli/commands/README b/cli/lib/leap_cli/commands/README new file mode 100644 index 0000000..00fcd84 --- /dev/null +++ b/cli/lib/leap_cli/commands/README @@ -0,0 +1,101 @@ +This directory contains ruby source files that define the available sub-commands of the `leap` executable. + +For example, the command: + + leap init <directory> + +Lives in lib/leap_cli/commands/init.rb + +These files use a DSL (called GLI) for defining command suites. +See https://github.com/davetron5000/gli for more information. + + + c.command + c.commands + c.default_command + c.default_value + c.get_default_command + c.commands + c.commands_declaration_order + + c.flag + c.flags + c.switch + c.switches + + c.long_desc + + c.default_desc + c.default_description + c.desc + c.description + c.long_description + c.context_description + c.usage + + c.arg_name + c.arguments_description + c.arguments_options + + c.skips_post + c.skips_pre + c.skips_around + + c.action + + c.copy_options_to_aliases + c.nodoc + c.aliases + c.execute + c.names + + +#desc 'Describe some switch here' +#switch [:s,:switch] + +#desc 'Describe some flag here' +#default_value 'the default' +#arg_name 'The name of the argument' +#flag [:f,:flagname] + +# desc 'Describe deploy here' +# arg_name 'Describe arguments to deploy here' +# command :deploy do |c| +# c.action do |global_options,options,args| +# puts "deploy command ran" +# end +# end + +# desc 'Describe dryrun here' +# arg_name 'Describe arguments to dryrun here' +# command :dryrun do |c| +# c.action do |global_options,options,args| +# puts "dryrun command ran" +# end +# end + +# desc 'Describe add-node here' +# arg_name 'Describe arguments to add-node here' +# command :"add-node" do |c| +# c.desc 'Describe a switch to init' +# c.switch :s +# +# c.desc 'Describe a flag to init' +# c.default_value 'default' +# c.flag :f +# c.action do |global_options,options,args| +# puts "add-node command ran" +# end +# end + +# post do |global,command,options,args| +# # Post logic here +# # Use skips_post before a command to skip this +# # block on that command only +# end + +# on_error do |exception| +# # Error logic here +# # return false to skip default error handling +# true +# end diff --git a/cli/lib/leap_cli/commands/compile.rb b/cli/lib/leap_cli/commands/compile.rb new file mode 100644 index 0000000..6b38de5 --- /dev/null +++ b/cli/lib/leap_cli/commands/compile.rb @@ -0,0 +1,15 @@ +module LeapCli + module Commands + + desc 'Compile json files to hiera configs' + command :compile do |c| + c.action do |global_options,options,args| + manager = ConfigManager.new + manager.load(Path.provider) + Path.ensure_dir(Path.hiera) + manager.export(Path.hiera) + end + end + + end +end
\ No newline at end of file diff --git a/cli/lib/leap_cli/commands/deploy.rb b/cli/lib/leap_cli/commands/deploy.rb new file mode 100644 index 0000000..3694a38 --- /dev/null +++ b/cli/lib/leap_cli/commands/deploy.rb @@ -0,0 +1,20 @@ +module LeapCli + module Commands + + desc 'Apply recipes to a node or set of nodes' + long_desc 'The node filter can be the name of a node, service, or tag.' + arg_name '<node filter>' + command :deploy do |c| + c.action do |global_options,options,args| + nodes = ConfigManager.filter(args) + say "Deploying to these nodes: #{nodes.keys.join(', ')}" + if agree "Continue? " + say "deploy not yet implemented" + else + say "OK. Bye." + end + end + end + + end +end
\ No newline at end of file diff --git a/cli/lib/leap_cli/commands/init.rb b/cli/lib/leap_cli/commands/init.rb new file mode 100644 index 0000000..75cc876 --- /dev/null +++ b/cli/lib/leap_cli/commands/init.rb @@ -0,0 +1,24 @@ +module LeapCli + module Commands + desc 'Creates a new provider configuration directory.' + arg_name '<directory>' + skips_pre + command :init do |c| + c.action do |global_options,options,args| + directory = args.first + unless directory && directory.any? + help_now! "Directory name is required." + end + directory = File.expand_path(directory) + if File.exists?(directory) + raise "#{directory} already exists." + end + if agree("Create directory '#{directory}'? ") + LeapCli.init(directory) + else + puts "OK, bye." + end + end + end + end +end
\ No newline at end of file diff --git a/cli/lib/leap_cli/commands/list.rb b/cli/lib/leap_cli/commands/list.rb new file mode 100644 index 0000000..a186049 --- /dev/null +++ b/cli/lib/leap_cli/commands/list.rb @@ -0,0 +1,61 @@ +module LeapCli + module Commands + + def self.print_config_table(type, config_list) + style = {:border_x => '-', :border_y => ':', :border_i => '-', :width => 60} + + if type == :services + t = table do + self.style = style + self.headings = ['SERVICE', 'NODES'] + list = config_list.keys.sort + list.each do |name| + add_row [name, config_list[name].nodes.keys.join(', ')] + add_separator unless name == list.last + end + end + puts t + puts "\n\n" + elsif type == :tags + t = table do + self.style = style + self.headings = ['TAG', 'NODES'] + list = config_list.keys.sort + list.each do |name| + add_row [name, config_list[name].nodes.keys.join(', ')] + add_separator unless name == list.last + end + end + puts t + puts "\n\n" + elsif type == :nodes + t = table do + self.style = style + self.headings = ['NODE', 'SERVICES', 'TAGS'] + list = config_list.keys.sort + list.each do |name| + add_row [name, config_list[name].services.to_a.join(', '), config_list[name].tags.to_a.join(', ')] + add_separator unless name == list.last + end + end + puts t + end + end + + desc 'List nodes and their classifications' + long_desc 'Prints out a listing of nodes, services, or tags.' + arg_name 'filter' + command :list do |c| + c.action do |global_options,options,args| + if args.any? + print_config_table(:nodes, ConfigManager.filter(args)) + else + print_config_table(:services, ConfigManager.services) + print_config_table(:tags, ConfigManager.tags) + print_config_table(:nodes, ConfigManager.nodes) + end + end + end + + end +end diff --git a/cli/lib/leap_cli/commands/pre.rb b/cli/lib/leap_cli/commands/pre.rb new file mode 100644 index 0000000..ae58fc8 --- /dev/null +++ b/cli/lib/leap_cli/commands/pre.rb @@ -0,0 +1,38 @@ + +# +# check to make sure we can find the root directory of the platform +# +module LeapCli + module Commands + + desc 'Verbosity level 0..2' + arg_name 'level' + default_value '0' + flag [:v, :verbose] + + desc 'Specify the root directory' + arg_name 'path' + default_value Path.root + flag [:root] + + pre do |global,command,options,args| + # + # set verbosity + # + LeapCli.log_level = global[:verbose].to_i + + # + # require a root directory + # + if global[:root] + Path.set_root(global[:root]) + end + if Path.ok? + true + else + exit_now!("Could not find the root directory. Change current working directory or try --root") + end + end + + end +end diff --git a/cli/lib/leap_cli/config.rb b/cli/lib/leap_cli/config.rb new file mode 100644 index 0000000..44e66be --- /dev/null +++ b/cli/lib/leap_cli/config.rb @@ -0,0 +1,119 @@ +module LeapCli + # + # This class represents the configuration for a single node, service, or tag. + # + class Config < Hash + + def initialize(config_type, manager) + @manager = manager + @type = config_type + end + + # + # lazily eval dynamic values when we encounter them. + # + def [](key) + value = fetch(key, nil) + if value.is_a? Array + value + elsif value.nil? + nil + else + if value =~ /^= (.*)$/ + value = eval($1) + self[key] = value + end + value + end + end + + # + # make the type appear to be a normal Hash in yaml. + # + def to_yaml_type + "!map" + end + + # + # just like Hash#to_yaml, but sorted + # + def to_yaml(opts = {}) + YAML::quick_emit(self, opts) do |out| + out.map(taguri, to_yaml_style) do |map| + keys.sort.each do |k| + v = self.fetch(k) + map.add(k, v) + end + end + end + end + + # + # make obj['name'] available as obj.name + # + def method_missing(method, *args, &block) + if has_key?(method.to_s) + self[method.to_s] + else + super + end + end + + # + # convert self into a plain hash, but only include the specified keys + # + def to_h(*keys) + keys.map(&:to_s).inject({}) do |hsh, key| + if has_key?(key) + hsh[key] = self[key] + end + hsh + end + end + + def nodes + if @type == :node + @manager.nodes + else + @nodes ||= ConfigList.new + end + end + + def services + if @type == :node + self['services'] || [] + else + @manager.services + end + end + + def tags + if @type == :node + self['tags'] || [] + else + @manager.tags + end + end + + private + + ## + ## MACROS + ## these are methods used when eval'ing a value in the .json configuration + ## + + # + # inserts the contents of a file + # + def file(filename) + filepath = Path.find_file(name, filename) + if filepath + File.read(filepath) + else + log0('no such file, "%s"' % filename) + "" + end + end + + end # class +end # module
\ No newline at end of file diff --git a/cli/lib/leap_cli/config_list.rb b/cli/lib/leap_cli/config_list.rb new file mode 100644 index 0000000..c8ff23b --- /dev/null +++ b/cli/lib/leap_cli/config_list.rb @@ -0,0 +1,77 @@ +module LeapCli + class ConfigList < Hash + + def initialize(config=nil) + if config + self << config + end + end + + # + # if the key is a hash, we treat it as a condition and filter all the configs using the condition + # + # for example: + # + # nodes[:public_dns => true] + # + # will return a ConfigList with node configs that have public_dns set to true + # + def [](key) + if key.is_a? Hash + results = ConfigList.new + field, match_value = key.to_a.first + field = field.is_a?(Symbol) ? field.to_s : field + match_value = match_value.is_a?(Symbol) ? match_value.to_s : match_value + each do |name, config| + value = config[field] + if !value.nil? + if value.is_a? Array + if value.includes?(match_value) + results[name] = config + end + else + if value == match_value + results[name] = config + end + end + end + end + results + else + super + end + end + + def <<(config) + if config.is_a? ConfigList + self.merge!(config) + else + self[config['name']] = config + end + end + + # + # converts the hash of configs into an array of hashes, with ONLY the specified fields + # + def fields(*fields) + result = [] + keys.sort.each do |name| + result << self[name].to_h(*fields) + end + result + end + + # + # like fields(), but returns an array of values instead of an array of hashes. + # + def field(field) + field = field.to_s + result = [] + keys.sort.each do |name| + result << self[name][field] + end + result + end + + end +end diff --git a/cli/lib/leap_cli/config_manager.rb b/cli/lib/leap_cli/config_manager.rb new file mode 100644 index 0000000..d383cc1 --- /dev/null +++ b/cli/lib/leap_cli/config_manager.rb @@ -0,0 +1,200 @@ +require 'oj' +require 'yaml' + +module LeapCli + + class ConfigManager + + attr_reader :services, :tags, :nodes + + ## + ## IMPORT EXPORT + ## + + # + # load .json configuration files + # + def load(dir) + @services = load_all_json("#{dir}/services/*.json") + @tags = load_all_json("#{dir}/tags/*.json") + @common = load_all_json("#{dir}/common.json")['common'] + @nodes = load_all_json("#{dir}/nodes/*.json", :node) + @nodes.each do |name, node| + apply_inheritance(node) + end + @nodes.each do |name, node| + node.each {|key,value| node[key] } # force evaluation of dynamic values + end + end + + # + # save compiled hiera .yaml files + # + def export(dir) + Dir.glob(dir + '/*.yaml').each do |f| + File.unlink(f) + end + @nodes.each do |name, node| + File.open("#{dir}/#{name}.#{node.domain_internal}.yaml", 'w') do |f| + f.write node.to_yaml + end + end + end + + ## + ## FILTERING + ## + + # + # returns a node list consisting only of nodes that satisfy the filter criteria. + # + # filter: condition [condition] [condition] [+condition] + # condition: [node_name | service_name | tag_name] + # + # if conditions is prefixed with +, then it works like an AND. Otherwise, it works like an OR. + # + def filter(filters) + if filters.empty? + return nodes + end + if filters[0] =~ /^\+/ + # don't let the first filter have a + prefix + filters[0] = filters[0][1..-1] + end + + node_list = ConfigList.new + filters.each do |filter| + if filter =~ /^\+/ + keep_list = nodes_for_filter(filter[1..-1]) + node_list.delete_if do |name, node| + if keep_list[name] + false + else + true + end + end + else + node_list << nodes_for_filter(filter) + end + end + return node_list + end + + ## + ## CLASS METHODS + ## + + def self.manager + @manager ||= begin + manager = ConfigManager.new + manager.load(Path.provider) + manager + end + end + + def self.filter(filters); manager.filter(filters); end + def self.nodes; manager.nodes; end + def self.services; manager.services; end + def self.tags; manager.tags; end + + private + + def load_all_json(pattern, config_type = :class) + results = ConfigList.new + Dir.glob(pattern).each do |filename| + obj = load_json(filename, config_type) + if obj + name = File.basename(filename).sub(/\.json$/,'') + obj['name'] = name + results[name] = obj + end + end + results + end + + def load_json(filename, config_type) + log2 { filename.sub(/^#{Regexp.escape(Path.root)}/,'') } + + # + # read file, strip out comments + # (File.read(filename) would be faster, but we like ability to have comments) + # + buffer = StringIO.new + File.open(filename) do |f| + while (line = f.gets) + next if line =~ /^\s*#/ + buffer << line + end + end + + # parse json, and flatten hash + begin + hash = Oj.load(buffer.string) || {} + rescue SyntaxError => exc + log0 'Error in file "%s":' % filename + log0 exc.to_s + return nil + end + return flatten_hash(hash, Config.new(config_type, self)) + end + + # + # remove all the nesting from a hash. + # + def flatten_hash(input = {}, output = {}, options = {}) + input.each do |key, value| + key = options[:prefix].nil? ? "#{key}" : "#{options[:prefix]}#{options[:delimiter]||"_"}#{key}" + if value.is_a? Hash + flatten_hash(value, output, :prefix => key, :delimiter => options[:delimiter]) + else + output[key] = value + end + end + output + end + + # + # makes this node inherit options from the common, service, and tag json files. + # + def apply_inheritance(node) + new_node = Config.new(:node, self) + new_node.merge!(@common) + if node['services'] + node['services'].sort.each do |node_service| + service = @services[node_service] + if service.nil? + log0('Error in node "%s": the service "%s" does not exist.' % [node['name'], node_service]) + else + new_node.merge!(service) + service.nodes << node # this is odd, but we want the node pointer, not new_node pointer. + end + end + end + if node['tags'] + node['tags'].sort.each do |node_tag| + tag = @tags[node_tag] + if tag.nil? + log0('Error in node "%s": the tag "%s" does not exist.' % [node['name'], node_tag]) + else + new_node.merge!(tag) + tag.nodes << node + end + end + end + new_node.merge!(node) + node.replace(new_node) + end + + def nodes_for_filter(filter) + if node = self.nodes[filter] + ConfigList.new(node) + elsif service = self.services[filter] + service.nodes + elsif tag = self.tags[filter] + tag.nodes + end + end + + end + +end diff --git a/cli/lib/leap_cli/init.rb b/cli/lib/leap_cli/init.rb new file mode 100644 index 0000000..bebede7 --- /dev/null +++ b/cli/lib/leap_cli/init.rb @@ -0,0 +1,74 @@ +require 'fileutils' + +module LeapCli + # + # creates new provider directory + # + def self.init(directory) + dirs = [directory] + mkdirs(dirs, false, false) + + Dir.chdir(directory) do + dirs = ["nodes", "services", "keys", "tags"] + mkdirs(dirs, false, false) + + #puts "Creating .provider" + #FileUtils.touch('.provider') + + mkfile("provider.json", PROVIDER_CONTENT) + mkfile("common.json", COMMON_CONTENT) + end + end + + def self.mkfile(filename, content) + puts "Creating #{filename}" + File.open(filename, 'w') do |f| + f.write content + end + end + + def self.mkdirs(dirs,force,dry_run) + exists = false + if !force + dirs.each do |dir| + if File.exist? dir + raise "#{dir} exists; use --force to override" + exists = true + end + end + end + if !exists + dirs.each do |dir| + puts "Creating #{dir}/" + if dry_run + puts "dry-run; #{dir} not created" + else + FileUtils.mkdir_p dir + end + end + else + puts "Exiting..." + return false + end + true + end + + PROVIDER_CONTENT = <<EOS +# +# Global provider definition file. +# +{ + "domain": "example.org" +} +EOS + + COMMON_CONTENT = <<EOS +# +# Options put here are inherited by all nodes. +# +{ + "domain": "example.org" +} +EOS + +end diff --git a/cli/lib/leap_cli/log.rb b/cli/lib/leap_cli/log.rb new file mode 100644 index 0000000..f51ca1e --- /dev/null +++ b/cli/lib/leap_cli/log.rb @@ -0,0 +1,44 @@ +module LeapCli + + def self.log_level + @log_level + end + + def self.log_level=(value) + @log_level = value + end + +end + +def log0(message=nil, &block) + if message + puts message + elsif block + puts yield(block) + end +end + +def log1(message=nil, &block) + if LeapCli.log_level > 0 + if message + puts message + elsif block + puts yield(block) + end + end +end + +def log2(message=nil, &block) + if LeapCli.log_level > 1 + if message + puts message + elsif block + puts yield(block) + end + end +end + +def help!(message=nil) + ENV['GLI_DEBUG'] = "false" + help_now!(message) +end diff --git a/cli/lib/leap_cli/path.rb b/cli/lib/leap_cli/path.rb new file mode 100644 index 0000000..5dc8fe8 --- /dev/null +++ b/cli/lib/leap_cli/path.rb @@ -0,0 +1,79 @@ +require 'fileutils' + +module LeapCli + module Path + + def self.root + @root ||= File.expand_path("#{provider}/..") + end + + def self.platform + @platform ||= File.expand_path("#{root}/leap_platform") + end + + def self.provider + @provider ||= if @root + File.expand_path("#{root}/provider") + else + find_in_directory_tree('provider.json') + end + end + + def self.hiera + @hiera ||= "#{provider}/hiera" + end + + def self.files + @files ||= "#{provider}/files" + end + + def self.ok? + provider != '/' + end + + def self.set_root(root_path) + @root = File.expand_path(root_path) + raise "No such directory '#{@root}'" unless File.directory?(@root) + end + + def self.ensure_dir(dir) + unless File.directory?(dir) + if File.exists?(dir) + raise 'Unable to create directory "%s", file already exists.' % dir + else + FileUtils.mkdir_p(dir) + end + end + end + + def self.find_file(name, filename) + path = [Path.files, filename].join('/') + return path if File.exists?(path) + path = [Path.files, name, filename].join('/') + return path if File.exists?(path) + path = [Path.files, 'nodes', name, filename].join('/') + return path if File.exists?(path) + path = [Path.files, 'services', name, filename].join('/') + return path if File.exists?(path) + path = [Path.files, 'tags', name, filename].join('/') + return path if File.exists?(path) + + # give up + return nil + end + + private + + def self.find_in_directory_tree(filename) + search_dir = Dir.pwd + while search_dir != "/" + Dir.foreach(search_dir) do |f| + return search_dir if f == filename + end + search_dir = File.dirname(search_dir) + end + return search_dir + end + + end +end diff --git a/cli/lib/leap_cli/version.rb b/cli/lib/leap_cli/version.rb new file mode 100644 index 0000000..c272647 --- /dev/null +++ b/cli/lib/leap_cli/version.rb @@ -0,0 +1,3 @@ +module LeapCli + VERSION = '0.0.1' +end diff --git a/cli/test/default_test.rb b/cli/test/default_test.rb new file mode 100644 index 0000000..c363bbb --- /dev/null +++ b/cli/test/default_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class DefaultTest < Test::Unit::TestCase + + def setup + end + + def teardown + end + + def test_the_truth + assert true + end +end diff --git a/cli/test/provider/common.json b/cli/test/provider/common.json new file mode 100644 index 0000000..ead9d68 --- /dev/null +++ b/cli/test/provider/common.json @@ -0,0 +1,11 @@ +# +# Options put here are inherited by all nodes. +# +{ + "domain": { + "public": "rewire.co", + "internal": "rewire" + }, + "public_dns": true, + "fqdn": "= name + '.' + (public_dns ? domain_public : domain_internal)" +} diff --git a/cli/test/provider/files/ca/ca.crt b/cli/test/provider/files/ca/ca.crt new file mode 100644 index 0000000..ed12e15 --- /dev/null +++ b/cli/test/provider/files/ca/ca.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIECzCCAl2gAwIBAgIEUFDp9TANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRU +RVNUMB4XDTEyMDkxMjIwMDA1M1oXDTEzMDkxMjIwMDA1M1owDzENMAsGA1UEAxME +VEVTVDCCAbgwDQYJKoZIhvcNAQEBBQADggGlADCCAaACggGXANsoS1m9wj9iv+UV +BXfeq14SR94gSot96eJu7PZVRrcGlGe/PRfbmfxF3j/gXM9B8sIkyM2L46OMtOKw +1iOTKtYYdMhtnUSd3FRshWGtYeuy+OCe9umU0jfZDBZ2pXlUmSqCNqfD0OPkksYL +GDjQUKjaEd1oURwpCG8uEU+3tjBNCMuEwhcMEoUYmI8t4vss2hdFb+LKefVMPTzz +oiNM/o8Z/ANzWCC0qSW5FsB4wGhUS5HKLDOr4tACgdxaJSWtAqFFAnyMeG9g8aqe +PTM+URlqVnzzGckrJwBbd4y0zEpv/R7SAiSAP725cnB1GKptwdrcNIIHnQjOdAOl +uNg6JlRXrv6fV1gApka4INfJAf1yMf+fA0WdZ22UJQ9Up7tdzi8lL+3HsEpEx4Pz +NyzuqzEw9LJ6SUmMcE/VP00t4RjTOVoncwcLjvURY8jt2DQ9E36JEPwUoyALq/De +bGBjeK2KGzBZcOu1HZAwWLLWR2++WKuCEXbRbahwSIlbMfmAe8xGx4bbHol0D1A+ +wmu0uxjAze6FvUkCAwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8E +BQMDBwQAMB0GA1UdDgQWBBT/PX8XZ0Y2jDkppz6PHs23IgzQEDANBgkqhkiG9w0B +AQsFAAOCAZcAMfi+HLbcFaB0/Mv8/GkIdjpThUBVEeFrIiDy9GmGWUDOXgP1Skld +5H4eY5inE5lFfB69yacHIGS4OiZIBuBKfKNl5d6XO+ztJEJpG3yrbF4MtGV/aHEp +OlbJCncnk3fspBk6tFGrv4Inak4gza6SQPfBEZj29ciwfwrqrtuWZ7km+og0Clcd +pIB0g+DK0K//NtaDZDK0havQw2AFJKyXlNfI8XZ2jsNmQYR1wtiMci+UfGQr7bjn +Kw9yyVCf0ohXvnSK4ortz/bDQbcMWkK0m/VCCEK8PSldk+XFzPWFWn5ndKCczcvd +1BQc392n12ZstEuzm6+d9A0D3kCxralJUXUC+4kThq4Rtjey/gBjyZQnZ+5tIxMF +5ZFAStEglNxqm6HB17q7owJqTvIg9Cf9GATsvoFFQDJrBXewRX7cWVeSr0zNSQB4 +ydIlSUOkyE3AyfLN+lx8NVS/I7gp4fWDuHrh27NKKDtMxalxPL5pTGO7l4uTybLY +4aVzQYGvzA5HVS++VAtcTQ6TP9p4HURL2cllEU9u9A== +-----END CERTIFICATE----- diff --git a/cli/test/provider/files/ca/ca.key b/cli/test/provider/files/ca/ca.key new file mode 100644 index 0000000..9721c35 --- /dev/null +++ b/cli/test/provider/files/ca/ca.key @@ -0,0 +1,41 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/cli/test/provider/files/public-definitions/provider.json.erb b/cli/test/provider/files/public-definitions/provider.json.erb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/cli/test/provider/files/public-definitions/provider.json.erb diff --git a/cli/test/provider/files/vpn1/vpn1.rewire.co.crt b/cli/test/provider/files/vpn1/vpn1.rewire.co.crt new file mode 100644 index 0000000..d2c9734 --- /dev/null +++ b/cli/test/provider/files/vpn1/vpn1.rewire.co.crt @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEWjCCAqygAwIBAgIEUFDqXzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRU +RVNUMB4XDTEyMDkxMjIwMDIzOVoXDTEzMDkxMjIwMDIzOVowKzEPMA0GA1UEChMG +eHgub3JnMRgwFgYDVQQDEw9ob3N0bmFtZS54eC5vcmcwggG4MA0GCSqGSIb3DQEB +AQUAA4IBpQAwggGgAoIBlwCvGqkXry509EWGAqbFUB5nqvsvA3kSIh0prgzaPYCg +MMst58ZB89eTgiuM+U3jSF7LZr+CuE1DAb4m2U2f8D8IfViwK1yCa5AohG+LCmwe +4w4bgXtxwEBDac4u23JZ4AKE/EcKMeBbXe2d3o1S3P3XdN1ZVP0DVw04+H8cdh+0 +ggvhAA+9W/NvAQCAffL8sospj9nbl2OhRnrlFAzMWECyEyySPK5TEchU0hnFBRys +DuYso5klLC6QXfSOkCSCOg9WQgjoyYBndTYxS3GwBnwyM+5V4TNtdc+P4vkkj+ZB +D9R9oMpamUuuRQvk5/hJa7i8AaBy7ZmOO9QtL3866ONa6cLUN/QfBUkgM5iS6oQt +X/qKxZFFYZPZUGBJqavuT+n4FB8XlIwcnqunK7rLD9OZwumYuZlHDtdAsgQ9Fd2z +06e7sDp28jcrk6gmpOapLqNPtPHVOGNA6mCZza4LonDMOSQKTfb6ZEXty+a8f2ig +zErhHvmyCvREytDc9pIf2bL+Sz4ULTq62GDKf1Y3tRi2uHFjhKLTAgMBAAGjdjB0 +MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/BAUD +AwegADAdBgNVHQ4EFgQUmQ5YZjESlkYq2FBaYqGp2HAnSfAwHwYDVR0jBBgwFoAU +/z1/F2dGNow5Kac+jx7NtyIM0BAwDQYJKoZIhvcNAQELBQADggGXAHiaPMSeIzac +rRZQ/dJA7VDgvuFcY67zj9531zsDVi848kBkpSZ+9UyZOdhy5b9Din/IAVvd/XUP ++VWwVsvKPbrWK79T/w8wj5nQR0uYfLdpMu7ZGjPhNes+/DnMX8Are2eb012g1km/ +HhOUxNg8/YpOJI4ZRnZls7j+u5kmHhc47sOQH9sY1FkHcWJ+K/lVhTk8Fmcm1vbN +p7rjO4BItPVDxle0XF6bItwF1ahsK9MTzJIEO9ulHQnKYdhT9BcJbcwA3vhcn8nN +uPN/RbDcWZTjONy58LVr7GxDQ267nZs5/wj4Cv3vDVq83kQJ7lCsYGTvxOejHWeQ +QjcXREdBih9CPO3f86TOI8GRipIGvDcEll4DzgGRi+uTSWG69uC9yud/7+rnLd9Z +WlobzAzRwljnR3aNACq0adYv1Wl05Fi2ab+QqL/C5ySrF5jL4OFUMpBu7nDPjty0 +KjQSmI9t6By6ORx14XT6piSlvSFn5phdMexXx1AYZEtdPSQduh2OquIPjN/qSdHO +J+ZXOqDL1Jv+a89ghE8= +-----END CERTIFICATE----- diff --git a/cli/test/provider/files/vpn1/vpn1.rewire.co.key b/cli/test/provider/files/vpn1/vpn1.rewire.co.key new file mode 100644 index 0000000..3fdf38a --- /dev/null +++ b/cli/test/provider/files/vpn1/vpn1.rewire.co.key @@ -0,0 +1,41 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/cli/test/provider/hiera/couch1.rewire.yaml b/cli/test/provider/hiera/couch1.rewire.yaml new file mode 100644 index 0000000..2c731ce --- /dev/null +++ b/cli/test/provider/hiera/couch1.rewire.yaml @@ -0,0 +1,8 @@ +--- +domain_internal: rewire +domain_public: rewire.co +fqdn: couch1.rewire +ip_address: 245.2.45.42 +name: couch1 +public_dns: false +services: couchdb diff --git a/cli/test/provider/hiera/couch2.rewire.yaml b/cli/test/provider/hiera/couch2.rewire.yaml new file mode 100644 index 0000000..a835c79 --- /dev/null +++ b/cli/test/provider/hiera/couch2.rewire.yaml @@ -0,0 +1,8 @@ +--- +domain_internal: rewire +domain_public: rewire.co +fqdn: couch2.rewire +ip_address: 73.45.87.11 +name: couch2 +public_dns: false +services: couchdb diff --git a/cli/test/provider/hiera/ns1.rewire.yaml b/cli/test/provider/hiera/ns1.rewire.yaml new file mode 100644 index 0000000..264dd52 --- /dev/null +++ b/cli/test/provider/hiera/ns1.rewire.yaml @@ -0,0 +1,25 @@ +--- +domain_internal: rewire +domain_public: rewire.co +fqdn: ns1.rewire.co +hosts_private: +- ip_address: 245.2.45.42 + fqdn: couch1.rewire +- ip_address: 73.45.87.11 + fqdn: couch2.rewire +hosts_public: +- ip_address: 1.1.1.1 + fqdn: ns1.rewire.co +- ip_address: 1.1.1.2 + fqdn: ns2.rewire.co +- ip_address: 2.2.2.2 + fqdn: vpn1.rewire.co +- ip_address: 6.6.7.7 + fqdn: web1.rewire.co + dns_alias: user.rewire.co +ip_address: 1.1.1.1 +name: ns1 +production: true +public_dns: true +services: dns +tags: production diff --git a/cli/test/provider/hiera/ns2.rewire.yaml b/cli/test/provider/hiera/ns2.rewire.yaml new file mode 100644 index 0000000..2885424 --- /dev/null +++ b/cli/test/provider/hiera/ns2.rewire.yaml @@ -0,0 +1,25 @@ +--- +domain_internal: rewire +domain_public: rewire.co +fqdn: ns2.rewire.co +hosts_private: +- ip_address: 245.2.45.42 + fqdn: couch1.rewire +- ip_address: 73.45.87.11 + fqdn: couch2.rewire +hosts_public: +- ip_address: 1.1.1.1 + fqdn: ns1.rewire.co +- ip_address: 1.1.1.2 + fqdn: ns2.rewire.co +- ip_address: 2.2.2.2 + fqdn: vpn1.rewire.co +- ip_address: 6.6.7.7 + fqdn: web1.rewire.co + dns_alias: user.rewire.co +ip_address: 1.1.1.2 +name: ns2 +production: true +public_dns: true +services: dns +tags: production diff --git a/cli/test/provider/hiera/vpn1.rewire.yaml b/cli/test/provider/hiera/vpn1.rewire.yaml new file mode 100644 index 0000000..158bb1b --- /dev/null +++ b/cli/test/provider/hiera/vpn1.rewire.yaml @@ -0,0 +1,158 @@ +--- +domain_internal: rewire +domain_public: rewire.co +fqdn: vpn1.rewire.co +ip_address: 2.2.2.2 +name: vpn1 +openvpn_ca_crt: | + -----BEGIN CERTIFICATE----- + MIIECzCCAl2gAwIBAgIEUFDp9TANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRU + RVNUMB4XDTEyMDkxMjIwMDA1M1oXDTEzMDkxMjIwMDA1M1owDzENMAsGA1UEAxME + VEVTVDCCAbgwDQYJKoZIhvcNAQEBBQADggGlADCCAaACggGXANsoS1m9wj9iv+UV + BXfeq14SR94gSot96eJu7PZVRrcGlGe/PRfbmfxF3j/gXM9B8sIkyM2L46OMtOKw + 1iOTKtYYdMhtnUSd3FRshWGtYeuy+OCe9umU0jfZDBZ2pXlUmSqCNqfD0OPkksYL + GDjQUKjaEd1oURwpCG8uEU+3tjBNCMuEwhcMEoUYmI8t4vss2hdFb+LKefVMPTzz + oiNM/o8Z/ANzWCC0qSW5FsB4wGhUS5HKLDOr4tACgdxaJSWtAqFFAnyMeG9g8aqe + PTM+URlqVnzzGckrJwBbd4y0zEpv/R7SAiSAP725cnB1GKptwdrcNIIHnQjOdAOl + uNg6JlRXrv6fV1gApka4INfJAf1yMf+fA0WdZ22UJQ9Up7tdzi8lL+3HsEpEx4Pz + NyzuqzEw9LJ6SUmMcE/VP00t4RjTOVoncwcLjvURY8jt2DQ9E36JEPwUoyALq/De + bGBjeK2KGzBZcOu1HZAwWLLWR2++WKuCEXbRbahwSIlbMfmAe8xGx4bbHol0D1A+ + wmu0uxjAze6FvUkCAwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8E + BQMDBwQAMB0GA1UdDgQWBBT/PX8XZ0Y2jDkppz6PHs23IgzQEDANBgkqhkiG9w0B + AQsFAAOCAZcAMfi+HLbcFaB0/Mv8/GkIdjpThUBVEeFrIiDy9GmGWUDOXgP1Skld + 5H4eY5inE5lFfB69yacHIGS4OiZIBuBKfKNl5d6XO+ztJEJpG3yrbF4MtGV/aHEp + OlbJCncnk3fspBk6tFGrv4Inak4gza6SQPfBEZj29ciwfwrqrtuWZ7km+og0Clcd + pIB0g+DK0K//NtaDZDK0havQw2AFJKyXlNfI8XZ2jsNmQYR1wtiMci+UfGQr7bjn + Kw9yyVCf0ohXvnSK4ortz/bDQbcMWkK0m/VCCEK8PSldk+XFzPWFWn5ndKCczcvd + 1BQc392n12ZstEuzm6+d9A0D3kCxralJUXUC+4kThq4Rtjey/gBjyZQnZ+5tIxMF + 5ZFAStEglNxqm6HB17q7owJqTvIg9Cf9GATsvoFFQDJrBXewRX7cWVeSr0zNSQB4 + ydIlSUOkyE3AyfLN+lx8NVS/I7gp4fWDuHrh27NKKDtMxalxPL5pTGO7l4uTybLY + 4aVzQYGvzA5HVS++VAtcTQ6TP9p4HURL2cllEU9u9A== + -----END CERTIFICATE----- + +openvpn_ca_key: | + -----BEGIN RSA PRIVATE KEY----- + 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 + -----END RSA PRIVATE KEY----- + +openvpn_filter_dns: false +openvpn_gateway_address: 3.3.3.3 +openvpn_nat: true +openvpn_ports: +- "80" +- "443" +- "53" +- "1194" +openvpn_server_crt: | + -----BEGIN CERTIFICATE----- + MIIEWjCCAqygAwIBAgIEUFDqXzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRU + RVNUMB4XDTEyMDkxMjIwMDIzOVoXDTEzMDkxMjIwMDIzOVowKzEPMA0GA1UEChMG + eHgub3JnMRgwFgYDVQQDEw9ob3N0bmFtZS54eC5vcmcwggG4MA0GCSqGSIb3DQEB + AQUAA4IBpQAwggGgAoIBlwCvGqkXry509EWGAqbFUB5nqvsvA3kSIh0prgzaPYCg + MMst58ZB89eTgiuM+U3jSF7LZr+CuE1DAb4m2U2f8D8IfViwK1yCa5AohG+LCmwe + 4w4bgXtxwEBDac4u23JZ4AKE/EcKMeBbXe2d3o1S3P3XdN1ZVP0DVw04+H8cdh+0 + ggvhAA+9W/NvAQCAffL8sospj9nbl2OhRnrlFAzMWECyEyySPK5TEchU0hnFBRys + DuYso5klLC6QXfSOkCSCOg9WQgjoyYBndTYxS3GwBnwyM+5V4TNtdc+P4vkkj+ZB + D9R9oMpamUuuRQvk5/hJa7i8AaBy7ZmOO9QtL3866ONa6cLUN/QfBUkgM5iS6oQt + X/qKxZFFYZPZUGBJqavuT+n4FB8XlIwcnqunK7rLD9OZwumYuZlHDtdAsgQ9Fd2z + 06e7sDp28jcrk6gmpOapLqNPtPHVOGNA6mCZza4LonDMOSQKTfb6ZEXty+a8f2ig + zErhHvmyCvREytDc9pIf2bL+Sz4ULTq62GDKf1Y3tRi2uHFjhKLTAgMBAAGjdjB0 + MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/BAUD + AwegADAdBgNVHQ4EFgQUmQ5YZjESlkYq2FBaYqGp2HAnSfAwHwYDVR0jBBgwFoAU + /z1/F2dGNow5Kac+jx7NtyIM0BAwDQYJKoZIhvcNAQELBQADggGXAHiaPMSeIzac + rRZQ/dJA7VDgvuFcY67zj9531zsDVi848kBkpSZ+9UyZOdhy5b9Din/IAVvd/XUP + +VWwVsvKPbrWK79T/w8wj5nQR0uYfLdpMu7ZGjPhNes+/DnMX8Are2eb012g1km/ + HhOUxNg8/YpOJI4ZRnZls7j+u5kmHhc47sOQH9sY1FkHcWJ+K/lVhTk8Fmcm1vbN + p7rjO4BItPVDxle0XF6bItwF1ahsK9MTzJIEO9ulHQnKYdhT9BcJbcwA3vhcn8nN + uPN/RbDcWZTjONy58LVr7GxDQ267nZs5/wj4Cv3vDVq83kQJ7lCsYGTvxOejHWeQ + QjcXREdBih9CPO3f86TOI8GRipIGvDcEll4DzgGRi+uTSWG69uC9yud/7+rnLd9Z + WlobzAzRwljnR3aNACq0adYv1Wl05Fi2ab+QqL/C5ySrF5jL4OFUMpBu7nDPjty0 + KjQSmI9t6By6ORx14XT6piSlvSFn5phdMexXx1AYZEtdPSQduh2OquIPjN/qSdHO + J+ZXOqDL1Jv+a89ghE8= + -----END CERTIFICATE----- + +openvpn_server_key: | + -----BEGIN RSA PRIVATE KEY----- + MIIHRwIBAAKCAZcArxqpF68udPRFhgKmxVAeZ6r7LwN5EiIdKa4M2j2AoDDLLefG + QfPXk4IrjPlN40hey2a/grhNQwG+JtlNn/A/CH1YsCtcgmuQKIRviwpsHuMOG4F7 + ccBAQ2nOLttyWeAChPxHCjHgW13tnd6NUtz913TdWVT9A1cNOPh/HHYftIIL4QAP + vVvzbwEAgH3y/LKLKY/Z25djoUZ65RQMzFhAshMskjyuUxHIVNIZxQUcrA7mLKOZ + JSwukF30jpAkgjoPVkII6MmAZ3U2MUtxsAZ8MjPuVeEzbXXPj+L5JI/mQQ/UfaDK + WplLrkUL5Of4SWu4vAGgcu2ZjjvULS9/OujjWunC1Df0HwVJIDOYkuqELV/6isWR + RWGT2VBgSamr7k/p+BQfF5SMHJ6rpyu6yw/TmcLpmLmZRw7XQLIEPRXds9Onu7A6 + dvI3K5OoJqTmqS6jT7Tx1ThjQOpgmc2uC6JwzDkkCk32+mRF7cvmvH9ooMxK4R75 + sgr0RMrQ3PaSH9my/ks+FC06uthgyn9WN7UYtrhxY4Si0wIDAQABAoIBlgvJw7Bw + frQo7bVD4G5QInvgKuDTXwc1fLkdmofmtA4UutjwTYyLGew4Sy5GalPuv1L6K9Jl + De6A44hCANPPnK65oYraoHO3QhE4OTonDXhW2NBJO0JBKxJewR6ub1hVmFXTlgS9 + rtj3zdNe9Cyr6/rhRzWIXzAmYCGBuSz1VtUUHDCdjHG3CwBiFOKRmBYi/vNhV81M + t8xXrlZVrzbiihhy6gE+TI4TGGV9b3awDWoX5q8CpIC4JLpbWOdwFMUfm4C3GVpy + lk5gubE/wnXiQyzqEzyHzC3OrNyh/JTbz2XBi+Agc45gRFL6t3EstNJY14lWwAy5 + pwLUFQnwVJQ0ljtA+qMo5nwGBaHgj1TutshLLcrP+cikule5DYm23VHU/u4epYPM + hEB6KrYr7h3/IhXJ5rp5kmsJKGlg1vyPkwcskL5fMiN1BnPV5cwmrg574SsoDydr + u40DJiijABVJG2aTnlOMGKyrnkbbOTq3adxjIWPPTK5r95pOWp3TpZWQzGa8Waum + Q3S9LpmGCiVnuXTyGqRXAeECgcwAzPJWd5P/lCrVgmCd+cc+ldbG2SLQ/v3vDqe3 + R0UPnkIkmOOKw9cgC9qy8XgZb2hcRKDwifZBCVKTVi3NAdtF9WF5DLmwBP2NGdWk + vNz9NF5Zd0GYa78Dec6Ej6nOJauDi5ymiJQxexx+N3I/ZjJMOpnIePz1yQbiB9dF + YM6lifd8WoeahOvp1m92qlF637JL7hmXjagB0H+27bLgDD7dtUcigYMvPOuO5S0s + Ec1PRg0lNhym9sJ0xm7uby88i83RyQKbCFEHyuQFZS8CgcwA2rk8X6WPF6NTmYP5 + VXnMAW1T1CoHCWQOW3KaYCHHgdWVTVl7MKXZ1zxz/8pKySX+QJrUsobSn7xjxGqT + ZTcbhaFtEsfS4meEyn2Ef+yT2kslF59aYQfFAQ2HR5bhg2kNXFPwIpV3o5zwmJH9 + 5H32XHjpneHT5QjTvQezsHtQbl61w8QqEmB5Cy5ZzcfSp+iZnR1gBquVgRSLpphE + sUzmTAlm2W8FZNLw1cDyB+8hNDrp/t9RQfJzzcCi4TAgZWy+DKjO7nj6tl7oe50C + gctgtVXh9T9b3l6DuC2zaLZ6pC+O1KQEPzUoGDIe+lKlXhbA4lZflUq07U0VLpPq + AzfO1pbKsx37VTDbMJ+Vaa/4WzdwrsqFgFOtxieHS0xcAs16vcQ7y5XLS4038Wuq + UOWw4ome1zcGHerdJRcPlVptKJX1qYAdjRbplkZRqRFqKhNO8MAUSvI70rsPIYW2 + uv6jawYdvRKmHS3nukmI3b1mxhtdO9b1iz4RnKA4AkaPCrLtdtW+iQHrhPsUEhki + 60s76/PWF85yieiV1wKBzACauN5UarFGb2r79bezF22QtN3P/8rqgbUGS5OY3Uxc + M9Jh3SKfzzLCZylHkLpGgHHTEbPUdjsYdBO/JgUOXGVDqmWWG3S6Y7Az7YaFV71f + djjO9RLiALUDgaZopfrxEqc44MfGLyVqv+ISi3Om5tQXphDcdpuGMTBXT9N0zEah + TK4XxfRc+5Gkry0nvGrwDEJeOiFrloUzwmzndF9jbJqcvynaNgcCw5VKICsWIbrD + T8mnWiIJHJF+wv51fa3tEXd/TQrU9w+jYo/ioQKBzACluagmFiDwMcJFowdUYyya + WJtxEQHej5PfyHRijBZ/qzhvPxyF2Ae2D5L9RS+uHsJA0ZVJDQgzkvrSZ8IcS/Q4 + q+zX3/AzgDL6IQGQIsETaAmFCco4RMLFaDMyDx/OJR29df+ibqYvfSoUkcmK8OyF + PWS0AobzJnqIaDpRCCvD/sL9PCkrUm33HoDBfxuvEsqZypNVmq+/3myWc9gIMOmZ + fpWS+744tFnNO9RdmZ8OZel4+iv8CGZvQxk14S+lpaSCpX+Zmfyy5PfPRg== + -----END RSA PRIVATE KEY----- + +production: true +public_dns: true +services: openvpn +tags: production diff --git a/cli/test/provider/hiera/web1.rewire.yaml b/cli/test/provider/hiera/web1.rewire.yaml new file mode 100644 index 0000000..6fc76d9 --- /dev/null +++ b/cli/test/provider/hiera/web1.rewire.yaml @@ -0,0 +1,16 @@ +--- +dns_alias: user.rewire.co +domain_internal: rewire +domain_public: rewire.co +fqdn: web1.rewire.co +ip_address: 6.6.7.7 +name: web1 +public_dns: true +services: webapp +webapp_couchdb_hosts: +- couch1.rewire +- couch2.rewire +webapp_modules: +- user +- billing +- help diff --git a/cli/test/provider/nodes/couch1.json b/cli/test/provider/nodes/couch1.json new file mode 100644 index 0000000..fe5d7e5 --- /dev/null +++ b/cli/test/provider/nodes/couch1.json @@ -0,0 +1,4 @@ +{ + "services": "couchdb", + "ip_address": "245.2.45.42" +}
\ No newline at end of file diff --git a/cli/test/provider/nodes/couch2.json b/cli/test/provider/nodes/couch2.json new file mode 100644 index 0000000..1fe2977 --- /dev/null +++ b/cli/test/provider/nodes/couch2.json @@ -0,0 +1,4 @@ +{ + "services": "couchdb", + "ip_address": "73.45.87.11" +}
\ No newline at end of file diff --git a/cli/test/provider/nodes/ns1.json b/cli/test/provider/nodes/ns1.json new file mode 100644 index 0000000..6323d10 --- /dev/null +++ b/cli/test/provider/nodes/ns1.json @@ -0,0 +1,8 @@ +# +# this is a comment +# +{ + "services": "dns", + "tags": "production", + "ip_address": "1.1.1.1" +}
\ No newline at end of file diff --git a/cli/test/provider/nodes/ns2.json b/cli/test/provider/nodes/ns2.json new file mode 100644 index 0000000..eeba9df --- /dev/null +++ b/cli/test/provider/nodes/ns2.json @@ -0,0 +1,8 @@ +# +# A nameserver +# +{ + "services": "dns", + "tags": "production", + "ip_address": "1.1.1.2" +}
\ No newline at end of file diff --git a/cli/test/provider/nodes/vpn1.json b/cli/test/provider/nodes/vpn1.json new file mode 100644 index 0000000..10859ac --- /dev/null +++ b/cli/test/provider/nodes/vpn1.json @@ -0,0 +1,8 @@ +{ + "services": "openvpn", + "ip_address": "2.2.2.2", + "tags": "production", + "openvpn": { + "gateway_address": "3.3.3.3" + } +}
\ No newline at end of file diff --git a/cli/test/provider/nodes/web1.json b/cli/test/provider/nodes/web1.json new file mode 100644 index 0000000..894fb6e --- /dev/null +++ b/cli/test/provider/nodes/web1.json @@ -0,0 +1,4 @@ +{ + "services": "webapp", + "ip_address": "6.6.7.7" +}
\ No newline at end of file diff --git a/cli/test/provider/provider.json b/cli/test/provider/provider.json new file mode 100644 index 0000000..58b6728 --- /dev/null +++ b/cli/test/provider/provider.json @@ -0,0 +1,13 @@ +# +# General service provider configuration. +# +{ + "name": "The Rewire Company", + "description": "A demonstration service provider using the LEAP platform", + "languages": ["en"], + "ca": { + "name": "Rewire Root CA", + "organization": "#{name}", + "bit_size": 4096 + } +}
\ No newline at end of file diff --git a/cli/test/provider/services/couchdb.json b/cli/test/provider/services/couchdb.json new file mode 100644 index 0000000..7c13c8d --- /dev/null +++ b/cli/test/provider/services/couchdb.json @@ -0,0 +1,3 @@ +{ + "public_dns": false +}
\ No newline at end of file diff --git a/cli/test/provider/services/dns.json b/cli/test/provider/services/dns.json new file mode 100644 index 0000000..3fea381 --- /dev/null +++ b/cli/test/provider/services/dns.json @@ -0,0 +1,6 @@ +{ + "hosts": { + "public": "= nodes[:public_dns => true].fields(:fqdn, :dns_alias, :ip_address)", + "private": "= nodes[:public_dns => false].fields(:fqdn, :dns_alias, :ip_address)" + } +}
\ No newline at end of file diff --git a/cli/test/provider/services/openvpn.json b/cli/test/provider/services/openvpn.json new file mode 100644 index 0000000..ffaa313 --- /dev/null +++ b/cli/test/provider/services/openvpn.json @@ -0,0 +1,11 @@ +{ + "openvpn": { + "ports": ["80", "443", "53", "1194"], + "filter_dns": false, + "nat": true, + "ca_crt": "= file 'ca/ca.crt'", + "ca_key": "= file 'ca/ca.key'", + "server_crt": "= file fqdn + '.crt'", + "server_key": "= file fqdn + '.key'" + } +} diff --git a/cli/test/provider/services/webapp.json b/cli/test/provider/services/webapp.json new file mode 100644 index 0000000..1513d6f --- /dev/null +++ b/cli/test/provider/services/webapp.json @@ -0,0 +1,7 @@ +{ + "dns_alias": "= 'user.' + domain_public", + "webapp": { + "modules": ["user", "billing", "help"], + "couchdb_hosts": "= nodes[:services => :couchdb].field(:fqdn)" + } +}
\ No newline at end of file diff --git a/cli/test/provider/tags/production.json b/cli/test/provider/tags/production.json new file mode 100644 index 0000000..b35c065 --- /dev/null +++ b/cli/test/provider/tags/production.json @@ -0,0 +1,3 @@ +{ + "production": true +}
\ No newline at end of file diff --git a/cli/test/test_helper.rb b/cli/test/test_helper.rb new file mode 100644 index 0000000..2e33705 --- /dev/null +++ b/cli/test/test_helper.rb @@ -0,0 +1,9 @@ +require 'test/unit' + +# Add test libraries you want to use here, e.g. mocha + +class Test::Unit::TestCase + + # Add global extensions to the test case class here + +end |