Setup Puppet Dashboard with WEBrick

Sekarang penulis akan berbagi mengenai Puppet Dashboard. Puppet Dashboard adalah aplikasi Ruby on Rails yang dirancang sebagai monitoring maupun report dari puppet agent. Ia juga bisa berfungsi untuk melihat inventaris dari host-host yang kita miliki, yang datanya di ambil dari facter. Sebenarnya penulis sudah bermain dengan dashboard ini sejak tahun lalu bersamaan dengan foreman, Alhamdulillah ada kesempatan berbagi sekarang. Mari kita bersama-sama pelajari. Sebelum itu mari kita jabarkan dahulu langkah yang akan kita lakukan:

1. Tambahkan repo dari puppetlabs
2. Install puppet dashboard
3. Konfig MySQL
4. Migrate table puppet-dashboard
5. testing

Tambakan repo puppetlabs:
[root@LAB01-01 ~]# cat /etc/yum.repos.d/puppetlabs.repo 
[puppetlabs-products]
name=Puppet Labs Products El 5 - $basearch
baseurl=http://yum.puppetlabs.com/el/5/products/$basearch
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
enabled=1
gpgcheck=1

[puppetlabs-deps]
name=Puppet Labs Dependencies El 5 - $basearch
baseurl=http://yum.puppetlabs.com/el/5/dependencies/$basearch
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
enabled=1
gpgcheck=1

[puppetlabs-devel]
name=Puppet Labs Devel El 5 - $basearch
baseurl=http://yum.puppetlabs.com/el/5/devel/$basearch
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
enabled=0
gpgcheck=1

[puppetlabs-products-source]
name=Puppet Labs Products El 5 - $basearch - Source
baseurl=http://yum.puppetlabs.com/el/5/products/SRPMS
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
failovermethod=priority
enabled=0
gpgcheck=1

[puppetlabs-deps-source]
name=Puppet Labs Source Dependencies El 5 - $basearch - Source
baseurl=http://yum.puppetlabs.com/el/5/dependencies/SRPMS
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
enabled=0
gpgcheck=1

[puppetlabs-devel-source]
name=Puppet Labs Devel El 5 - $basearch - Source
baseurl=http://yum.puppetlabs.com/el/5/devel/SRPMS
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
enabled=0
gpgcheck=1
[root@LAB01-01 ~]# yum install puppet-dashboard

Installing:
 puppet-dashboard               noarch          1.2.14-1.el5
Installing for dependencies:
 mysql                          x86_64          5.0.95-1.el5_7.1
 perl-DBI                       x86_64          1.52-2.el5
 ruby-mysql                     x86_64          2.7.3-2
 rubygem-rake                   noarch          0.8.7-2.el5
 rubygems                       noarch          1.3.7-1.el5
Updating for dependencies:
 ruby                           x86_64          1.8.7.370-1.el5
 ruby-irb                       x86_64          1.8.7.370-1.el5
 ruby-libs                      x86_64          1.8.7.370-1.el5
 ruby-rdoc                      x86_64          1.8.7.370-1.el5
[root@LAB01-01 ~]# ll /usr/share/puppet-dashboard/
total 136
drwxr-xr-x  7 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 app
drwxr-xr-x  2 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 bin
drwxr-xr-x  2 puppet-dashboard puppet-dashboard 4096 Nov  9 15:22 certs
drwxr-xr-x  5 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 config
drwxr-xr-x  3 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 db
drwxr-xr-x  2 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 examples
drwxr-xr-x  4 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 ext
drwxr-xr-x  4 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 lib
drwxr-xr-x  2 puppet-dashboard puppet-dashboard 4096 Nov  9 15:22 log
drwxr-xr-x  5 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 public
-rw-r--r--  1 puppet-dashboard puppet-dashboard 1451 Oct  4 19:05 Rakefile
drwxr-xr-x  3 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 script
drwxr-xr-x 10 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 spec
drwxr-xr-x  2 puppet-dashboard puppet-dashboard 4096 Nov  9 15:22 spool
drwxr-xr-x  2 puppet-dashboard puppet-dashboard 4096 Nov  9 15:22 tmp
drwxr-xr-x  5 puppet-dashboard puppet-dashboard 4096 Nov 10 04:16 vendor
-rw-r--r--  1 puppet-dashboard puppet-dashboard    7 Nov  9 13:51 VERSION

