]> review.fuel-infra Code Review - puppet-modules/puppetlabs-apt.git/commitdiff
Update to use the puppet-resource_api gem
authorDavid Schmitt <david.schmitt@puppet.com>
Mon, 11 Sep 2017 15:14:40 +0000 (16:14 +0100)
committerDavid Schmitt <david.schmitt@puppet.com>
Mon, 11 Sep 2017 15:14:40 +0000 (16:14 +0100)
Gemfile
lib/puppet/provider/apt_key2/apt_key2.rb
lib/puppet/type/apt_key2.rb
lib/puppet_x/apt_key/resource_api.rb [deleted file]

diff --git a/Gemfile b/Gemfile
index a9f0161c79e6ba92b7a4f6f7a52750339be2299e..70a6af7efb8215ae8558c173f3e03b3173f17875 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -62,6 +62,7 @@ gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION'])
 gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) if ENV['FACTER_GEM_VERSION']
 gem 'hiera', *location_for(ENV['HIERA_GEM_VERSION']) if ENV['HIERA_GEM_VERSION']
 
+gem 'puppet-resource_api', git: 'https://github.com/puppetlabs/puppet-resource_api', ref: 'master'
 
 # Evaluate Gemfile.local if it exists
 if File.exists? "#{__FILE__}.local"
index aa21c6b186c149f74ba1b112168d901e267c183c..b5066f0bc802bb2f5a52b5ba52dc00a7d72d40af 100644 (file)
@@ -1,12 +1,14 @@
-require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'puppet_x', 'apt_key', 'resource_api.rb'))
-
-require 'open-uri'
 require 'net/ftp'
+require 'open-uri'
+require 'puppet/resource_api'
 require 'tempfile'
 
-register_provider('apt_key2') do
-  commands apt_key: 'apt-key'
-  commands gpg: '/usr/bin/gpg'
+class Puppet::Provider::AptKey2::AptKey2
+
+  def initialize
+    @apt_key_cmd = Puppet::ResourceApi::Command.new 'apt-key'
+    @gpg_cmd = Puppet::ResourceApi::Command.new  '/usr/bin/gpg'
+  end
 
   def canonicalize(resources)
     resources.each do |r|
index eb671175c534fc6a2a86190164ca186b06876feb..9ad45389cae6d73eea8e8f0f8a2b7016473ec7c2 100644 (file)
@@ -1,6 +1,7 @@
-require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'puppet_x', 'apt_key', 'resource_api.rb'))
+require 'puppet/resource_api'
 
