diff --git a/.rubocop.yml b/.rubocop.yml index 5984ccc..4adb7f0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,545 +1,549 @@ require: rubocop-rspec AllCops: TargetRubyVersion: 2.1 Include: - ./**/*.rb Exclude: - files/**/* - vendor/**/* - .vendor/**/* - pkg/**/* - spec/fixtures/**/* - Gemfile - Rakefile - Guardfile - Vagrantfile Lint/ConditionPosition: Enabled: True Lint/ElseLayout: Enabled: True Lint/UnreachableCode: Enabled: True Lint/UselessComparison: Enabled: True Lint/EnsureReturn: Enabled: True Lint/HandleExceptions: Enabled: True Lint/LiteralInCondition: Enabled: True Lint/ShadowingOuterLocalVariable: Enabled: True Lint/LiteralInInterpolation: Enabled: True Style/HashSyntax: Enabled: True Style/RedundantReturn: Enabled: True Layout/EndOfLine: Enabled: False Lint/AmbiguousOperator: Enabled: True Lint/AssignmentInCondition: Enabled: True Layout/SpaceBeforeComment: Enabled: True Style/AndOr: Enabled: True Style/RedundantSelf: Enabled: True Metrics/BlockLength: Enabled: False # Method length is not necessarily an indicator of code quality Metrics/MethodLength: Enabled: False # Module length is not necessarily an indicator of code quality Metrics/ModuleLength: Enabled: False Style/WhileUntilModifier: Enabled: True Lint/AmbiguousRegexpLiteral: Enabled: True Security/Eval: Enabled: True Lint/BlockAlignment: Enabled: True Lint/DefEndAlignment: Enabled: True Lint/EndAlignment: Enabled: True Lint/DeprecatedClassMethods: Enabled: True Lint/Loop: Enabled: True Lint/ParenthesesAsGroupedExpression: Enabled: True Lint/RescueException: Enabled: True Lint/StringConversionInInterpolation: Enabled: True Lint/UnusedBlockArgument: Enabled: True Lint/UnusedMethodArgument: Enabled: True Lint/UselessAccessModifier: Enabled: True Lint/UselessAssignment: Enabled: True Lint/Void: Enabled: True Layout/AccessModifierIndentation: Enabled: True Style/AccessorMethodName: Enabled: True Style/Alias: Enabled: True Layout/AlignArray: Enabled: True Layout/AlignHash: Enabled: True Layout/AlignParameters: Enabled: True Metrics/BlockNesting: Enabled: True Style/AsciiComments: Enabled: True Style/Attr: Enabled: True Style/BracesAroundHashParameters: Enabled: True Style/CaseEquality: Enabled: True Layout/CaseIndentation: Enabled: True Style/CharacterLiteral: Enabled: True Style/ClassAndModuleCamelCase: Enabled: True Style/ClassAndModuleChildren: Enabled: False Style/ClassCheck: Enabled: True # Class length is not necessarily an indicator of code quality Metrics/ClassLength: Enabled: False Style/ClassMethods: Enabled: True Style/ClassVars: Enabled: True Style/WhenThen: Enabled: True Style/WordArray: Enabled: True Style/UnneededPercentQ: Enabled: True Layout/Tab: Enabled: True Layout/SpaceBeforeSemicolon: Enabled: True Layout/TrailingBlankLines: Enabled: True Layout/SpaceInsideBlockBraces: Enabled: True Layout/SpaceInsideBrackets: Enabled: True Layout/SpaceInsideHashLiteralBraces: Enabled: True Layout/SpaceInsideParens: Enabled: True Layout/LeadingCommentSpace: Enabled: True Layout/SpaceBeforeFirstArg: Enabled: True Layout/SpaceAfterColon: Enabled: True Layout/SpaceAfterComma: Enabled: True Layout/SpaceAfterMethodName: Enabled: True Layout/SpaceAfterNot: Enabled: True Layout/SpaceAfterSemicolon: Enabled: True Layout/SpaceAroundEqualsInParameterDefault: Enabled: True Layout/SpaceAroundOperators: Enabled: True Layout/SpaceBeforeBlockBraces: Enabled: True Layout/SpaceBeforeComma: Enabled: True Style/CollectionMethods: Enabled: True Layout/CommentIndentation: Enabled: True Style/ColonMethodCall: Enabled: True Style/CommentAnnotation: Enabled: True # 'Complexity' is very relative Metrics/CyclomaticComplexity: Enabled: False Style/ConstantName: Enabled: True Style/Documentation: Enabled: False Style/DefWithParentheses: Enabled: True Style/PreferredHashMethods: Enabled: True Layout/DotPosition: EnforcedStyle: trailing Style/DoubleNegation: Enabled: True Style/EachWithObject: Enabled: True Layout/EmptyLineBetweenDefs: Enabled: True Layout/IndentArray: Enabled: True Layout/IndentHash: Enabled: True Layout/IndentationConsistency: Enabled: True Layout/IndentationWidth: Enabled: True Layout/EmptyLines: Enabled: True Layout/EmptyLinesAroundAccessModifier: Enabled: True Style/EmptyLiteral: Enabled: True # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: Enabled: False Style/MethodCallWithoutArgsParentheses: Enabled: True Style/MethodDefParentheses: Enabled: True Style/LineEndConcatenation: Enabled: True Layout/TrailingWhitespace: Enabled: True Style/StringLiterals: Enabled: True Style/TrailingCommaInArguments: Enabled: True Style/TrailingCommaInLiteral: Enabled: True Style/GlobalVars: Enabled: True Style/GuardClause: Enabled: True Style/IfUnlessModifier: Enabled: True Style/MultilineIfThen: Enabled: True Style/NegatedIf: Enabled: True Style/NegatedWhile: Enabled: True Style/Next: Enabled: True Style/SingleLineBlockParams: Enabled: True Style/SingleLineMethods: Enabled: True Style/SpecialGlobalVars: Enabled: True Style/TrivialAccessors: Enabled: True Style/UnlessElse: Enabled: True Style/VariableInterpolation: Enabled: True Style/VariableName: Enabled: True Style/WhileUntilDo: Enabled: True Style/EvenOdd: Enabled: True Style/FileName: Enabled: True Style/For: Enabled: True Style/Lambda: Enabled: True Style/MethodName: Enabled: True Style/MultilineTernaryOperator: Enabled: True Style/NestedTernaryOperator: Enabled: True Style/NilComparison: Enabled: True Style/FormatString: Enabled: True Style/MultilineBlockChain: Enabled: True Style/Semicolon: Enabled: True Style/SignalException: Enabled: True Style/NonNilCheck: Enabled: True Style/Not: Enabled: True Style/NumericLiterals: Enabled: True Style/OneLineConditional: Enabled: True Style/OpMethod: Enabled: True Style/ParenthesesAroundCondition: Enabled: True Style/PercentLiteralDelimiters: Enabled: True Style/PerlBackrefs: Enabled: True Style/PredicateName: Enabled: True Style/RedundantException: Enabled: True Style/SelfAssignment: Enabled: True Style/Proc: Enabled: True Style/RaiseArgs: Enabled: True Style/RedundantBegin: Enabled: True Style/RescueModifier: Enabled: True # based on https://github.com/voxpupuli/modulesync_config/issues/168 Style/RegexpLiteral: EnforcedStyle: percent_r Enabled: True Lint/UnderscorePrefixedVariableName: Enabled: True Metrics/ParameterLists: Enabled: False Lint/RequireParentheses: Enabled: True Style/ModuleFunction: Enabled: True Lint/Debugger: Enabled: True Style/IfWithSemicolon: Enabled: True Style/Encoding: Enabled: True Style/BlockDelimiters: Enabled: True Layout/MultilineBlockLayout: Enabled: True # 'Complexity' is very relative Metrics/AbcSize: Enabled: False # 'Complexity' is very relative Metrics/PerceivedComplexity: Enabled: False Lint/UselessAssignment: Enabled: True Layout/ClosingParenthesisIndentation: Enabled: True # RSpec RSpec/BeforeAfterAll: Exclude: - spec/acceptance/**/* # We don't use rspec in this way RSpec/DescribeClass: Enabled: False # Example length is not necessarily an indicator of code quality RSpec/ExampleLength: Enabled: False RSpec/NamedSubject: Enabled: False # disabled for now since they cause a lot of issues # these issues aren't easy to fix RSpec/RepeatedDescription: Enabled: False RSpec/NestedGroups: Enabled: False # this is broken on ruby1.9 Layout/IndentHeredoc: Enabled: False # disable Yaml safe_load. This is needed to support ruby2.0.0 development envs Security/YAMLLoad: Enabled: false # This affects hiera interpolation, as well as some configs that we push. Style/FormatStringToken: Enabled: false # This is useful, but sometimes a little too picky about where unit tests files # are located. RSpec/FilePath: Enabled: false + +# silence it to support older jruby (<= v1.9) which can not handle e.g. %i[] +Style/SymbolArray: + Enabled: false diff --git a/data/common.yaml b/data/common.yaml index a8516de..ccf7554 100644 --- a/data/common.yaml +++ b/data/common.yaml @@ -1,27 +1,29 @@ --- grafana::archive_source: ~ grafana::cfg_location: '/etc/grafana/grafana.ini' grafana::cfg: {} grafana::ldap_cfg: ~ grafana::container_cfg: false grafana::container_params: {} grafana::docker_image: 'grafana/grafana' grafana::docker_ports: '3000:3000' grafana::data_dir: '/var/lib/grafana' grafana::install_dir: '/usr/share/grafana' grafana::install_method: 'package' grafana::manage_package_repo: true grafana::package_name: 'grafana' grafana::package_source: ~ grafana::repo_name: 'stable' grafana::rpm_iteration: '1' grafana::service_name: 'grafana-server' grafana::version: 'installed' grafana::plugins: {} grafana::provisioning_dashboards: {} grafana::provisioning_datasources: {} grafana::provisioning_dashboards_file: '/etc/grafana/provisioning/dashboards/puppetprovisioned.yaml' grafana::provisioning_datasources_file: '/etc/grafana/provisioning/datasources/puppetprovisioned.yaml' grafana::create_subdirs_provisioning: false grafana::sysconfig_location: ~ grafana::sysconfig: ~ +grafana::ldap_servers: {} +grafana::ldap_group_mappings: {} diff --git a/lib/puppet/type/grafana_ldap_config.rb b/lib/puppet/type/grafana_ldap_config.rb new file mode 100644 index 0000000..a98b479 --- /dev/null +++ b/lib/puppet/type/grafana_ldap_config.rb @@ -0,0 +1,182 @@ +require 'toml' + +Puppet::Type.newtype(:grafana_ldap_config) do + @doc = 'Manage Grafana LDAP configuration' + @toml_header = <<-EOF +# +# Grafana LDAP configuration +# +# generated by Puppet module puppet-grafana +# https://github.com/voxpupuli/puppet-grafana +# +# *** Edit at your own peril *** +# +# ############################################# # +EOF + + # currently not ensurable as we are not parsing the LDAP toml config. + # ensurable + + newparam(:title, namevar: true) do + desc 'Path to ldap.toml' + + validate do |value| + raise ArgumentError, _('name/title must be a String') unless value.is_a?(String) + end + end + + newparam(:owner) do + desc 'Owner of the LDAP configuration-file either as String or Integer (default: root)' + defaultto 'root' + + validate do |value| + raise ArgumentError, _('owner must be a String or Integer') unless value.is_a?(String) || value.is_a?(Integer) + end + end + + newparam(:group) do + desc 'Group of the LDAP configuration file either as String or Integer (default: grafana)' + defaultto 'grafana' + + validate do |value| + raise ArgumentError, _('group must be a String or Integer') unless value.is_a?(String) || value.is_a?(Integer) + end + end + + newparam(:mode) do + desc 'File-permissions mode of the LDAP configuration file as String' + defaultto '0440' + + validate do |value| + # regex-pattern stolen from Puppetlabs here - all credis to them! + # https://github.com/puppetlabs/puppetlabs-stdlib/blob/master/types/filemode.pp + # currently disabled, as it fails when implicitly called. + # + # raise ArgumentError, _('file-permissions is not valid') unless value.to_s.match(%r{/\A(([0-7]{1,4})|(([ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+)(,([ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+))*))\z/}) + end + end + + newparam(:replace, boolean: true, parent: Puppet::Parameter::Boolean) do + desc 'Replace existing files' + defaultto true + end + + newparam(:backup, boolean: true, parent: Puppet::Parameter::Boolean) do + desc 'Backup existing files before replacing them into the file-bucket' + defaultto false + end + + newparam(:validate_cmd) do + desc 'A command to validate the new Grafana LDAP configuration before actually replacing it' + + validate do |value| + raise ArgumentError, _('group must be a String or undef') unless value.nil? || value.is_a?(String) + end + end + + def ldap_servers + catalog.resources.each_with_object({}) do |resource, memo| + next unless resource.is_a?(Puppet::Type.type(:grafana_ldap_server)) + next unless resource[:name].is_a?(String) + + memo[resource[:name]] = resource + memo + end + end + + def should_content + return @generated_config if @generated_config + + @generated_config = {} + + ldap_servers.each do |server_k, server_v| + # convert symbols to strings + server_params = Hash[server_v.original_parameters.map { |k, v| [k.to_s, v] }] + + server_attributes = server_params['attributes'] + server_params.delete('attributes') + + # grafana-syntax for multiple hosts is a space-separate list. + server_params['host'] = server_params['hosts'].join(' ') + server_params.delete('hosts') + + server_group_mappings = server_v.group_mappings + + server_block = { + 'servers' => [server_params], + 'servers.attributes' => server_attributes, + 'servers.group_mappings' => server_group_mappings + }.compact + + @generated_config[server_k] = server_block + end + + @generated_config.compact + end + + def generate + file_opts = {} + # currently not ensurable + # file_opts = { + # ensure: (self[:ensure] == :absent) ? :absent : :file, + # } + + [:name, + :owner, + :group, + :mode, + :replace, + :backup, + # this we have currently not implemented + # :selinux_ignore_defaults, + # :selrange, + # :selrole, + # :seltype, + # :seluser, + # :show_diff, + :validate_cmd].each do |param| + file_opts[param] = self[param] unless self[param].nil? + end + + metaparams = Puppet::Type.metaparams + excluded_metaparams = ['before', 'notify', 'require', 'subscribe', 'tag'] + + metaparams.reject! { |param| excluded_metaparams.include? param } + + metaparams.each do |metaparam| + file_opts[metaparam] = self[metaparam] unless self[metaparam].nil? + end + + [Puppet::Type.type(:file).new(file_opts)] + end + + def eval_generate + ldap_servers = should_content + + if !ldap_servers.nil? && !ldap_servers.empty? + + toml_contents = [] + toml_contents << @toml_header + + toml_contents << ldap_servers.map do |k, v| + str = [] + str << "\n\n" + str << <<-EOF +# +# #{k} +# +EOF + str << TOML::Generator.new(v).body + str.join + end + + catalog.resource("File[#{self[:name]}]")[:content] = toml_contents.join + end + + [catalog.resource("File[#{self[:name]}]")] + end + + autonotify(:class) do + 'grafana::service' + end +end diff --git a/lib/puppet/type/grafana_ldap_group_mapping.rb b/lib/puppet/type/grafana_ldap_group_mapping.rb new file mode 100644 index 0000000..7897d2f --- /dev/null +++ b/lib/puppet/type/grafana_ldap_group_mapping.rb @@ -0,0 +1,49 @@ +Puppet::Type.newtype(:grafana_ldap_group_mapping) do + @doc = 'Map an LDAP group to a Grafana role.' + + def initialize(*args) + @org_roles = %w[Admin Editor Viewer] + super + end + + validate do + raise(_('grafana_ldap_group_mapping: title needs to be a non-empty string')) if self[:name].nil? || self[:name].empty? + raise(_('grafana_ldap_group_mapping: ldap_server_name needs to be a non-empty string')) if self[:ldap_server_name].nil? || self[:ldap_server_name].empty? + raise(_('grafana_ldap_group_mapping: group_dn needs to be a non-empty string')) if self[:group_dn].nil? || self[:group_dn].empty? + raise(_("grafana_ldap_group_mapping: org_role needs to be a string of: #{@org_roles.join(', ')})")) if self[:org_role].nil? || self[:org_role].empty? + end + + newparam(:title, namevar: true) do + desc 'A unique identifier of the resource' + + validate do |value| + raise ArgumentError, _('name/title must be a String') unless value.is_a?(String) + end + end + + newparam(:ldap_server_name) do + desc 'The LDAP server config to apply the group-mappings on' + + validate do |value| + raise ArgumentError, _('ldap_server_name must be a String') unless value.is_a?(String) + end + end + + newparam(:group_dn) do + desc 'The LDAP distinguished-name of the group' + + validate do |value| + raise ArgumentError, _('group_dn must be a String') unless value.is_a?(String) + end + end + + newparam(:org_role) do + desc 'The Grafana role the shall be assigned to this group' + newvalues(:Admin, :Editor, :Viewer) + end + + newparam(:grafana_admin, boolean: true, parent: Puppet::Parameter::Boolean) do + desc 'Additonal flag for Grafana > v5.3 to signal admin-role to Grafana' + defaultto false + end +end diff --git a/lib/puppet/type/grafana_ldap_server.rb b/lib/puppet/type/grafana_ldap_server.rb new file mode 100644 index 0000000..679717e --- /dev/null +++ b/lib/puppet/type/grafana_ldap_server.rb @@ -0,0 +1,175 @@ +Puppet::Type.newtype(:grafana_ldap_server) do + @doc = 'Manage Grafana LDAP servers for LDAP authentication.' + + validate do + raise(_('grafana_ldap_server: name must not be empty')) if self[:name].nil? || self[:name].empty? + raise(_('grafana_ldap_server: hosts must not be empty')) if self[:hosts].nil? || self[:hosts].empty? + raise(_('grafana_ldap_server: port must not be empty')) if self[:port].nil? + + raise(_('grafana_ldap_server: root_ca_cert must be set when SSL/TLS is enabled')) \ + if !self[:ssl_skip_verify] && (self[:use_ssl] || self[:start_tls]) && self[:root_ca_cert].empty? + + raise(_('grafana_ldap_server: search_base_dns needs to contain at least one LDAP base-dn')) \ + if self[:search_base_dns].empty? + + raise(_('grafana_ldap_server: group_search_base_dns needs to contain at least one LDAP base-dn')) \ + if !self[:group_search_base_dns].nil? && self[:group_search_base_dns].empty? + end + + newparam(:title, namevar: true) do + desc 'A unique identified for this LDAP server.' + + validate do |value| + raise ArgumentError, _('name/title must be a String') unless value.is_a?(String) + end + end + + newparam(:hosts) do + desc 'The servers to perform LDAP authentication at' + + validate do |value| + raise ArgumentError, _('hosts must be an Array') unless value.is_a?(Array) + end + end + + newparam(:port) do + desc 'The port to connect at the LDAP servers (389 for TLS/plaintext, 636 for SSL [ldaps], optional)' + defaultto 389 + + validate do |value| + raise ArgumentError, _('port must be an Integer within the range 1-65535') unless value.is_a?(Integer) && value.between?(1, 65_535) # rubocop wants to have this weirdness + end + end + + newparam(:use_ssl, boolean: true, parent: Puppet::Parameter::Boolean) do + desc 'Set to true if you want to perform LDAP via a SSL-connection (not meant to be for TLS, optional)' + defaultto false + end + + newparam(:start_tls, boolean: true, parent: Puppet::Parameter::Boolean) do + desc 'Set to true if you want to perform LDAP via a TLS-connection (not meant to be for SSL, optional)' + defaultto true + end + + newparam(:ssl_skip_verify, boolean: true, parent: Puppet::Parameter::Boolean) do + desc "Set to true to disable verification of the LDAP server's SSL certificate (for TLS and SSL, optional)" + defaultto false + end + + newparam(:root_ca_cert) do + desc "The root ca-certificate to verify the LDAP server's SSL certificate against (for TLS and SSL, optional)" + defaultto '/etc/ssl/certs/ca-certificates.crt' + + validate do |value| + raise ArgumentError, _('root_ca_cert must be a String') unless value.is_a?(String) + end + end + + newparam(:client_cert) do + desc "If the LDAP server requires certificate-based authentication, specify the client's certificate (for TLS and SSL, optional)" + + validate do |value| + raise ArgumentError, _('client_cert must be a String') unless value.is_a?(String) + end + end + + newparam(:client_key) do + desc "If the LDAP server requires certificate-based authentication, specify the client's certificate (for TLS and SSL, optional)" + + validate do |value| + raise ArgumentError, _('client_key must be a String') unless value.is_a?(String) + end + end + + newparam(:bind_dn) do + desc 'If the LDAP server requires authentication (i.e. non-anonymous), provide the distinguished-name (dn) here (optional)' + + validate do |value| + raise ArgumentError, _('bind_dn must be a String') unless value.is_a?(String) + end + end + + newparam(:bind_password) do + desc 'If the LDAP server requires authentication (i.e. non-anonymous), provide the password (optional)' + + validate do |value| + raise ArgumentError, _('bind_password must be a String') unless value.is_a?(String) + end + end + + newparam(:search_filter) do + desc 'A search-filter to be used when querying LDAP for user-accounts (optional)' + + validate do |value| + raise ArgumentError, _('search_filter must be a String') unless value.is_a?(String) + end + end + + newparam(:search_base_dns) do + desc 'The one or more base-dn to be used when querying LDAP for user-accounts (optional)' + defaultto [] + + validate do |value| + raise ArgumentError, _('search_base_dns must be an Array') unless value.is_a?(Array) + + value.each { |base_dn| raise ArgumentError, _('search_base_dns elements must be a String') unless base_dn.is_a?(String) } + end + end + + newparam(:group_search_filter) do + desc 'A search-filter to be used when querying LDAP for group-accounts (optional)' + + validate do |value| + raise ArgumentError, _('group_search_filter must be a String') unless value.is_a?(String) + end + end + + newparam(:group_search_filter_user_attribute) do + desc 'The attribute to be used to locate matching user-accounts in the group (optional)' + + validate do |value| + raise ArgumentError, _('group_search_filter_user_attribute must be a String') unless value.is_a?(String) + end + end + + newparam(:group_search_base_dns) do + desc 'The base-dn to be used when querying LDAP for group-accounts (optional)' + + validate do |value| + raise ArgumentError, _('search_base_dns must be an Array') unless value.is_a?(Array) + + value.each { |base_dn| raise ArgumentError, _('search_base_dns elements must be a String') unless base_dn.is_a?(String) } + end + end + + newparam(:attributes) do + desc 'Mapping LDAP attributes to their Grafana user-account-properties (optional)' + + validate do |value| + valid_attributes = %w[name surname username member_of email] + + raise ArgumentError, _('attributes must be a Hash') unless value.is_a?(Hash) + + value.each { |k, v| raise ArgumentError, _('attributes hash keys and values must be Strings') unless k.is_a?(String) && v.is_a?(String) } + + raise ArgumentError, _("attributes contains an unknown key, allowed: #{valid_attributes.join(', ')}") if value.keys.reject { |key| valid_attributes.include?(key) }.count > 0 + end + end + + def set_sensitive_parameters(sensitive_parameters) # rubocop:disable Style/AccessorMethodName + parameter(:bind_password).sensitive = true if parameter(:bind_password) + super(sensitive_parameters) + end + + def group_mappings + catalog.resources.map do |resource| + next unless resource.is_a?(Puppet::Type.type(:grafana_ldap_group_mapping)) + next unless resource[:ldap_server_name] == self[:name] + + group_mapping = Hash[resource.original_parameters.map { |k, v| [k.to_s, v] }] + group_mapping.delete('ldap_server_name') + + group_mapping + end.compact + end +end diff --git a/manifests/init.pp b/manifests/init.pp index 9d19154..9b0957d 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,150 +1,163 @@ # == Class: grafana # # Installs and configures Grafana. # # === Parameters # [*archive_source*] # Download location of tarball to be used with the 'archive' install method. # Defaults to the URL of the latest version of Grafana available at the time of module release. # # [*container_cfg*] # Boolean. Determines whether a configuration file should be generated when using the 'docker' install method. # If true, use the `cfg` and `cfg_location` parameters to control creation of the file. # Defaults to false. # # [*container_params*] # Hash of parameters to use when creating the Docker container. For use with the 'docker' install method. # Refer to documentation of the `docker::run` resource in the `garethr-docker` module for details of available parameters. # Defaults to: # # container_params => { # 'image' => 'grafana/grafana:latest', # 'ports' => '3000' # } # # [*data_dir*] # The directory Grafana will use for storing its data. # Defaults to '/var/lib/grafana'. # # [*install_dir*] # Installation directory to be used with the 'archive' install method. # Defaults to '/usr/share/grafana'. # # [*install_method*] # Set to 'archive' to install Grafana using the tar archive. # Set to 'docker' to install Grafana using the official Docker container. # Set to 'package' to install Grafana using .deb or .rpm packages. # Set to 'repo' to install Grafana using an apt or yum repository. # Defaults to 'package'. # # [*manage_package_repo*] # If true this will setup the official grafana repositories on your host. Defaults to true. # # [*package_name*] # The name of the package managed with the 'package' install method. # Defaults to 'grafana'. # # [*package_source*] # Download location of package to be used with the 'package' install method. # Defaults to the URL of the latest version of Grafana available at the time of module release. # # [*service_name*] # The name of the service managed with the 'archive' and 'package' install methods. # Defaults to 'grafana-server'. # # [*version*] # The version of Grafana to install and manage. # Defaults to 'installed' # # [*repo_name*] # When using 'repo' install_method, the repo to look for packages in. # Set to 'stable' to install only stable versions # Set to 'beta' to install beta versions # Defaults to stable. # # [*plugins*] # A hash of plugins to be passed to `create_resources`, wraps around the # `grafana_plugin` resource. # # [*provisioning_dashboards*] # Hash of dashboards to provision into grafana. grafana > v5.0.0 # required. Hash will be converted into YAML and used by grafana to # provision dashboards. # # [*provisioning_datasources*] # Hash of datasources to provision into grafana, grafana > v5.0.0 # required. Hash will be converted into YAML and used by granfana to # configure datasources. # # [*provisioning_dashboards_file*] # String with the fully qualified path to place the provisioning file # for dashboards, only used if provisioning_dashboards is specified. # Defaults to '/etc/grafana/provisioning/dashboards/puppetprovisioned.yaml' # # [*provisioning_datasources_file*] # String with the fully qualified path to place the provisioning file # for datasources, only used if provisioning_datasources is specified. # Default to '/etc/grafana/provisioning/datasources/puppetprovisioned.yaml' # # [*create_subdirs_provisioning*] # Boolean, defaults to false. If true puppet will create any # subdirectories in the given path when provisioning dashboards. # # [*sysconfig_location*] # Location of the sysconfig file for the environment of the grafana-server service. # This is only used when the install_method is 'package' or 'repo'. # # [*sysconfig*] # A hash of environment variables for the grafana-server service # +# [*ldap_servers*] +# A hash of ldap_servers to be passed to `create_resources`, wraps around the +# `grafana_ldap_server` resource. +# +# [*ldap_group_mappings*] +# A hash of ldap_servers to be passed to `create_resources`, wraps around the +# `grafana_ldap_group_mapping` resource. +# # Example: # sysconfig => { 'http_proxy' => 'http://proxy.example.com/' } # # === Examples # # class { '::grafana': # install_method => 'docker', # } # class grafana ( Optional[String] $archive_source, String $cfg_location, Hash $cfg, Optional[Variant[Hash,Array]] $ldap_cfg, Boolean $container_cfg, Hash $container_params, String $docker_image, String $docker_ports, String $data_dir, String $install_dir, String $install_method, Boolean $manage_package_repo, String $package_name, Optional[String] $package_source, Enum['stable', 'beta'] $repo_name, String $rpm_iteration, String $service_name, String $version, Hash $plugins, Hash $provisioning_dashboards, Hash $provisioning_datasources, String $provisioning_dashboards_file, String $provisioning_datasources_file, Boolean $create_subdirs_provisioning, Optional[String] $sysconfig_location, Optional[Hash] $sysconfig, + Hash[String[1], Hash] $ldap_servers, + Hash[String[1], Hash] $ldap_group_mappings, ) { contain grafana::install contain grafana::config contain grafana::service Class['grafana::install'] -> Class['grafana::config'] -> Class['grafana::service'] create_resources(grafana_plugin, $plugins) # Dependency added for Grafana_plugins to ensure it runs at the # correct time. Class['grafana::config'] -> Grafana_Plugin <| |> ~> Class['grafana::service'] + + create_resources('grafana_ldap_server', $ldap_servers) + create_resources('grafana_ldap_group_mapping', $ldap_group_mappings) }