[root@LAB01-01 ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 45
Server version: 5.0.95 Source distribution

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE DATABASE puppet_dashboard CHARACTER SET utf8;
Query OK, 1 row affected (0.00 sec)

mysql> CREATE USER 'dashboard'@'localhost' IDENTIFIED BY 'Jago@nNeon!';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON puppet_dashboard.* TO 'dashboard'@'localhost';
Query OK, 0 rows affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema | 
| mysql              | 
| puppet             | 
| puppet_dashboard   | 
| test               | 
+--------------------+
5 rows in set (0.00 sec)

mysql> SELECT user FROM mysql.user;
+-----------+
| user      |
+-----------+
| root      | 
|           | 
| root      | 
|           | 
| dashboard | 
| puppet    | 
| root      | 
+-----------+
7 rows in set (0.00 sec)

mysql> quit
Bye

[root@LAB01-01 ~]# cat /etc/my.cnf 
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1

# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
# symbolic-links=0

max_allowed_packet = 32M

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[root@LAB01-01 ~]# /etc/init.d/mysqld restart
Stopping MySQL:                                            [  OK  ]
Starting MySQL:                                            [  OK  ]

[root@LAB01-01 ~]# cd /usr/share/puppet-dashboard/
[root@LAB01-01 puppet-dashboard]# rake RAILS_ENV=production db:migrate

==  BasicSchema: migrating ====================================================
-- create_table(:assignments, {:force=>true})
   -> 0.0081s
-- create_table(:nodes, {:force=>true})
   -> 0.0067s
-- create_table(:services, {:force=>true})
   -> 0.0074s
==  BasicSchema: migrated (0.0240s) ===========================================

==  CreateNodeGroupMemberships: migrating =====================================
-- create_table(:node_group_memberships)
   -> 0.0061s
==  CreateNodeGroupMemberships: migrated (0.0067s) ============================

==  CreateNodeClasses: migrating ==============================================
-- create_table(:node_classes)
   -> 0.0056s
==  CreateNodeClasses: migrated (0.0061s) =====================================

==  CreateNodeClassMemberships: migrating =====================================
-- create_table(:node_class_memberships)
   -> 0.0059s
==  CreateNodeClassMemberships: migrated (0.0064s) ============================

==  CreateNodeGroups: migrating ===============================================
-- create_table(:node_groups)
   -> 0.0060s
==  CreateNodeGroups: migrated (0.0066s) ======================================

==  CreateNodeGroupClassMemberships: migrating ================================
-- create_table(:node_group_class_memberships)
   -> 0.0071s
==  CreateNodeGroupClassMemberships: migrated (0.0076s) =======================

==  AddParametersToNodeGroups: migrating ======================================
-- add_column(:node_groups, :parameters, :text)
   -> 0.0096s
==  AddParametersToNodeGroups: migrated (0.0102s) =============================

==  CreateTimelineEvents: migrating ===========================================
-- create_table(:timeline_events)
   -> 0.0079s
==  CreateTimelineEvents: migrated (0.0084s) ==================================

==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0099s
==  CreateUsers: migrated (0.0105s) ===========================================

==  CreateParameters: migrating ===============================================
-- create_table(:parameters)
   -> 0.0062s
==  CreateParameters: migrated (0.0067s) ======================================

==  RemoveParametersFromNode: migrating =======================================
-- remove_column(:nodes, :parameters)
   -> 0.0083s
==  RemoveParametersFromNode: migrated (0.0088s) ==============================

==  CreateNodeGroupEdges: migrating ===========================================
-- create_table(:node_group_edges)
   -> 0.0084s
==  CreateNodeGroupEdges: migrated (0.0090s) ==================================

==  RemoveParametersFromNodeGroups: migrating =================================
-- remove_column(:node_groups, :parameters)
   -> 0.0093s
==  RemoveParametersFromNodeGroups: migrated (0.0099s) ========================

==  CreateReports: migrating ==================================================
-- create_table(:reports)
   -> 0.0066s
==  CreateReports: migrated (0.0072s) =========================================

==  AddUrlToNode: migrating ===================================================
-- add_column(:nodes, :url, :string)
   -> 0.0084s
==  AddUrlToNode: migrated (0.0090s) ==========================================

==  AddReportedAtToNode: migrating ============================================
-- add_column(:nodes, :reported_at, :timestamp)
   -> 0.0085s
-- migrate Node data
   ->          100% |#########################################################################################################################| Time: 00:00:00
==  AddReportedAtToNode: migrated (0.0399s) ===================================

==  AddSuccessToReport: migrating =============================================
-- add_column(:reports, :success, :boolean)
   -> 0.0098s
==  AddSuccessToReport: migrated (0.0104s) ====================================

==  AddHostAndTimeToReport: migrating =========================================
-- add_column(:reports, :host, :string)
   -> 0.0095s
-- add_column(:reports, :time, :datetime)
   -> 0.0327s
==  AddHostAndTimeToReport: migrated (0.0433s) ================================

==  MigrateReportData: migrating ==============================================
-- migrate Report data
   ->          100% |#########################################################################################################################| Time: 00:00:00
==  MigrateReportData: migrated (0.0177s) =====================================

==  AddIndexes: migrating =====================================================
-- add_index(:reports, :time)
   -> 0.0104s
-- add_index(:reports, :node_id)
   -> 0.0103s
==  AddIndexes: migrated (0.0219s) ============================================

==  AddSuccessAndLastReportToNodes: migrating =================================
-- add_column(:nodes, :success, :boolean, {:default=>false})
   -> 0.0094s
-- add_column(:nodes, :last_report_id, :integer)
   -> 0.0102s
Migrating:     100% |#########################################################################################################################| Time: 00:00:00
==  AddSuccessAndLastReportToNodes: migrated (0.0230s) ========================

==  CleanupNodeMemberships: migrating =========================================
==  CleanupNodeMemberships: migrated (0.0206s) ================================

==  ChangeReportReportFieldSizeToBeLarger: migrating ==========================
-- Increasing column size of reports to avoid truncation problems:
-- change_column(:reports, :report, :mediumtext, {:limit=>16777216})
   -> 0.0147s
==  ChangeReportReportFieldSizeToBeLarger: migrated (0.0372s) =================

==  AddSuccessToReportIndex: migrating ========================================
-- remove_index(:reports, :node_id)
   -> 0.0095s
-- add_index(:reports, [:node_id, :success])
   -> 0.0106s
==  AddSuccessToReportIndex: migrated (0.0212s) ===============================

==  RemoveDuplicateClassAndGroupMemberships: migrating ========================
==  RemoveDuplicateClassAndGroupMemberships: migrated (0.0215s) ===============

==  AdjustIndexesOnReports: migrating =========================================
-- remove_index(:reports, :time)
   -> 0.0107s
-- add_index(:reports, [:time, :node_id, :success])
   -> 0.0097s
==  AdjustIndexesOnReports: migrated (0.0215s) ================================

==  AddStatusToReports: migrating =============================================
-- add_column(:reports, :status, :string)
   -> 0.0087s
-- add_index(:reports, [:time, :node_id, :status])
   -> 0.0100s
-- remove_index(:reports, [:time, :node_id, :success])
   -> 0.0104s
-- remove_column(:reports, :success)
   -> 0.0088s
-- add_column(:nodes, :status, :string)
   -> 0.0083s
-- remove_column(:nodes, :success)
   -> 0.0092s
==  AddStatusToReports: migrated (0.0587s) ====================================

==  AddHiddenToNodes: migrating ===============================================
-- add_column(:nodes, :hidden, :boolean, {:default=>false})
   -> 0.0090s
==  AddHiddenToNodes: migrated (0.0096s) ======================================

==  SchematizeReports: migrating ==============================================
-- create_table(:report_logs)
   -> 0.0071s
-- add_index(:report_logs, [:report_id])
   -> 0.0109s
-- create_table(:resource_statuses)
   -> 0.0074s
-- add_index(:resource_statuses, [:report_id])
   -> 0.0102s
-- create_table(:resource_events)
   -> 0.0074s
-- add_index(:resource_events, [:resource_status_id])
   -> 0.0099s
-- create_table(:metrics)
   -> 0.0064s
-- add_index(:metrics, [:report_id])
   -> 0.0099s
-- remove_index("reports", {:name=>"index_reports_on_node_id_and_success"})
   -> 0.0103s
-- remove_index("reports", ["time", "node_id", "status"])
   -> 0.0108s
-- rename_table(:reports, :old_reports)
   -> 0.0017s
-- create_table(:reports)
   -> 0.0073s
-- add_index("reports", ["node_id"])
   -> 0.0101s
-- add_index("reports", ["time", "node_id", "status"])
   -> 0.0103s
==  SchematizeReports: migrated (0.1283s) =====================================

==  AddBaselineReportIdToNodes: migrating =====================================
-- add_column(:nodes, :baseline_report_id, :integer)
   -> 0.0096s
==  AddBaselineReportIdToNodes: migrated (0.0102s) ============================

==  DropUserTable: migrating ==================================================
-- drop_table(:users)
   -> 0.0021s
==  DropUserTable: migrated (0.0026s) =========================================

==  AddOutOfSyncCountToResourceStatuses: migrating ============================
-- add_column(:resource_statuses, :out_of_sync_count, :integer)
   -> 0.0104s
==  AddOutOfSyncCountToResourceStatuses: migrated (0.0110s) ===================

==  RemoveSourceDescriptionFromResourceStatuses: migrating ====================
-- remove_column(:resource_statuses, :source_description)
   -> 0.0091s
==  RemoveSourceDescriptionFromResourceStatuses: migrated (0.0097s) ===========

==  RemoveSourceDescriptionFromResourceEvents: migrating ======================
-- remove_column(:resource_events, :source_description)
   -> 0.0087s
==  RemoveSourceDescriptionFromResourceEvents: migrated (0.0092s) =============

==  AddHistoricalValueToResourceEvents: migrating =============================
-- add_column(:resource_events, :historical_value, :string)
   -> 0.0091s
==  AddHistoricalValueToResourceEvents: migrated (0.0098s) ====================

==  AddAuditedToResourceEvents: migrating =====================================
-- add_column(:resource_events, :audited, :boolean)
   -> 0.0098s
==  AddAuditedToResourceEvents: migrated (0.0103s) ============================

==  RemoveTagsFromResourceEvents: migrating ===================================
-- remove_column(:resource_events, :tags)
   -> 0.0094s
==  RemoveTagsFromResourceEvents: migrated (0.0100s) ==========================

==  AddSkippedToResourceStatuses: migrating ===================================
-- add_column(:resource_statuses, :skipped, :boolean)
   -> 0.0091s
==  AddSkippedToResourceStatuses: migrated (0.0097s) ==========================

==  RemoveOutOfSyncColumn: migrating ==========================================
-- remove_column(:resource_statuses, :out_of_sync)
   -> 0.0095s
==  RemoveOutOfSyncColumn: migrated (0.0101s) =================================

==  MakeLongStringFieldsIntoTextFields: migrating =============================
-- change_table(:report_logs)
   -> 0.0476s
-- change_table(:resource_events)
   -> 0.0512s
-- change_table(:resource_statuses)
   -> 0.1424s
==  MakeLongStringFieldsIntoTextFields: migrated (0.2429s) ====================

==  AddLastInspectReportIdToNodes: migrating ==================================
-- add_column(:nodes, :last_inspect_report_id, :integer)
   -> 0.0099s
==  AddLastInspectReportIdToNodes: migrated (0.0104s) =========================

==  RemoveUnusedTablesAndModels: migrating ====================================
-- drop_table(:assignments)
   -> 0.0025s
-- drop_table(:services)
   -> 0.0024s
==  RemoveUnusedTablesAndModels: migrated (0.0065s) ===========================

==  RenameColumnLastReportIdToLastApplyReportIdOnNodes: migrating =============
-- rename_column(:nodes, :last_report_id, :last_apply_report_id)
   -> 0.0158s
==  RenameColumnLastReportIdToLastApplyReportIdOnNodes: migrated (0.0165s) ====

==  AddFailedToResourceStatuses: migrating ====================================
-- add_column(:resource_statuses, :failed, :boolean)
   -> 0.0112s
==  AddFailedToResourceStatuses: migrated (0.0117s) ===========================

==  RemoveColumnBaselineReportIdFromNodes: migrating ==========================
-- remove_column(:nodes, :baseline_report_id)
   -> 0.0113s
==  RemoveColumnBaselineReportIdFromNodes: migrated (0.0118s) =================

==  AddStatusColumnToResourceStatuses: migrating ==============================
-- add_column(:resource_statuses, :status, :string)
   -> 0.0105s
==  AddStatusColumnToResourceStatuses: migrated (0.0123s) =====================

==  CreateDelayedJobs: migrating ==============================================
-- create_table(:delayed_jobs, {:force=>true})
   -> 0.0086s
-- add_index(:delayed_jobs, [:priority, :run_at], {:name=>"delayed_jobs_priority"})
   -> 0.0105s
========================================================================
You MUST run at least one `delayed_job` worker on your system, so that
background jobs are processed.  Without this various parts of dashboard,
especially things like report import, will not work.

Please see `README.markdown` for details of how to run the workers, or
use one of:

] rake RAILS_ENV=production jobs:work
] ./script/delayed_job -p dashboard -n $CPUS -m start
========================================================================
==  CreateDelayedJobs: migrated (0.0205s) =====================================