-register_type(name: 'apt_key2',
+Puppet::ResourceApi.register_type(
+  name: 'apt_key2',
   docs: <<-EOS,
       This type provides Puppet with the capabilities to manage GPG keys needed
       by apt to perform package validation. Apt has it's own GPG keyring that can
@@ -36,7 +37,7 @@ register_type(name: 'apt_key2',
     server:      {
       type:      'Pattern[/\A((hkp|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?$/]',
       docs:      'The key server to fetch the key from based on the ID. It can either be a domain name or url.',
-      behaviour: :read_only,
+      behaviour: :parameter,
       default:   :'keyserver.ubuntu.com',
     },
     options:     {
@@ -88,4 +89,6 @@ register_type(name: 'apt_key2',
   autorequires: {
     file:    '$source', # will evaluate to the value of the `source` attribute
     package: 'apt',
-  })
+  },
+  features: ['canonicalize'],
+)
diff --git a/lib/puppet_x/apt_key/resource_api.rb b/lib/puppet_x/apt_key/resource_api.rb
deleted file mode 100644 (file)
index 17fcc99..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-require 'pathname'
-
-module Puppet::SimpleResource
-  class TypeShim
-    attr_reader :values
-
-    def initialize(title, resource_hash)
-      # internalize and protect - needs to go deeper
-      @values        = resource_hash.dup
-      # "name" is a privileged key
-      @values[:name] = title
-      @values.freeze
-    end
-
-    def to_resource
-      ResourceShim.new(@values)
-    end
-
-    def name
-      values[:name]
-    end
-  end
-
-  class ResourceShim
-    attr_reader :values
-
-    def initialize(resource_hash)
-      @values = resource_hash.dup.freeze # whatevs
-    end
-
-    def title
-      values[:name]
-    end
-
-    def prune_parameters(*args)
-      # puts "not pruning #{args.inspect}" if args.length > 0
-      self
-    end
-
-    def to_manifest
-      (["apt_key { #{values[:name].inspect}: "] + values.keys.select { |k| k != :name }.collect { |k| "  #{k} => #{values[k].inspect}," } + ['}']).join("\n")
-    end
-  end
-end
-
-class Logger
-  def initialize(typename)
-    @typename = typename
-  end
-
-  def format_titles(titles)
-    "#{@typename}[#{[titles].flatten.compact.join(", ")}]"
-  end
-
-  def setup_context(titles, message = nil)
-    @context = format_titles(titles)
-    @context += ": #{message}: " if message
-  end
-
-  [:debug, :info, :notice, :warning, :err, :critical, :alert, :emerg].each do |method|
-    define_method(method) do |*args|
-      if args.length == 1
-        puts "#{method}: #{@context || @typename}: #{args.last}"
-      elsif args.length == 2
-        resources = format_titles(args.first)
-        puts "#{method}: #{resources}: #{args.last}"
-      else
-        puts "#{method}: #{args.map(&inspect).join(", ")}"
-      end
-    end
-  end
-
-  [:creating, :updating, :deleting, :failing].each do |method|
-    define_method(method) do |titles, message: method.to_s.capitalize, &block|
-      setup_context(titles, message)
-      begin
-        debug("Start")
-        yield
-        notice("Finished in x.yz seconds")
-      rescue
-        err("Failed after x.yz seconds")
-        raise
-      ensure
-        @context = nil
-      end
-    end
-  end
-
-  def processing(titles, is, should, message: 'Processing', &block)
-    setup_context(titles, message)
-    begin
-      debug("Changing #{is.inspect} to #{should.inspect}")
-      yield
-      notice("Changed from #{is.inspect} to #{should.inspect} in x.yz seconds")
-    rescue
-      err("Failed changing #{is.inspect} to #{should.inspect} after x.yz seconds")
-      raise
-    ensure
-      @context = nil
-    end
-  end
-
-  def attribute_changed(titles, is, should, message: nil)
-    setup_context(titles, message)
-    notice("Changed from #{is.inspect} to #{should.inspect}")
-  end
-end
-
-def register_type(definition)
-  Puppet::Type.newtype(definition[:name].to_sym) do
-    @docs = definition[:docs]
-    has_namevar = false
-    namevar_name = nil
-
-    def initialize(attributes)
-      $stderr.puts "A: #{attributes.inspect}"
-      attributes = attributes.to_hash if attributes.is_a? Puppet::Resource
-      $stderr.puts "B: #{attributes.inspect}"
-      attributes = self.class.canonicalize([attributes])[0]
-      $stderr.puts "C: #{attributes.inspect}"
-      super(attributes)
-    end
-
-    definition[:attributes].each do |name, options|
-      # puts "#{name}: #{options.inspect}"
-
-      # TODO: using newparam everywhere would suppress change reporting
-      #       that would allow more fine-grained reporting through logger,
-      #       but require more invest in hooking up the infrastructure to emulate existing data
-      param_or_property = if options[:behaviour] == :read_only || options[:behaviour] == :namevar
-                            :newparam
-                          else
-                            :newproperty
-                          end
-      send(param_or_property, name.to_sym) do
-        unless options[:type]
-          fail("#{definition[:name]}.#{name} has no type")
-        end
-
-        if options[:docs]
-          desc "#{options[:docs]} (a #{options[:type]}"
-        else
-          warn("#{definition[:name]}.#{name} has no docs")
-        end
-
-        if options[:behaviour] == :namevar
-          puts 'setting namevar'
-          isnamevar
-          has_namevar = true
-          namevar_name = name
-        end
-
-        # read-only values do not need type checking, but can have default values
-        if options[:behaviour] != :read_only
-          # TODO: this should use Pops infrastructure to avoid hardcoding stuff, and enhance type fidelity
-          # validate do |v|
-          #   type = Puppet::Pops::Types::TypeParser.singleton.parse(options[:type]).normalize
-          #   if type.instance?(v)
-          #     return true
-          #   else
-          #     inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value)
-          #     error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("#{DEFINITION[:name]}.#{name}", type, inferred_type)
-          #     raise Puppet::ResourceError, error_msg
-          #   end
-          # end
-
-          if options.has_key? :default
-            defaultto options[:default]
-          end
-
-          case options[:type]
-            when 'String'
-              # require any string value
-              newvalue // do
-              end
-            when 'Boolean'
-              ['true', 'false', :true, :false, true, false].each do |v|
-                newvalue v do
-                end
-              end
-
-              munge do |v|
-                case v
-                  when 'true', :true
-                    true
-                  when 'false', :false
-                    false
-                  else
-                    v
-                end
-              end
-            when 'Integer'
-              newvalue /^\d+$/ do
-              end
-              munge do |v|
-                Puppet::Pops::Utils.to_n(v)
-              end
-            when 'Float', 'Numeric'
-              newvalue Puppet::Pops::Patterns::NUMERIC do
-              end
-              munge do |v|
-                Puppet::Pops::Utils.to_n(v)
-              end
-            when 'Enum[present, absent]'
-              newvalue :absent do
-              end
-              newvalue :present do
-              end
-            when 'Variant[Pattern[/\A(0x)?[0-9a-fA-F]{8}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{16}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{40}\Z/]]'
-              # the namevar needs to be a Parameter, which only has newvalue*s*
-              newvalues(/\A(0x)?[0-9a-fA-F]{8}\Z/, /\A(0x)?[0-9a-fA-F]{16}\Z/, /\A(0x)?[0-9a-fA-F]{40}\Z/)
-            when 'Optional[String]'
-              newvalue :undef do
-              end
-              newvalue // do
-              end
-            when 'Variant[Stdlib::Absolutepath, Pattern[/\A(https?|ftp):\/\//]]'
-              # TODO: this is wrong, but matches original implementation
-              [/^\//, /\A(https?|ftp):\/\//].each do |v|
-                newvalue v do
-                end
-              end
-            when 'Pattern[/\A((hkp|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?$/]'
-              newvalues(/\A((hkp|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?$/)
-            when /^(Enum|Optional|Variant)/
-              fail("Datatype #{$1} is not yet supported in this prototype")
-            else
-              fail("Datatype #{options[:type]} is not yet supported in this prototype")
-          end
-        end
-      end
-    end
-
-    define_singleton_method(:instances) do
-      puts 'instances'
-      # klass = Puppet::Type.type(:api)
-      # force autoloading of the provider
-      autoloaded_provider = provider(name)
-      get.collect do |resource_hash|
-        Puppet::SimpleResource::TypeShim.new(resource_hash[namevar_name], resource_hash)
-      end
-    end
-
-    define_method(:retrieve) do
-      puts 'retrieve'
-      result        = Puppet::Resource.new(self.class, title)
-      current_state = self.class.get.find { |h| h[namevar_name] == title }
-
-      if current_state
-        current_state.each do |k, v|
-          result[k]=v
-        end
-      else
-        result[:ensure] = :absent
-      end
-
-      puts 'retrieve done'
-
-      @rapi_current_state = current_state
-      result
-    end
-
-    def flush
-      puts 'flush'
-      target_state = self.class.canonicalize([Hash[@parameters.collect { |k, v| [k, v.value] }]]).first
-      if @rapi_current_state != target_state
-        self.class.set({title => @rapi_current_state}, {title => target_state}, false)
-      else
-        puts 'no changes'
-      end
-    end
-
-    define_singleton_method(:logger) do
-      return Logger.new(definition[:name])
-    end
-
-    def self.commands(*args)
-      args.each do |command_group|
-        command_group.each do |command_name, command|
-          puts "registering command: #{command_name}, using #{command}"
-          define_singleton_method(command_name) do |*args|
-            puts "spawn([#{command.to_s}, #{command.to_s}], #{args.inspect})"
-            # TODO: capture output to debug stream
-            p = Process.spawn([command, command], *args)
-            Process.wait(p)
-            unless $?.exitstatus == 0
-              raise Puppet::ResourceError, "#{command} failed with exit code #{$?.exitstatus}"
-            end
-          end
-
-          define_singleton_method("#{command_name}_lines") do |*args|
-            puts "capture3([#{command.to_s}, #{command.to_s}], #{args.inspect})"
-            stdin_str, stderr_str, status = Open3.capture3([command, command], *args)
-            unless status.exitstatus == 0
-              raise Puppet::ResourceError, "#{command} failed with exit code #{$?.exitstatus}"
-            end
-            stdin_str.split("\n")
-          end
-        end
-      end
-    end
-  end
-end
-
-def register_provider(typename, &block)
-  type = Puppet::Type.type(typename.to_sym)
-  type.instance_eval &block
-  # require'pry';binding.pry
-end