From 8497b8976263c2a20fc8e364da915c4489547b23 Mon Sep 17 00:00:00 2001 From: "Haneysmith, Nathan" Date: Thu, 23 Apr 2015 13:11:01 -0700 Subject: [PATCH] all the things --- .kitchen.yml | 39 ++ .rspec | 2 + .rubocop.yml | 24 ++ .template_version | 2 + Berksfile | 10 + CHANGELOG.md | 21 ++ Gemfile | 48 +++ Gemfile.lock | 336 ++++++++++++++++++ Guardfile | 59 +++ README.md | 10 +- Rakefile | 71 ++++ attributes/default.rb | 25 ++ chefignore | 101 ++++++ metadata.rb | 15 + recipes/config.rb | 7 + recipes/default.rb | 10 + recipes/install.rb | 53 +++ recipes/service.rb | 3 + spec/recipes/default_spec.rb | 7 + spec/spec_helper.rb | 92 +++++ templates/default/grafana.ini.erb | 198 +++++++++++ .../serverspec/cookbook/default_spec.rb | 16 + .../default/serverspec/spec_helper.rb | 7 + 23 files changed, 1154 insertions(+), 2 deletions(-) create mode 100644 .kitchen.yml create mode 100644 .rspec create mode 100644 .rubocop.yml create mode 100644 .template_version create mode 100644 Berksfile create mode 100644 CHANGELOG.md create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Guardfile create mode 100644 Rakefile create mode 100644 attributes/default.rb create mode 100644 chefignore create mode 100644 metadata.rb create mode 100644 recipes/config.rb create mode 100644 recipes/default.rb create mode 100644 recipes/install.rb create mode 100644 recipes/service.rb create mode 100644 spec/recipes/default_spec.rb create mode 100644 spec/spec_helper.rb create mode 100644 templates/default/grafana.ini.erb create mode 100644 test/integration/default/serverspec/cookbook/default_spec.rb create mode 100644 test/integration/default/serverspec/spec_helper.rb diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 0000000..bba13cf --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,39 @@ +<% proxy_vars = {} %> +<% %w(http_proxy https_proxy no_proxy).each do |envvar| %> +<% if ENV.key?(envvar) %> +<% proxy_vars[envvar] = ENV[envvar] %> +<% end %> +<% end %> +--- +driver: + name: vagrant + network: + - ["forwarded_port", { guest: 3000, host: 3000 }] + - ["private_network", {ip: "192.168.33.33" }] + +<% if proxy_vars.size > 0 %> +driver_config: +<% %w(http_proxy https_proxy no_proxy).each do |envvar| %> +<% if ENV.key?(envvar) %> + <%= envvar %>: '<%= ENV[envvar] %>' +<% end %> +<% end %> + +<% end %> + +provisioner: + name: chef_zero + client_rb: +<% %w(http_proxy https_proxy no_proxy).each do |envvar| %> +<% if ENV.key?(envvar) %> + <%= envvar %>: '<%= ENV[envvar] %>' +<% end %> +<% end %> + +platforms: + - name: opscode-centos-6.5 + +suites: + - name: default + run_list: + - recipe[grafana2::default] diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..83e16f8 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..c8dc3bb --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,24 @@ +AllCops: + Exclude: + - 'vendor/**/*' + +Style/SingleSpaceBeforeFirstArg: + Exclude: + - '**/Berksfile' + - '**/metadata.rb' + +Style/FileName: + Exclude: + - '**/Gemfile' + - '**/Berksfile' + +Metrics/LineLength: + Max: 150 + +Style/RegexpLiteral: + Exclude: + - '**/Guardfile' + +Style/AlignParameters: + Exclude: + - '**/Gemfile' diff --git a/.template_version b/.template_version new file mode 100644 index 0000000..19c9b36 --- /dev/null +++ b/.template_version @@ -0,0 +1,2 @@ +--- +template_version: 0.16.2 diff --git a/Berksfile b/Berksfile new file mode 100644 index 0000000..a137702 --- /dev/null +++ b/Berksfile @@ -0,0 +1,10 @@ +source 'https://supermarket.chef.io' + +metadata + +# load local overrides +berksfile_dir = File.absolute_path(File.join('.', 'lib', 'berksfile')) +Dir.glob(File.join(berksfile_dir, '*.berks')).each do |snippet| + # rubocop:disable Lint/Eval + eval File.read(snippet), nil, snippet +end diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d47345d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,21 @@ +# Revision History for grafana2 + +## 0.1.4 +- Nathan Haneysmith +- Go ahead and keep grafana package updated + +## 0.1.3 +- Nathan Haneysmith +- No more defaults.ini, just grafana.ini + +## 0.1.2 +- Nathan Haneysmith +- Sessions in MySQL + +## 0.1.1 +- Nathan Haneysmith +- Adding in templates for config + +## 0.1.0 +- Nathan Haneysmith +- Initial commit, pkg install and service definition diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..b97f810 --- /dev/null +++ b/Gemfile @@ -0,0 +1,48 @@ +source 'https://rubygems.org' + +group :development do + gem 'rake', '~> 10.3' + gem 'pry' + gem 'pry-byebug' + gem 'pry-rescue', '~> 1.3' + gem 'pry-stack_explorer', '~> 0.4' +end + +group :test do + gem 'foodcritic', '~> 4.0' + gem 'chefspec', '~> 4.1' + gem 'ci_reporter_rspec', '~> 1.0' + gem 'test-kitchen', '~> 1.2' + gem 'kitchen-vagrant', '~> 0.15' + # log_switch v1.0.0 breaks tailor v1.4.0 but tailor + # does a >= pin; we add a ~> pin for now to keep us + # on the 0.4.x release + gem 'log_switch', '~> 0.4' + gem 'tailor', '~> 1.4' + # use our forked version until + # https://github.com/berkshelf/berkshelf/pull/1393 has been accepted + gem 'berkshelf', '~> 3.2', + git: 'https://github.com/Nordstrom/berkshelf.git', + branch: 'use_httpclient_instead_of_nethttp' + # use our forked version until + # https://github.com/berkshelf/berkshelf-api-client/pull/5 has been accepted + gem 'berkshelf-api-client', '~> 1.2', + git: 'https://github.com/Nordstrom/berkshelf-api-client.git', + branch: 'use_httpclient_instead_of_nethttp' + # pin to 2.8 series until guard-foodcritic has been updated for v2 API + gem 'guard', '~> 2.8.2' + # pin to 4.3 series until guard-foodcritic has been updated for v2 API + gem 'guard-rspec', '~> 4.3.1' + gem 'guard-foodcritic', '~> 1.0' + gem 'guard-rake', '~> 0.0' + gem 'rubocop', '~> 0.28.0' + gem 'guard-rubocop', '~> 1.1' + gem 'ruby_gntp', '~> 0.3' +end + +# load local overrides +gemfile_dir = File.absolute_path(File.join('.', 'lib', 'gemfile')) +Dir.glob(File.join(gemfile_dir, '*.bundler')).each do |snippet| + # rubocop:disable Lint/Eval + eval File.read(snippet), nil, snippet +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..46e71ca --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,336 @@ +GIT + remote: https://github.com/Nordstrom/berkshelf-api-client.git + revision: d6dd7aa7027028dfe9ddca7375d568e978bcd7ad + branch: use_httpclient_instead_of_nethttp + specs: + berkshelf-api-client (1.2.1) + faraday (~> 0.9.0) + httpclient (~> 2.6.0) + +GIT + remote: https://github.com/Nordstrom/berkshelf.git + revision: 07888a69fd20e7714123346d4ec7c19320fb59ea + branch: use_httpclient_instead_of_nethttp + specs: + berkshelf (3.2.3) + addressable (~> 2.3.4) + berkshelf-api-client (~> 1.2) + buff-config (~> 1.0) + buff-extensions (~> 1.0) + buff-shell_out (~> 0.1) + celluloid (~> 0.16.0) + celluloid-io (~> 0.16.1) + cleanroom (~> 1.0) + faraday (~> 0.9.0) + httpclient (~> 2.6.0) + minitar (~> 0.5.4) + octokit (~> 3.0) + retryable (~> 2.0) + ridley (~> 4.0) + solve (~> 1.1) + thor (~> 0.19) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.3.8) + ast (2.0.0) + astrolabe (1.3.0) + parser (>= 2.2.0.pre.3, < 3.0) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + buff-config (1.0.1) + buff-extensions (~> 1.0) + varia_model (~> 0.4) + buff-extensions (1.0.0) + buff-ignore (1.1.1) + buff-ruby_engine (0.1.0) + buff-shell_out (0.2.0) + buff-ruby_engine (~> 0.1.0) + builder (3.2.2) + byebug (4.0.5) + columnize (= 0.9.0) + celluloid (0.16.0) + timers (~> 4.0.0) + celluloid-io (0.16.2) + celluloid (>= 0.16.0) + nio4r (>= 1.1.0) + chef (12.2.1) + chef-zero (~> 4.0) + diff-lcs (~> 1.2, >= 1.2.4) + erubis (~> 2.7) + ffi-yajl (>= 1.2, < 3.0) + highline (~> 1.6, >= 1.6.9) + mixlib-authentication (~> 1.3) + mixlib-cli (~> 1.4) + mixlib-config (~> 2.0) + mixlib-log (~> 1.3) + mixlib-shellout (>= 2.0.0.rc.0, < 3.0) + net-ssh (~> 2.6) + net-ssh-multi (~> 1.1) + ohai (~> 8.0) + plist (~> 3.1.0) + pry (~> 0.9) + rspec-core (~> 3.2) + rspec-expectations (~> 3.2) + rspec-mocks (~> 3.2) + rspec_junit_formatter (~> 0.2.0) + serverspec (~> 2.7) + specinfra (~> 2.10) + chef-zero (4.2.1) + ffi-yajl (>= 1.1, < 3.0) + hashie (~> 2.0) + mixlib-log (~> 1.3) + rack + uuidtools (~> 2.1) + chefspec (4.2.0) + chef (>= 11.14) + fauxhai (~> 2.0) + rspec (~> 3.0) + ci_reporter (2.0.0) + builder (>= 2.1.2) + ci_reporter_rspec (1.0.0) + ci_reporter (~> 2.0) + rspec (>= 2.14, < 4) + cleanroom (1.0.0) + coderay (1.1.0) + columnize (0.9.0) + debug_inspector (0.0.2) + dep-selector-libgecode (1.0.2) + dep_selector (1.0.3) + dep-selector-libgecode (~> 1.0) + ffi (~> 1.9) + diff-lcs (1.2.5) + erubis (2.7.0) + faraday (0.9.1) + multipart-post (>= 1.2, < 3) + fauxhai (2.3.0) + net-ssh + ohai + ffi (1.9.8) + ffi-yajl (2.1.0) + libyajl2 (~> 1.2) + foodcritic (4.0.0) + erubis + gherkin (~> 2.11) + nokogiri (~> 1.5) + rake + rufus-lru (~> 1.0) + treetop (~> 1.4) + yajl-ruby (~> 1.1) + formatador (0.2.5) + gherkin (2.12.2) + multi_json (~> 1.3) + guard (2.8.2) + formatador (>= 0.2.4) + listen (~> 2.7) + lumberjack (~> 1.0) + pry (>= 0.9.12) + thor (>= 0.18.1) + guard-foodcritic (1.0.3) + foodcritic (>= 1.3, < 5.0) + guard (>= 1.0, < 3.0) + guard-rake (0.0.10) + guard + rake + guard-rspec (4.3.1) + guard (~> 2.1) + rspec (>= 2.14, < 4.0) + guard-rubocop (1.2.0) + guard (~> 2.0) + rubocop (~> 0.20) + hashie (2.1.2) + highline (1.7.2) + hitimes (1.2.2) + httpclient (2.6.0.1) + interception (0.5) + ipaddress (0.8.0) + json (1.8.2) + kitchen-vagrant (0.16.0) + test-kitchen (~> 1.0) + libyajl2 (1.2.0) + listen (2.10.0) + celluloid (~> 0.16.0) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + log_switch (0.4.0) + lumberjack (1.0.9) + method_source (0.8.2) + mime-types (2.4.3) + mini_portile (0.6.2) + minitar (0.5.4) + mixlib-authentication (1.3.0) + mixlib-log + mixlib-cli (1.5.0) + mixlib-config (2.1.0) + mixlib-log (1.6.0) + mixlib-shellout (2.0.1) + multi_json (1.11.0) + multipart-post (2.0.0) + net-http-persistent (2.9.4) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-ssh (2.9.2) + net-ssh-gateway (1.2.0) + net-ssh (>= 2.6.5) + net-ssh-multi (1.2.1) + net-ssh (>= 2.6.5) + net-ssh-gateway (>= 1.2.0) + nio4r (1.1.0) + nokogiri (1.6.6.2) + mini_portile (~> 0.6.0) + octokit (3.8.0) + sawyer (~> 0.6.0, >= 0.5.3) + ohai (8.2.0) + ffi (~> 1.9) + ffi-yajl (>= 1.1, < 3.0) + ipaddress + mime-types (~> 2.0) + mixlib-cli + mixlib-config (~> 2.0) + mixlib-log + mixlib-shellout (~> 2.0) + rake (~> 10.1) + systemu (~> 2.6.4) + wmi-lite (~> 1.0) + parser (2.2.2.1) + ast (>= 1.1, < 3.0) + plist (3.1.0) + polyglot (0.3.5) + powerpack (0.0.9) + pry (0.10.1) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-byebug (3.1.0) + byebug (~> 4.0) + pry (~> 0.10) + pry-rescue (1.4.1) + interception (>= 0.5) + pry + pry-stack_explorer (0.4.9.2) + binding_of_caller (>= 0.7) + pry (>= 0.9.11) + rack (1.6.0) + rainbow (2.0.0) + rake (10.4.2) + rb-fsevent (0.9.4) + rb-inotify (0.9.5) + ffi (>= 0.5.0) + retryable (2.0.1) + ridley (4.1.2) + addressable + buff-config (~> 1.0) + buff-extensions (~> 1.0) + buff-ignore (~> 1.1) + buff-shell_out (~> 0.1) + celluloid (~> 0.16.0) + celluloid-io (~> 0.16.1) + erubis + faraday (~> 0.9.0) + hashie (>= 2.0.2, < 3.0.0) + json (>= 1.7.7) + mixlib-authentication (>= 1.3.0) + net-http-persistent (>= 2.8) + retryable (>= 2.0.0) + semverse (~> 1.1) + varia_model (~> 0.4) + rspec (3.2.0) + rspec-core (~> 3.2.0) + rspec-expectations (~> 3.2.0) + rspec-mocks (~> 3.2.0) + rspec-core (3.2.3) + rspec-support (~> 3.2.0) + rspec-expectations (3.2.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.2.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.2.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.2.0) + rspec-support (3.2.2) + rspec_junit_formatter (0.2.0) + builder (< 4) + rspec (>= 2, < 4) + rspec-core (!= 2.12.0) + rubocop (0.28.0) + astrolabe (~> 1.3) + parser (>= 2.2.0.pre.7, < 3.0) + powerpack (~> 0.0.6) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.4) + ruby-progressbar (1.7.5) + ruby_gntp (0.3.4) + rufus-lru (1.0.5) + safe_yaml (1.0.4) + sawyer (0.6.0) + addressable (~> 2.3.5) + faraday (~> 0.8, < 0.10) + semverse (1.2.1) + serverspec (2.14.1) + multi_json + rspec (~> 3.0) + rspec-its + specinfra (~> 2.25) + slop (3.6.0) + solve (1.2.1) + dep_selector (~> 1.0) + semverse (~> 1.1) + specinfra (2.30.0) + net-scp + net-ssh + systemu (2.6.5) + tailor (1.4.0) + log_switch (>= 0.3.0) + nokogiri (>= 1.6.0) + term-ansicolor (>= 1.0.5) + text-table (>= 1.2.2) + term-ansicolor (1.3.0) + tins (~> 1.0) + test-kitchen (1.3.1) + mixlib-shellout (>= 1.2, < 3.0) + net-scp (~> 1.1) + net-ssh (~> 2.7) + safe_yaml (~> 1.0) + thor (~> 0.18) + text-table (1.2.4) + thor (0.19.1) + timers (4.0.1) + hitimes + tins (1.4.2) + treetop (1.6.2) + polyglot (~> 0.3) + uuidtools (2.1.5) + varia_model (0.4.0) + buff-extensions (~> 1.0) + hashie (>= 2.0.2, < 3.0.0) + wmi-lite (1.0.0) + yajl-ruby (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + berkshelf (~> 3.2)! + berkshelf-api-client (~> 1.2)! + chefspec (~> 4.1) + ci_reporter_rspec (~> 1.0) + foodcritic (~> 4.0) + guard (~> 2.8.2) + guard-foodcritic (~> 1.0) + guard-rake (~> 0.0) + guard-rspec (~> 4.3.1) + guard-rubocop (~> 1.1) + kitchen-vagrant (~> 0.15) + log_switch (~> 0.4) + pry + pry-byebug + pry-rescue (~> 1.3) + pry-stack_explorer (~> 0.4) + rake (~> 10.3) + rubocop (~> 0.28.0) + ruby_gntp (~> 0.3) + tailor (~> 1.4) + test-kitchen (~> 1.2) diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..51ff9fe --- /dev/null +++ b/Guardfile @@ -0,0 +1,59 @@ +notification :terminal_title + +# prevent dropping into pry when nothing is happening +interactor :off + +# automatically runs Foodcritic +guard :foodcritic, cookbook_paths: '.', cli: '-f any -X spec -X test -X features' do + watch(%r{^attributes/.+\.rb$}) + watch(%r{^resources/.+\.rb$}) + watch(%r{^providers/.+\.rb$}) + watch(%r{^libraries/.+\.rb$}) + watch(%r{^recipes/.+\.rb$}) + watch(%r{^metadata\.rb$}) +end + +# automatically runs Tailor +guard :rake, all_on_start: true, task: :tailor do + watch(%r{^spec/recipes/.+_spec\.rb$}) + watch(%r{^spec/spec_helper\.rb$}) + watch(%r{^attributes/.+\.rb$}) + watch(%r{^resources/.+\.rb$}) + watch(%r{^providers/.+\.rb$}) + watch(%r{^libraries/.+\.rb$}) + watch(%r{^recipes/.+\.rb$}) + watch(%r{^metadata\.rb$}) +end + +# automatically runs Rubocop +guard :rubocop, all_on_start: true, cli: ['-f', 'p', '-D'] do + watch(%r{^attributes/.+\.rb$}) + watch(%r{^recipes/.+\.rb$}) + watch(%r{^libraries/.+\.rb$}) + watch(%r{^resources/.+\.rb$}) + watch(%r{^providers/.+\.rb$}) + watch(%r{^spec/.+\.rb$}) + watch(%r{^test/.+\.rb$}) + watch(%r{^metadata\.rb$}) + watch(%r{^Berksfile$}) + watch(%r{^Gemfile$}) + watch(%r{^Rakefile$}) +end + +# automatically runs ChefSpec tests +rspec_command = ENV.key?('DISABLE_PRY_RESCUE') ? 'rspec' : 'rescue rspec' +guard :rspec, all_on_start: true, cmd: "bundle exec #{rspec_command}" do + watch(%r{^spec/recipes/.+_spec\.rb$}) + watch(%r{^spec/spec_helper\.rb$}) { 'spec' } + watch(%r{^attributes/.+\.rb$}) { 'spec' } + watch(%r{^resources/.+\.rb$}) { 'spec' } + watch(%r{^providers/.+\.rb$}) { 'spec' } + watch(%r{^libraries/.+\.rb$}) { 'spec' } + watch(%r{^recipes/(.+)\.rb$}) { |m| "spec/recipes/#{m[1]}_spec.rb" } +end + +# load local overrides +guardfile_dir = File.absolute_path(File.join('.', 'lib', 'guardfile')) +Dir.glob(File.join(guardfile_dir, '*.guard')).each do |snippet| + eval File.read(snippet), nil, snippet # rubocop:disable Lint/Eval +end diff --git a/README.md b/README.md index 244737d..f4b7d32 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # grafana2 ## Description +Right now, this is only tested on CentOS in AWS. We used RDS/MySQL for +data and sessions. Will add options for other setups soon. + Manually create a MySQL RDS instance and update attributes/default.rb Manually create the sessions table in mysql: yum install mysql @@ -17,6 +20,8 @@ CREATE TABLE `session` ( ## Usage +You must change the attributes for domain and database host, user, password. + Add 'recipe[grafana2::default]' to your node's run-list. To use this cookbook in another recipe, add a dependency on it to your @@ -36,7 +41,7 @@ will have to change this to '~> 1.0' as appropriate.) ### default -The default recipe ... +The default recipe will call install, config, and service definitions. ## Attributes @@ -45,7 +50,8 @@ The attributes defined by this recipe are organized under the Attribute | Description | Type | Default ----------|-------------|--------|-------- -... | ... | String | ... +domain | Used in setting root URL | String | +db_host | IP or hostname for database | String | ## LWRP diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..e780994 --- /dev/null +++ b/Rakefile @@ -0,0 +1,71 @@ +require 'foodcritic' +require 'foodcritic/rake_task' +require 'tailor/rake_task' +require 'rspec/core/rake_task' +require 'rubocop/rake_task' +require 'kitchen/rake_tasks' + +# Style tests (Foodcritic / Tailor) +FoodCritic::Rake::LintTask.new +Tailor::RakeTask.new do |t| + { + spec: 'spec/recipes/*_spec.rb', + spec_helper: 'spec/spec_helper.rb', + attributes: 'attributes/*.rb', + resources: 'resources/*.rb', + providers: 'providers/*.rb', + libraries: 'libraries/**/*.rb', + recipes: 'recipes/*.rb', + metadata: 'metadata.rb' + }.each do |name, glob| + t.file_set glob, name do |s| + s.max_line_length 1000 + s.max_code_lines_in_method 1000 + s.max_code_lines_in_class 1000 + end + end +end + +RuboCop::RakeTask.new do |t| + t.formatters = ['progress'] + t.options = ['-D'] + t.patterns = %w( + attributes/*.rb + recipes/*.rb + libraries/**/*.rb + resources/*.rb + providers/*.rb + spec/**/*.rb + test/**/*.rb + ./metadata.rb + ./Berksfile + ./Gemfile + ./Rakefile + ) +end + +desc 'Run Style Tests' +task style: [:foodcritic, :tailor, :rubocop] + +# ChefSpec (RSpec) +RSpec::Core::RakeTask.new + +desc 'Generate ChefSpec coverage report' +task :coverage do + ENV['COVERAGE'] = 'true' + Rake::Task[:spec].invoke +end + +# Test Kitchen +begin + Kitchen::RakeTasks.new +rescue LoadError + puts 'test-kitchen initialization failed; disabling kitchen tasks' +end + +# if we are running inside the CI pipeline, turn on +# xUnit-style test reports +if ENV.key?('CI_BUILD') + require 'ci/reporter/rake/rspec' + task spec: 'ci:setup:rspec' +end diff --git a/attributes/default.rb b/attributes/default.rb new file mode 100644 index 0000000..edf7bd2 --- /dev/null +++ b/attributes/default.rb @@ -0,0 +1,25 @@ +# +# Cookbook grafana2 +# Copyright (c) 2015 Nordstrom, Inc. +# + +default['grafana']['log_dir'] = '/var/log/grafana' +default['grafana']['log_level'] = 'Info' # Either "Trace", "Debug", "Info", "Warn", "Error", "Critical" +default['grafana']['protocol'] = 'http' +default['grafana']['port'] = '8080' +default['grafana']['domain'] = 'grafana2.example.com' + +default['grafana']['db_type'] = 'mysql' +default['grafana']['db_port'] = '3306' +default['grafana']['db_host'] = 'grafana2-mysql.example.com' +default['grafana']['db_name'] = 'grafana' +default['grafana']['db_user'] = 'grafana_user' +default['grafana']['db_password'] = 'SECRET' + +default['grafana']['session_type'] = 'mysql' + +default['grafana']['user'] = 'grafana' +default['grafana']['group'] = 'grafana' +default['grafana']['conf_ini'] = '/etc/grafana/grafana.ini' + +default['grafana']['yum_repo_url'] = 'https://packagecloud.io' diff --git a/chefignore b/chefignore new file mode 100644 index 0000000..feec19c --- /dev/null +++ b/chefignore @@ -0,0 +1,101 @@ +# OS generated files # +###################### +.DS_Store +Icon? +nohup.out +ehthumbs.db +Thumbs.db + +# SASS # +######## +.sass-cache + +# EDITORS # +########### +\#* +.#* +*~ +*.sw[a-z] +*.bak +REVISION +TAGS* +tmtags +*_flymake.* +*_flymake +*.tmproj +.project +.settings +mkmf.log + +## COMPILED ## +############## +a.out +*.o +*.pyc +*.so +*.com +*.class +*.dll +*.exe +*/rdoc/ + +# Testing # +########### +.watchr +.rspec +spec/* +spec/fixtures/* +test/* +features/* +Guardfile +Procfile + +# SCM # +####### +.git +*/.git +.gitignore +.gitmodules +.gitconfig +.gitattributes +.svn +*/.bzr/* +*/.hg/* +*/.svn/* + +# Berkshelf # +############# +Berksfile +Berksfile.lock +cookbooks/* +tmp + +# Cookbooks # +############# +CONTRIBUTING + +# Strainer # +############ +Colanderfile +Strainerfile +.colander +.strainer + +# Vagrant # +########### +.vagrant +Vagrantfile + +# Travis # +########## +.travis.yml + +# Bundler # +########### +bin/* +vendor/* +.bundle/* + +# Test Kitchen # +################ +.kitchen/* diff --git a/metadata.rb b/metadata.rb new file mode 100644 index 0000000..a0e1a6c --- /dev/null +++ b/metadata.rb @@ -0,0 +1,15 @@ +# +# Copyright (c) 2015 Nordstrom, Inc. +# +# Originally created from Nordstrom Cookbook Template v0.16.2 +# + +name 'grafana2' +maintainer 'Nordstrom, Inc.' +maintainer_email 'techinfraperfmet@nordstrom.com' +license 'All rights reserved' +description 'Installs/Configures grafana2' +version '0.1.4' + +depends 'yum' +depends 'apt' diff --git a/recipes/config.rb b/recipes/config.rb new file mode 100644 index 0000000..9caaee5 --- /dev/null +++ b/recipes/config.rb @@ -0,0 +1,7 @@ +template node['grafana']['conf_ini'] do + source 'grafana.ini.erb' + mode '600' + owner node['grafana']['user'] + group node['grafana']['group'] + notifies :restart, 'service[grafana-server]', :delayed +end diff --git a/recipes/default.rb b/recipes/default.rb new file mode 100644 index 0000000..e166628 --- /dev/null +++ b/recipes/default.rb @@ -0,0 +1,10 @@ +# +# Recipe: grafana2::default +# Copyright (c) 2015 Nordstrom, Inc. +# + +# TODO split install into package vs file based on attributes +include_recipe 'grafana2::install' + +include_recipe 'grafana2::service' +include_recipe 'grafana2::config' diff --git a/recipes/install.rb b/recipes/install.rb new file mode 100644 index 0000000..98c7ee3 --- /dev/null +++ b/recipes/install.rb @@ -0,0 +1,53 @@ +package_options = '' + +platform_family = node['platform_family'] +platform_version = node['platform_version'].to_i + +case platform_family +when 'debian' + package_options = '--force-yes -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew"' + + include_recipe 'apt' +else + rhel_version_equivalent = + case platform_family + when 'rhel' + if platform?('amazon') || platform_version >= 7 + 6 + else + platform_version + end + when 'fedora' + case platform_version + when 6..11 then 5 + when 12..18 then 6 + else + fail "Cannot map fedora version #{platform_version} to a RHEL version. aborting" + end + else + fail "Unsupported Linux platform family #{platform_family}" + end + + repo = yum_repository 'grafana' do + description 'grafana' + repo = node['grafana']['use_unstable_repo'] ? 'grafana/testing' : 'grafana/stable' + url "#{node['grafana']['yum_repo_url']}/#{repo}/el/#{rhel_version_equivalent}/$basearch/" + action :add + end + repo.gpgcheck(false) if repo.respond_to?(:gpgcheck) +end + +case platform_family +when 'debian' + package 'grafana' do + version node['grafana'].version + options package_options + end +else + yum_package 'grafana' do + version node['grafana']['version'] + options package_options + allow_downgrade true + action :upgrade + end +end diff --git a/recipes/service.rb b/recipes/service.rb new file mode 100644 index 0000000..cd694e6 --- /dev/null +++ b/recipes/service.rb @@ -0,0 +1,3 @@ +service 'grafana-server' do + action [:enable, :start] +end diff --git a/spec/recipes/default_spec.rb b/spec/recipes/default_spec.rb new file mode 100644 index 0000000..15b6fe0 --- /dev/null +++ b/spec/recipes/default_spec.rb @@ -0,0 +1,7 @@ +RSpec.describe 'grafana2::default' do + let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) } + + it 'converges successfully' do + expect(chef_run).to include_recipe(described_recipe) + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..825822c --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,92 @@ +require 'chefspec' +require 'chefspec/berkshelf' + +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause this +# file to always be loaded, without a need to explicitly require it in any files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Limits the available syntax to the non-monkey patched syntax that is recommended. + # For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = false + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +end + +ChefSpec::Coverage.start! if ENV['COVERAGE'] diff --git a/templates/default/grafana.ini.erb b/templates/default/grafana.ini.erb new file mode 100644 index 0000000..50fb3bf --- /dev/null +++ b/templates/default/grafana.ini.erb @@ -0,0 +1,198 @@ +##################### Grafana Configuration Example ##################### +# +# Everything has defaults so you only need to uncomment things you want to +# change + +; app_mode = production + +#################################### Paths #################################### +[paths] +# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is useD) +# +;data = /var/lib/grafana +# +# Directory where grafana can store logs +# +logs = <%= node['grafana']['log_dir'] %> + +#################################### Server #################################### +[server] +# Protocol (http or https) +;protocol = http + +# The ip address to bind to, empty will bind to all interfaces +;http_addr = + +# The http port to use +http_port = <%= node['grafana']['port'] %> + +# The public facing domain name used to access grafana from a browser +domain = <%= node['grafana']['domain'] %> + +# The full public facing url +;root_url = %(protocol)s://%(domain)s:%(http_port)s/ + +# Log web requests +;router_logging = false + +# the path relative working path +;static_root_path = public + +# enable gzip +;enable_gzip = false + +# https certs & key file +;cert_file = +;cert_key = + +#################################### Database #################################### +[database] +# Either "mysql", "postgres" or "sqlite3", it's your choice +type = <%= node['grafana']['db_type'] %> +host = <%= node['grafana']['db_host'] %>:<%= node['grafana']['db_port'] %> +name = <%= node['grafana']['db_name'] %> +user = <%= node['grafana']['db_user'] %> +password = <%= node['grafana']['db_password'] %> + +# For "postgres" only, either "disable", "require" or "verify-full" +;ssl_mode = disable + +# For "sqlite3" only, path relative to data_path setting +# ;path = grafana.db + +#################################### Session #################################### +[session] +# Either "memory", "file", "redis", "mysql", default is "memory" +provider = <%= node['grafana']['session_type'] %> + +# Provider config options +# memory: not have any config yet +# file: session dir path, is relative to grafana data_path +# redis: config like redis server addr, poolSize, password, e.g. `127.0.0.1:6379,100,grafana` +# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1)/database_name` +provider_config = <%= node['grafana']['db_user'] %>:<%= node['grafana']['db_password'] %>@tcp(<%= node['grafana']['db_host'] %>:<%= node['grafana']['db_port'] %>)/<%= node['grafana']['db_name'] %> + +# Session cookie name +;cookie_name = grafana_sess + +# If you use session in https only, default is false +;cookie_secure = false + +# Session life time, default is 86400 +;session_life_time = 86400 + +#################################### Analytics #################################### +[analytics] +# Server reporting, sends usage counters to stats.grafana.org every 24 hours. +# No ip addresses are being tracked, only simple counters to track +# running instances, dashboard and error counts. It is very helpful to us. +# Change this option to false to disable reporting. +;reporting_enabled = true + +# Google Analytics universal tracking code, only enabled if you specify an id here +;google_analytics_ua_id = + +#################################### Security #################################### +[security] +# default admin user, created on startup +;admin_user = admin + +# default admin password, can be changed before first start of grafana, or in profile settings +;admin_password = admin + +# used for signing +;secret_key = AAAABBBBBCCCC + +# Auto-login remember days +;login_remember_days = 7 +;cookie_username = grafana_user +;cookie_remember_name = grafana_remember + +#################################### Users #################################### +[users] +# disable user signup / registration +;allow_sign_up = true + +# Allow non admin users to create organizations +;allow_org_create = true + +# Set to true to automatically assign new users to the default organization (id 1) +;auto_assign_org = true + +# Default role new users will be automatically assigned (if disabled above is set to true) +;auto_assign_org_role = Viewer + +#################################### Anonymous Auth ########################## +[auth.anonymous] +# enable anonymous access +enabled = true + +# specify organization name that should be used for unauthenticated users +org_name = Nordstrom Inc + +# specify role for unauthenticated users +;org_role = Viewer + +#################################### Github Auth ########################## +[auth.github] +;enabled = false +;client_id = some_id +;client_secret = some_secret +;scopes = user:email +;auth_url = https://github.com/login/oauth/authorize +;token_url = https://github.com/login/oauth/access_token +;api_url = https://api.github.com/user +# Uncomment bellow to only allow specific email domains +; allowed_domains = mycompany.com othercompany.com + +#################################### Google Auth ########################## +[auth.google] +;enabled = false +;client_id = some_client_id +;client_secret = some_client_secret +;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email +;auth_url = https://accounts.google.com/o/oauth2/auth +;token_url = https://accounts.google.com/o/oauth2/token +;api_url = https://www.googleapis.com/oauth2/v1/userinfo +# Uncomment bellow to only allow specific email domains +; allowed_domains = mycompany.com othercompany.com + +#################################### Logging ########################## +[log] +# Either "console", "file", default is "console" +# Use comma to separate multiple modes, e.g. "console, file" +;mode = console, file + +# Buffer length of channel, keep it as it is if you don't know what it is. +;buffer_len = 10000 + +# Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace" +level = <%= node['grafana']['log_level'] %> + +# For "console" mode only +[log.console] +;level = + +# For "file" mode only +[log.file] +;level = +# This enables automated log rotate(switch of following options), default is true +;log_rotate = true + +# Max line number of single file, default is 1000000 +;max_lines = 1000000 + +# Max size shift of single file, default is 28 means 1 << 28, 256MB +;max_lines_shift = 28 + +# Segment log daily, default is true +;daily_rotate = true + +# Expired days of log file(delete after max days), default is 7 +;max_days = 7 + +#################################### AMPQ Event Publisher ########################## +[event_publisher] +;enabled = false +;rabbitmq_url = amqp://localhost/ +;exchange = grafana_events diff --git a/test/integration/default/serverspec/cookbook/default_spec.rb b/test/integration/default/serverspec/cookbook/default_spec.rb new file mode 100644 index 0000000..254788c --- /dev/null +++ b/test/integration/default/serverspec/cookbook/default_spec.rb @@ -0,0 +1,16 @@ +# +# Copyright (c) 2015 Nordstrom, Inc. +# + +require 'spec_helper' + +# this is a generic ServerSpec test. It just runs 'whoami' +# and confirms that it returns 'root'. In a real test suite, +# you would want to test things like directories, users, +# processes, services, etc. +# +# for more information on the things ServerSpec can test, refer +# to the documentation at http://serverspec.org +describe command('whoami') do + its(:stdout) { should eq "root\n" } +end diff --git a/test/integration/default/serverspec/spec_helper.rb b/test/integration/default/serverspec/spec_helper.rb new file mode 100644 index 0000000..7157acd --- /dev/null +++ b/test/integration/default/serverspec/spec_helper.rb @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015 Nordstrom, Inc. +# + +require 'serverspec' + +set :backend, :exec