==  CreateDelayedJobFailures: migrating =======================================
-- create_table(:delayed_job_failures)
   -> 0.0067s
==  CreateDelayedJobFailures: migrated (0.0074s) ==============================

==  AddNodeHostUniquenessConstraint: migrating ================================
-- execute("      ALTER TABLE nodes\n        ADD CONSTRAINT uc_node_name UNIQUE (name)\n")
   -> 0.0090s
==  AddNodeHostUniquenessConstraint: migrated (0.0096s) =======================

==  AddDelayedJobFailureBacktrace: migrating ==================================
-- add_column(:delayed_job_failures, :backtrace, :text)
   -> 0.0088s
==  AddDelayedJobFailureBacktrace: migrated (0.0094s) =========================

==  AddReportForeignKeyConstraints: migrating =================================
Going to delete orphaned records from metrics, report_logs, resource_statuses, resource_events
Preparing to delete from metrics
2012-11-10 04:34:19: Deleting 0 orphaned records from metrics
Deleting       100% |#########################################################################################################################| Time: 00:00:00

Preparing to delete from report_logs
2012-11-10 04:34:19: Deleting 0 orphaned records from report_logs
Deleting       100% |#########################################################################################################################| Time: 00:00:00

Preparing to delete from resource_statuses
2012-11-10 04:34:19: Deleting 0 orphaned records from resource_statuses
Deleting       100% |#########################################################################################################################| Time: 00:00:00

