From e52eca890ec87a8b59cd4954a100126de312721f Mon Sep 17 00:00:00 2001 From: Stephan Eicher Date: Wed, 13 Oct 2021 10:43:04 +0200 Subject: [PATCH] Add package provider for improved plugin handling #178 --- README.md | 18 ++++++ lib/puppet/provider/package/grafana.rb | 77 ++++++++++++++++++++++++++ spec/acceptance/grafana_plugin_spec.rb | 26 +++++++++ 3 files changed, 121 insertions(+) create mode 100644 lib/puppet/provider/package/grafana.rb diff --git a/README.md b/README.md index c93a9739..55cf5942 100644 --- a/README.md +++ b/README.md @@ -870,6 +870,24 @@ grafana_plugin { 'grafana-example-custom-plugin': } ``` +If you need to enforce a specific version of an plugin you can use the package provider. + +```puppet +package { 'grafana-image-renderer': + ensure => '2.0.0', + provider => 'grafana', +} +``` + +The package provider also enables the possibility to use `latest` which will update plugins if there is a newer version. + +```puppet +package { 'grafana-image-renderer': + ensure => 'latest', + provider => 'grafana', +} +``` + ##### `grafana_folder` Creates and manages Grafana folders via the API. diff --git a/lib/puppet/provider/package/grafana.rb b/lib/puppet/provider/package/grafana.rb new file mode 100644 index 00000000..d699ec1a --- /dev/null +++ b/lib/puppet/provider/package/grafana.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'puppet/provider/package' + +Puppet::Type.type(:package).provide :grafana, parent: Puppet::Provider::Package do + desc 'This provider only handles grafana plugins.' + + has_feature :installable, :install_options, :uninstallable, :upgradeable, :versionable + + has_command(:grafana_cli, 'grafana-cli') do + is_optional + end + + def self.pluginslist + plugins = {} + + grafana_cli('plugins', 'ls').split(%r{\n}).each do |line| + next unless line =~ %r{^(\S+)\s+@\s+((?:\d\.).+)\s*$} + + name = Regexp.last_match(1) + version = Regexp.last_match(2) + plugins[name] = version + end + + plugins + end + + def self.instances + pluginslist.map do |k, v| + new(name: k, ensure: v, provider: 'grafana') + end + end + + def query + plugins = self.class.pluginslist + + if plugins.key?(resource[:name]) + { ensure: plugins[resource[:name]], name: resource[:name] } + else + { ensure: :absent, name: resource[:name] } + end + end + + def latest + grafana_cli('plugins', 'list-versions', resource[:name]).lines.first.strip + end + + def update + plugins = self.class.pluginslist + + if plugins.key?(resource[:name]) + cmd = %w[plugins update] + cmd << install_options if resource[:install_options] + cmd << resource[:name] + grafana_cli(*cmd) + else + install + end + end + + def install + cmd = %w[plugins install] + cmd << install_options if resource[:install_options] + cmd << resource[:name] + cmd << resource[:ensure] unless resource[:ensure].is_a? Symbol + + grafana_cli(*cmd) + end + + def install_options + join_options(resource[:install_options]) + end + + def uninstall + grafana_cli('plugins', 'uninstall', resource[:name]) + end +end diff --git a/spec/acceptance/grafana_plugin_spec.rb b/spec/acceptance/grafana_plugin_spec.rb index 1a9ae12b..4116f895 100644 --- a/spec/acceptance/grafana_plugin_spec.rb +++ b/spec/acceptance/grafana_plugin_spec.rb @@ -95,5 +95,31 @@ class { 'grafana': end end end + + context 'grafana plugins' do + it 'installs' do + pp = <<-EOS + class { 'grafana': + version => 'latest', + } + + package { 'grafana-image-renderer': + provider => 'grafana', + } + EOS + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end + + describe package('grafana-image-renderer') do + it { is_expected.to be_installed } + end + + describe service('grafana-server') do + it { is_expected.to be_enabled } + it { is_expected.to be_running } + end + end end end