]> gitweb.fluxo.info Git - leap/leap_cli.git/commitdiff
added automatic secret generation in secrets.json
authorelijah <elijah@riseup.net>
Sun, 4 Nov 2012 19:30:16 +0000 (11:30 -0800)
committerelijah <elijah@riseup.net>
Sun, 4 Nov 2012 19:30:16 +0000 (11:30 -0800)
lib/leap_cli.rb
lib/leap_cli/commands/compile.rb
lib/leap_cli/config/manager.rb
lib/leap_cli/config/object.rb
lib/leap_cli/path.rb
lib/leap_cli/util/secret.rb [new file with mode: 0644]

index 4dccec256dbdf7d0d7b206d72dd9af77e7317361..728e501483c535c6d4be005923969876d1b41d91 100644 (file)
@@ -8,6 +8,8 @@ require 'core_ext/nil'
 require 'leap_cli/init'
 require 'leap_cli/path'
 require 'leap_cli/util'
+require 'leap_cli/util/secret'
+
 require 'leap_cli/log'
 require 'leap_cli/ssh_key'
 require 'leap_cli/config/object'
index c5bb93e015bd224f4d0337406b98e39c773e65f0..9882e6a45586e08d9ced00f7ee25b938e16f05ac 100644 (file)
@@ -5,8 +5,12 @@ module LeapCli
     desc 'Compile json files to hiera configs'
     command :compile do |c|
       c.action do |global_options,options,args|
-        update_compiled_ssh_configs                     # this must come first, hiera configs import these files.
-        manager.export Path.named_path(:hiera_dir)      # generate a hiera .yaml config for each node
+        # these must come first
+        update_compiled_ssh_configs
+
+        # export generated files
+        manager.export_nodes
+        manager.export_secrets
       end
     end
 
index 2eda7a49f008f1e7b08a92ee93f42a2f43f15fda..8a4a617181e4adf86c90ff24c80860d19387a3bb 100644 (file)
@@ -8,7 +8,7 @@ module LeapCli
     #
     class Manager
 
-      attr_reader :services, :tags, :nodes, :provider, :common
+      attr_reader :services, :tags, :nodes, :provider, :common, :secrets
 
       ##
       ## IMPORT EXPORT
@@ -18,11 +18,13 @@ module LeapCli
       # load .json configuration files
       #
       def load(provider_dir=Path.provider)
+        @provider_dir = provider_dir
         @services = load_all_json(Path.named_path([:service_config, '*'], provider_dir))
         @tags     = load_all_json(Path.named_path([:tag_config, '*'],     provider_dir))
         @nodes    = load_all_json(Path.named_path([:node_config, '*'],    provider_dir))
         @common   = load_json(Path.named_path(:common_config,   provider_dir))
         @provider = load_json(Path.named_path(:provider_config, provider_dir))
+        @secrets  = load_json(Path.named_path(:secrets_config, provider_dir))
 
         Util::assert!(@provider, "Failed to load provider.json")
         Util::assert!(@common, "Failed to load common.json")
@@ -35,7 +37,8 @@ module LeapCli
       #
       # save compiled hiera .yaml files
       #
-      def export(dir=Path.named_path(:hiera_dir))
+      def export_nodes(destination_directory = nil)
+        dir = destination_directory || Path.named_path(:hiera_dir, @provider_dir)
         existing_files = Dir.glob(dir + '/*.yaml')
         updated_files = []
         @nodes.each do |name, node|
@@ -48,6 +51,13 @@ module LeapCli
         end
       end
 
+      def export_secrets(destination_file = nil)
+        if @secrets.any?
+          file_path = destination_file || Path.named_path(:secrets_config, @provider_dir)
+          Util.write_file!(file_path, @secrets.dump_json + "\n")
+        end
+      end
+
       ##
       ## FILTERING
       ##
@@ -119,6 +129,10 @@ module LeapCli
       end
 
       def load_json(filename)
+        if !File.exists?(filename)
+          return Config::Object.new(self)
+        end
+
         #
         # read file, strip out comments
         # (File.read(filename) would be faster, but we like ability to have comments)
index 8b14c490e0022b130aa9e557d6cd236b3fb8bfb2..ad32f54d1642f6643e83d589bfc2f34ad4110629 100644 (file)
@@ -39,6 +39,10 @@ module LeapCli
         self.ya2yaml(:syck_compatible => true)
       end
 
+      def dump_json
+        generate_json(self)
+      end
+
       ##
       ## FETCHING VALUES
       ##
@@ -169,6 +173,15 @@ module LeapCli
         end
       end
 
+      #
+      # inserts a named secret, generating it if needed.
+      #
+      # manager.export_secrets should be called later to capture any newly generated secrets.
+      #
+      def secret(name, length=32)
+        @manager.secrets[name.to_s] ||= Util::Secret.generate(length)
+      end
+
       private
 
       #
index aa20e17b4a64bad95bb2c98363945879e7e3f69f..88288d0c1b16c7a676a00f2b7e9e2a0f5ca26f1a 100644 (file)
@@ -13,6 +13,7 @@ module LeapCli; module Path
     # input config files
     :common_config    => 'common.json',
     :provider_config  => 'provider.json',
+    :secrets_config   => 'secrets.json',
     :node_config      => 'nodes/#{arg}.json',
     :service_config   => 'services/#{arg}.json',
     :tag_config       => 'tags/#{arg}.json',
diff --git a/lib/leap_cli/util/secret.rb b/lib/leap_cli/util/secret.rb
new file mode 100644 (file)
index 0000000..4833caa
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# A simple alphanumeric secret generator, with no ambiguous characters.
+#
+# It also includes symbols that are treated as word characters by most
+# terminals (so you can still double click to select the entire secret).
+#
+# Uses OpenSSL random number generator instead of Ruby's rand function
+#
+
+require 'openssl'
+
+module LeapCli; module Util
+
+  class Secret
+
+    CHARS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + "_-&@%~=+".split(//u) - "io01lO".split(//u)
+
+    def self.generate(length = 10)
+      seed
+      OpenSSL::Random.random_bytes(length).bytes.to_a.collect { |byte|
+        CHARS[ byte % CHARS.length ]
+      }.join
+    end
+
+    def self.seed
+      @pid ||= 0
+      pid = $$
+      if @pid != pid
+        now = Time.now
+        OpenSSL::Random.seed( [now.to_i, now.nsec, @pid, pid].join )
+        @pid = pid
+      end
+    end
+
+  end
+
+end; end