Preparing to delete from resource_events
2012-11-10 04:34:19: Deleting 0 orphaned records from resource_events
Deleting       100% |#########################################################################################################################| Time: 00:00:00

-- execute("ALTER TABLE reports ADD CONSTRAINT fk_reports_node_id FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE;")
   -> 0.0124s
-- execute("ALTER TABLE resource_events ADD CONSTRAINT fk_resource_events_resource_status_id FOREIGN KEY (resource_status_id) REFERENCES resource_statuses(id) ON DELETE CASCADE;")
   -> 0.0147s
-- execute("ALTER TABLE resource_statuses ADD CONSTRAINT fk_resource_statuses_report_id FOREIGN KEY (report_id) REFERENCES reports(id) ON DELETE CASCADE;")
   -> 0.0091s
-- execute("ALTER TABLE report_logs ADD CONSTRAINT fk_report_logs_report_id FOREIGN KEY (report_id) REFERENCES reports(id) ON DELETE CASCADE;")
   -> 0.0098s
-- execute("ALTER TABLE metrics ADD CONSTRAINT fk_metrics_report_id FOREIGN KEY (report_id) REFERENCES reports(id) ON DELETE CASCADE;")
   -> 0.0097s
==  AddReportForeignKeyConstraints: migrated (0.0933s) ========================

==  RemoveUrlFromNodes: migrating =============================================
-- remove_column(:nodes, :url)
   -> 0.0088s
==  RemoveUrlFromNodes: migrated (0.0093s) ====================================
[root@LAB01-01 ~]# /etc/init.d/puppet-dashboard start
Starting Puppet Dashboard: NOTE: Gem.source_index is deprecated, use Specification. It will be removed on or after 2011-11-01.
--cut--
=> Booting WEBrick
=> Rails 2.3.14 application starting on http://0.0.0.0:3000
                                                           [  OK  ]
[root@LAB01-01 ~]# /etc/init.d/puppet-dashboard-workers start
Starting puppet-dashboard-workers: NOTE: Gem.source_index is deprecated, use Specification. It will be removed on or after 2011-11-01.
--cut--
                                                           [  OK  ]
[root@LAB01-01 ~]# puppet agent --test
Info: Retrieving plugin
Info: Caching catalog for lab01-01.cloud.net
Info: Applying configuration version '1352606090'
Finished catalog run in 0.08 seconds
[root@LAB01-02 ~]# puppet agent --test
info: Caching catalog for lab01-02.cloud.net
info: Applying configuration version '1352606152'
notice: Finished catalog run in 0.13 seconds