├── .travis.yml ├── LICENSE ├── README.md ├── Vagrantfile ├── defaults └── main.yml ├── files ├── background.jpg └── cmdb_schema.sql ├── handlers └── main.yml ├── meta └── main.yml ├── playbook.yml ├── playbooks ├── create_host_groups_inventory.yml ├── db_exports │ └── 1_export_groups_hosts_from_db.yml ├── db_imports │ ├── 1_create_host_groups_inventory.yml │ ├── 2_import_db_inventory_to_sqlite.yml │ ├── add_host_details_to_db.yml │ ├── create_db_hostdetails.sql.j2 │ └── create_db_inventory_list.yml.j2 ├── db_inventory_list.yml.j2 ├── generate_db_inventory.yml └── import_db_inventory_to_sqlite.yml ├── provision.sh ├── requirements.yml ├── screenshots ├── Ansible_Group_Actions.png ├── Ansible_Host_details.png └── Jenkins_Integration.png ├── tasks ├── config_apache2_pages.yml ├── config_php5_apache2.yml ├── config_sqlite.yml ├── debian.yml └── main.yml ├── templates ├── etc │ └── php5 │ │ └── apache2 │ │ └── php.ini.j2 └── var │ └── www │ └── html │ ├── add_group_contact.html.j2 │ ├── add_group_contact.php.j2 │ ├── add_group_host.html.j2 │ ├── add_group_host.php.j2 │ ├── add_groups.html.j2 │ ├── add_groups.php.j2 │ ├── add_user_links.php.j2 │ ├── ansible_actions.html.j2 │ ├── ansible_actions.php.j2 │ ├── ansible_test_jenkins_job.php.j2 │ ├── calendar.php.j2 │ ├── common.php.j2 │ ├── common_base.php.j2 │ ├── configure_user_jenkins_api.php.j2 │ ├── create_user.html.j2 │ ├── create_user.php.j2 │ ├── delete_group.html.j2 │ ├── delete_group.php.j2 │ ├── delete_group_contact.php.j2 │ ├── delete_group_host.html.j2 │ ├── delete_group_host.php.j2 │ ├── edit_group.html.j2 │ ├── edit_group.php.j2 │ ├── edit_group_contact.html.j2 │ ├── edit_group_contact.php.j2 │ ├── edit_user_info.php.j2 │ ├── edit_user_jenkins_api.php.j2 │ ├── group_actions.php.j2 │ ├── index.html.j2 │ ├── index.php.j2 │ ├── login.php.j2 │ ├── logout.php.j2 │ ├── members.php.j2 │ ├── php_details.php.j2 │ ├── query_group.php.j2 │ ├── query_group_contact_info.php.j2 │ ├── query_group_details.php.j2 │ ├── query_group_hosts.php.j2 │ ├── query_host_details.php.j2 │ ├── query_users.php.j2 │ ├── register_user.php.j2 │ ├── run_group_ansible_playbook.php.j2 │ ├── send_group_email.html.j2 │ ├── send_group_email.php.j2 │ ├── validate_login.php.j2 │ ├── view_group_contact_info.php.j2 │ ├── view_user_jenkins_api.php.j2 │ └── view_user_links.php.j2 ├── tests ├── inventory └── test.yml └── vars └── main.yml /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | # Use the new container infrastructure 6 | sudo: false 7 | 8 | # Install ansible 9 | addons: 10 | apt: 11 | packages: 12 | - python-pip 13 | 14 | install: 15 | # Install ansible 16 | - pip install ansible 17 | 18 | # Check ansible version 19 | - ansible --version 20 | 21 | # Create ansible.cfg with correct roles_path 22 | - printf '[defaults]\nroles_path=../' >ansible.cfg 23 | 24 | script: 25 | # Basic role syntax check 26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check 27 | 28 | notifications: 29 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Information 2 | =========== 3 | 4 | This is a project that I started about 6-7 months ago. I worked on it for a bit and put it down. 5 | The intention of this was to turn into an Ansible Tower alternative with a ton of options. Allowing 6 | for back-end components to be pluggable. Jenkins integration, ELKStack, PowerDNS, PHPipam, VMWare, 7 | OpenStack and so much more. I initially built this around a simple SQLite DB but planned on porting 8 | to MySQL. I wrote all of the PHP code for the pages and etc. So yeah...a lot of work needed there. 9 | 10 | So I have decided to put this out here in hopes that maybe someone may have a need for something 11 | like this and/or contribute to this and push it along as an open-source project. Then again 12 | it may not be of any use but in any case. I am putting it out here. Feel free to contribute as you 13 | see fit. 14 | 15 | I had huge plans for this but honestly for one person it was a lot to take on and I have been 16 | sitting on this code for months and figured it was time to open this up to anyone and everyone 17 | and see what we can come up with. 18 | 19 | Enjoy! 20 | 21 | Usage 22 | ----- 23 | ###### Vagrant 24 | You can spin this up in a Vagrant environment easily for testing and hacking. 25 | ```` 26 | vagrant up 27 | ```` 28 | Once deployed open your browser of choice and browse to http://127.0.0.1:8080 29 | 30 | There is not a default login so you will need to click register at the bottom left 31 | of the page. Enter your details and then submit and login with the username/password 32 | you registered with. This registration is in no way sent anywhere. It is purely 33 | written to the DB and then a lookup is done to the DB for logins. (This obviously 34 | needs work). 35 | 36 | There are many playbooks to utilize within the playbooks directory. You can generate 37 | host groups and inventory with details about hosts which are discovered via ansible 38 | facts. Those facts can be imported into the DB and then will show up in the WebUI. 39 | Once those fields are populated you can then import playbooks and etc. to run against 40 | a group of hosts or a single host. Lot's of options...Many are not complete. 41 | 42 | Contributing 43 | ------------ 44 | Highly encouraged. Fork this project. Hack away at it. Submit a PR and let's keep 45 | this project going. 46 | 47 | Screenshots 48 | ----------- 49 |  50 | 51 |  52 | 53 |  54 | 55 | License 56 | ------- 57 | 58 | Apache 2.0 59 | 60 | Author Information 61 | ------------------ 62 | 63 | Larry Smith Jr. 64 | - @mrlesmithjr 65 | - http://everythingshouldbevirtual.com 66 | - mrlesmithjr [at] gmail.com 67 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | Vagrant.configure(2) do |config| 9 | config.vm.define "cmdb" do |cmdb| 10 | cmdb.vm.box = "mrlesmithjr/trusty64" 11 | cmdb.vm.hostname = "cmdb" 12 | 13 | cmdb.vm.network :private_network, ip: "192.168.202.201" 14 | cmdb.vm.network "forwarded_port", guest: 80, host: 8080 15 | 16 | cmdb.vm.provider "virtualbox" do |vb| 17 | vb.memory = "1024" 18 | end 19 | end 20 | config.vm.provision :shell, path: "provision.sh", keep_color: "true" 21 | end 22 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | allow_www_data_sudo: false 3 | apache2_root: /var/www/html 4 | cmdb_notifications_from_email: '{{ infra_email_notifications }}' 5 | cmdb_notifications_from_email_address: '{{ infra_email_notifications }}' 6 | cmdb_sqlite_db_file: '{{ cmdb_sqlite_db_path }}/cmdb.db' 7 | cmdb_sqlite_db_path: '{{ apache2_root }}/../db' 8 | cmdb_web_author: '{{ pri_domain_name }}' 9 | cmdb_web_body: '{{ pri_domain_name }} - CMDB' 10 | cmdb_web_description: 'One Stop Portal for All THINGS DevOps' 11 | cmdb_web_group: www-data 12 | cmdb_web_keywords: 'Jenkins, Rundeck, Ansible, CMDB, Logstash, ELK, PHPIpam, DDI, DNS, DevOps' 13 | cmdb_web_links: 14 | - name: 'DDI - NSEdit' 15 | url: 'http://{{ ipam_server_fqdn }}/nsedit' 16 | - name: 'DDI - PHPIpam' 17 | url: 'http://{{ ipam_server_fqdn }}/phpipam' 18 | - name: 'ELK Stack - ES Cluster Status' 19 | url: 'http://{{ logstash_server_fqdn }}:9200/_plugin/HQ' 20 | - name: 'ELK Stack - HAProxy Stats' 21 | url: 'http://{{ logstash_server_fqdn }}:9090' 22 | - name: 'ELK Stack - Logstash' 23 | url: 'http://{{ logstash_server_fqdn }}' 24 | - name: Gitlab 25 | url: 'http://{{ gitlab_server_fqdn }}' 26 | - name: 'Jenkins - CI' 27 | url: 'http://{{ jenkins_server_fqdn }}:8080' 28 | - name: Jira 29 | url: 'http://{{ jira_server_fqdn }}:8080' 30 | - name: 'RANCID - NCM - Network Configs' 31 | url: 'http://{{ gitlab_server_fqdn}}/rancid/rancid/tree/master' 32 | - name: 'Rundeck - CI' 33 | url: 'http://{{ rundeck_server_fqdn }}:4440' 34 | - name: 'Sensu - Monitoring' 35 | url: 'http://sensu.{{ pri_domain_name }}:3000' 36 | - name: 'PHP Server Info' 37 | url: 'php_details.php' 38 | cmdb_web_title: '{{ pri_domain_name }} - CMDB' 39 | cmdb_web_user: www-data 40 | enable_php_syslog: false 41 | gitlab_server_fqdn: 'gitlab.{{ pri_domain_name }}' 42 | infra_email_notifications: 'infrastructure@{{ pri_domain_name }}' 43 | install_ansible: true 44 | install_php_sqlite: true 45 | install_php: true 46 | ipam_server_fqdn: 'ipam.{{ pri_domain_name }}' 47 | jenkins_api_token: 4758714d940c7a5c9dc2e7dbd00310e6 48 | jenkins_server_fqdn: 'jenkins.{{ pri_domain_name }}' 49 | jira_server_fqdn: 'jira.{{ pri_domain_name }}' 50 | logstash_server_fqdn: 'logstash.{{ pri_domain_name }}' 51 | php_sendmail_path: '/usr/sbin/sendmail -t -i' 52 | pri_domain_name: 'example.org' 53 | rundeck_server_fqdn: 'rundeck.{{ pri_domain_name }}' 54 | -------------------------------------------------------------------------------- /files/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/ansible-cmdb/ab2a0d1eb09223d5c6754925623c39d36917803c/files/background.jpg -------------------------------------------------------------------------------- /files/cmdb_schema.sql: -------------------------------------------------------------------------------- 1 | BEGIN TRANSACTION; 2 | CREATE TABLE IF NOT EXISTS "AnsiblePlaybooks" ( 3 | `Id` INTEGER PRIMARY KEY AUTOINCREMENT, 4 | `Name` TEXT, 5 | `Description` TEXT, 6 | `Path` TEXT, 7 | UNIQUE (Name,Path) 8 | ); 9 | CREATE TABLE IF NOT EXISTS "Hosts" ( 10 | `HostId` INTEGER PRIMARY KEY AUTOINCREMENT, 11 | `HostName` TEXT NOT NULL UNIQUE, 12 | `HostDescription` TEXT, 13 | `HostCreatedOn` TEXT, 14 | `LastUpdateTime` TEXT 15 | ); 16 | CREATE TABLE IF NOT EXISTS "HostDetails" ( 17 | `HostDetailsId` INTEGER PRIMARY KEY AUTOINCREMENT, 18 | `HostArchitecture` TEXT, 19 | `HostBIOSDate` TEXT, 20 | `HostBIOSVersion` TEXT, 21 | `HostDistribution` TEXT, 22 | `HostDistributionRelease` TEXT, 23 | `HostDistributionVersion` TEXT, 24 | `HostFQDN` TEXT, 25 | `HostHardDrive` TEXT, 26 | `HostHardDrivePartions` TEXT, 27 | `HostHardDriveSize` TEXT, 28 | `HostInterface` TEXT, 29 | `HostInterfaceAddress` TEXT, 30 | `HostInterfaceGateway` TEXT, 31 | `HostInterfaceMAC` TEXT, 32 | `HostInterfaceNetmask` TEXT, 33 | `HostInterfaces` TEXT, 34 | `HostKernel` TEXT, 35 | `HostMemFreeMB` INTEGER, 36 | `HostMemTotalMB` INTEGER, 37 | `HostMounts` TEXT, 38 | `HostOSFamily` TEXT, 39 | `HostProcessor` TEXT, 40 | `HostProcessorCores` INTEGER, 41 | `HostProcessorCount` INTEGER, 42 | `HostProductName` TEXT, 43 | `HostSwapFree` INTEGER, 44 | `HostSwapTotal` INTEGER, 45 | `HostSystemVendor` TEXT, 46 | `HostTimeZone` TEXT, 47 | `HostVirtualizationType` TEXT, 48 | `LastUpdateTime` TEXT, 49 | `HostId` INTEGER, 50 | FOREIGN KEY(`HostId`) REFERENCES Hosts ( HostId ) ON DELETE CASCADE ON UPDATE CASCADE, 51 | UNIQUE (HostId,HostFQDN) 52 | ); 53 | CREATE TABLE IF NOT EXISTS "Groups" ( 54 | `GroupId` INTEGER PRIMARY KEY AUTOINCREMENT, 55 | `GroupName` TEXT NOT NULL UNIQUE, 56 | `GroupDescription` TEXT, 57 | `GroupDTAP` CHAR(1) NOT NULL, 58 | `GroupCreatedOn` TEXT, 59 | `LastUpdateTime` TEXT 60 | ); 61 | CREATE TABLE IF NOT EXISTS "GroupVars" ( 62 | `VarsId` INTEGER PRIMARY KEY AUTOINCREMENT, 63 | `VarName` TEXT NOT NULL UNIQUE, 64 | `VarDescription` TEXT, 65 | `VarReference` TEXT NOT NULL, 66 | `VarSet` TEXT NOT NULL, 67 | `VarValue` TEXT NOT NULL, 68 | `LastUpdateTime` TEXT, 69 | `GroupId` INTEGER NOT NULL, 70 | FOREIGN KEY(`GroupId`) REFERENCES Groups ( GroupId ) ON DELETE CASCADE ON UPDATE CASCADE 71 | ); 72 | CREATE TABLE IF NOT EXISTS "GroupContact" ( 73 | `ContactId` INTEGER PRIMARY KEY AUTOINCREMENT, 74 | `ContactName` TEXT NOT NULL, 75 | `ContactEmail` TEXT NOT NULL, 76 | `ContactPhone` TEXT NOT NULL, 77 | `ContactCreatedOn` TEXT, 78 | `LastUpdateTime` TEXT, 79 | `GroupId` INTEGER NOT NULL, 80 | FOREIGN KEY(`GroupId`) REFERENCES Groups ( GroupId ) ON DELETE CASCADE ON UPDATE CASCADE, 81 | UNIQUE (ContactName,ContactEmail) 82 | ); 83 | CREATE TABLE IF NOT EXISTS "HostGroups" ( 84 | `HostGroupId` INTEGER PRIMARY KEY AUTOINCREMENT, 85 | `GroupId` INTEGER NOT NULL, 86 | `GroupName` TEXT NOT NULL, 87 | `HostId` INTEGER NOT NULL, 88 | `HostName` TEXT NOT NULL, 89 | FOREIGN KEY(`GroupId`) REFERENCES Groups (GroupId) ON DELETE CASCADE ON UPDATE CASCADE, 90 | FOREIGN KEY(`HostId`) REFERENCES Hosts ( HostId ) ON DELETE CASCADE ON UPDATE CASCADE, 91 | UNIQUE (GroupId,HostId) 92 | ); 93 | CREATE TABLE IF NOT EXISTS "LoginAttempts" ( 94 | `Id` INTEGER PRIMARY KEY AUTOINCREMENT, 95 | `UserId` INTEGER NOT NULL, 96 | `Time` TEXT NOT NULL 97 | ); 98 | CREATE TABLE IF NOT EXISTS "Users" ( 99 | `UserId` INTEGER PRIMARY KEY AUTOINCREMENT, 100 | `Email` TEXT NOT NULL, 101 | `FirstName` TEXT NOT NULL, 102 | `LastName` TEXT NOT NULL, 103 | `Password` CHAR(128) NOT NULL, 104 | `Phone` TEXT, 105 | `Role` TEXT NOT NULL DEFAULT 'user', 106 | `Salt` CHAR(128), 107 | `UserName` TEXT NOT NULL, 108 | UNIQUE (UserName,Email) 109 | ); 110 | CREATE TABLE IF NOT EXISTS "UsersExtAPILinks" ( 111 | `Id` INTEGER PRIMARY KEY AUTOINCREMENT, 112 | `APIToken` TEXT, 113 | `JenkinsURL` TEXT, 114 | `JenkinsAPITokenUserId` TEXT, 115 | `JenkinsUserAPIToken` TEXT, 116 | `Name` TEXT, 117 | `Url` TEXT, 118 | `UserId` INTEGER NOT NULL, 119 | FOREIGN KEY ('UserId') REFERENCES Users (UserId) ON DELETE CASCADE ON UPDATE CASCADE, 120 | UNIQUE (UserId,Name,Url,APIToken), 121 | UNIQUE (UserId,JenkinsURL,JenkinsAPITokenUserId,JenkinsUserAPIToken) 122 | ); 123 | CREATE TABLE IF NOT EXISTS "UsersLinks" ( 124 | `Id` INTEGER PRIMARY KEY AUTOINCREMENT, 125 | `Name` TEXT NOT NULL, 126 | `Url` TEXT NOT NULL, 127 | `UserId` INTEGER NOT NULL, 128 | FOREIGN KEY(`UserId`) REFERENCES Users (UserId) ON DELETE CASCADE ON UPDATE CASCADE, 129 | UNIQUE (UserId,Name,Url) 130 | ); 131 | CREATE TABLE IF NOT EXISTS "GroupContactLog" ( 132 | `Id` INTEGER PRIMARY KEY AUTOINCREMENT, 133 | `OldContactName` TEXT, 134 | `NewContactName` TEXT, 135 | `OldContactEmail` TEXT, 136 | `NewContactEmail` TEXT, 137 | `OldContactPhone` TEXT, 138 | `NewContactPhone` TEXT, 139 | `Date` TEXT 140 | ); 141 | CREATE TABLE IF NOT EXISTS "GroupVarsLog" ( 142 | `Id` INTEGER PRIMARY KEY AUTOINCREMENT, 143 | `OldVarName` TEXT, 144 | `NewVarName` TEXT, 145 | `OldVarDescription` TEXT, 146 | `NewVarDescription` TEXT, 147 | `OldVarReference` TEXT, 148 | `NewVarReference` TEXT, 149 | `OldVarSet` TEXT, 150 | `NewVarSet` TEXT, 151 | `OldVarValue` TEXT, 152 | `NewVarValue` TEXT, 153 | `Date` TEXT 154 | ); 155 | CREATE TABLE IF NOT EXISTS "GroupsLog" ( 156 | `Id` INTEGER PRIMARY KEY AUTOINCREMENT, 157 | `OldGroupName` TEXT, 158 | `NewGroupName` TEXT, 159 | `OldGroupDescription` TEXT, 160 | `NewGroupDescription` TEXT, 161 | `Date` TEXT 162 | ); 163 | CREATE TRIGGER IF NOT EXISTS GroupContactUpdated UPDATE OF ContactName ON GroupContact 164 | BEGIN 165 | INSERT INTO GroupContactLog(OldContactName, NewContactName, Date) VALUES (old.ContactName, New.ContactName, datetime('now')); 166 | END; 167 | COMMIT; 168 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for ansible-cmdb 3 | - name: restart apache2 4 | service: name=apache2 state=restarted 5 | 6 | - name: reload apache2 7 | service: name=apache2 state=reloaded 8 | 9 | - name: reload ferm 10 | shell: service ferm force-reload 11 | 12 | - name: run ferm 13 | shell: ferm /etc/ferm/ferm.conf 14 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: your name 3 | description: 4 | company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # Optionally specify the branch Galaxy will use when accessing the GitHub 22 | # repo for this role. During role install, if no tags are available, 23 | # Galaxy will use this branch. During import Galaxy will access files on 24 | # this branch. If travis integration is cofigured, only notification for this 25 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 26 | # (usually master) will be used. 27 | #github_branch: 28 | 29 | # 30 | # Below are all platforms currently available. Just uncomment 31 | # the ones that apply to your role. If you don't see your 32 | # platform on this list, let us know and we'll get it added! 33 | # 34 | #platforms: 35 | #- name: EL 36 | # versions: 37 | # - all 38 | # - 5 39 | # - 6 40 | # - 7 41 | #- name: GenericUNIX 42 | # versions: 43 | # - all 44 | # - any 45 | #- name: Solaris 46 | # versions: 47 | # - all 48 | # - 10 49 | # - 11.0 50 | # - 11.1 51 | # - 11.2 52 | # - 11.3 53 | #- name: Fedora 54 | # versions: 55 | # - all 56 | # - 16 57 | # - 17 58 | # - 18 59 | # - 19 60 | # - 20 61 | # - 21 62 | # - 22 63 | #- name: Windows 64 | # versions: 65 | # - all 66 | # - 2012R2 67 | #- name: SmartOS 68 | # versions: 69 | # - all 70 | # - any 71 | #- name: opensuse 72 | # versions: 73 | # - all 74 | # - 12.1 75 | # - 12.2 76 | # - 12.3 77 | # - 13.1 78 | # - 13.2 79 | #- name: Amazon 80 | # versions: 81 | # - all 82 | # - 2013.03 83 | # - 2013.09 84 | #- name: GenericBSD 85 | # versions: 86 | # - all 87 | # - any 88 | #- name: FreeBSD 89 | # versions: 90 | # - all 91 | # - 8.0 92 | # - 8.1 93 | # - 8.2 94 | # - 8.3 95 | # - 8.4 96 | # - 9.0 97 | # - 9.1 98 | # - 9.1 99 | # - 9.2 100 | #- name: Ubuntu 101 | # versions: 102 | # - all 103 | # - lucid 104 | # - maverick 105 | # - natty 106 | # - oneiric 107 | # - precise 108 | # - quantal 109 | # - raring 110 | # - saucy 111 | # - trusty 112 | # - utopic 113 | # - vivid 114 | #- name: SLES 115 | # versions: 116 | # - all 117 | # - 10SP3 118 | # - 10SP4 119 | # - 11 120 | # - 11SP1 121 | # - 11SP2 122 | # - 11SP3 123 | #- name: GenericLinux 124 | # versions: 125 | # - all 126 | # - any 127 | #- name: Debian 128 | # versions: 129 | # - all 130 | # - etch 131 | # - jessie 132 | # - lenny 133 | # - squeeze 134 | # - wheezy 135 | 136 | galaxy_tags: [] 137 | # List tags for your role here, one per line. A tag is 138 | # a keyword that describes and categorizes the role. 139 | # Users find roles by searching for tags. Be sure to 140 | # remove the '[]' above if you add tags to this list. 141 | # 142 | # NOTE: A tag is limited to a single word comprised of 143 | # alphanumeric characters. Maximum 20 tags per role. 144 | 145 | dependencies: [] 146 | # List your role dependencies here, one per line. 147 | # Be sure to remove the '[]' above if you add dependencies 148 | # to this list. -------------------------------------------------------------------------------- /playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | become: true 4 | vars: 5 | - install_ansible: false #set to false for Vagrant environment...Ansible is already installed. 6 | roles: 7 | - role: ansible-postfix 8 | - role: ansible-timezone 9 | - role: ansible-apache2 10 | - role: ansible-cmdb 11 | -------------------------------------------------------------------------------- /playbooks/create_host_groups_inventory.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | sudo: true 3 | remote_user: remote 4 | vars: 5 | - db_inventory_dir: ./db_inventory 6 | - db_inventory_file: ./db_inventory.yml 7 | tasks: 8 | - name: creating db_inventory_dir 9 | file: path="{{ db_inventory_dir }}" state=directory 10 | delegate_to: localhost 11 | run_once: true 12 | sudo: false 13 | 14 | - name: removing existing inventory files 15 | file: path="{{ item }}" state=absent 16 | delegate_to: localhost 17 | with_items: 18 | - "{{ db_inventory_dir }}/{{ ansible_hostname }}.yml" 19 | - "{{ db_inventory_file }}" 20 | 21 | - name: creating yaml list of groups/hosts 22 | template: src=db_inventory_list.yml.j2 dest="{{ db_inventory_dir }}/{{ ansible_hostname }}.yml" 23 | delegate_to: localhost 24 | sudo: false 25 | 26 | - name: merging all host inventory groups into one 27 | assemble: src="{{ db_inventory_dir }}/" dest="{{ db_inventory_file }}" 28 | delegate_to: localhost 29 | run_once: true 30 | sudo: false 31 | 32 | - name: adding list var to inventory file 33 | lineinfile: dest="{{ db_inventory_file }}" regexp="^host_groups" line="host_groups{{ ':' }}" insertbefore=BOF 34 | delegate_to: localhost 35 | run_once: true 36 | sudo: false 37 | 38 | - name: adding yaml formatting to inventory file 39 | lineinfile: dest="{{ db_inventory_file }}" regexp="^---" line="---" insertbefore=BOF 40 | delegate_to: localhost 41 | run_once: true 42 | sudo: false 43 | 44 | - name: chmodding inventory file 45 | file: path="{{ db_inventory_file }}" mode=0775 46 | delegate_to: localhost 47 | run_once: true 48 | -------------------------------------------------------------------------------- /playbooks/db_exports/1_export_groups_hosts_from_db.yml: -------------------------------------------------------------------------------- 1 | --- 2 | #### Exports Groups and Hosts from DB and dumps to an inventory file for use with Ansible.. 3 | #### Associcates the hosts with their proper groups. 4 | - hosts: localhost 5 | sudo: true 6 | remote_user: remote 7 | vars: 8 | - apache2_root: /var/www/html 9 | - cmdb_sqlite_db_file: '{{ cmdb_sqlite_db_path }}/cmdb.db' 10 | - cmdb_sqlite_db_path: '{{ apache2_root }}/../db' 11 | - create_inventory_file: ./hosts 12 | - db_groups_export_file: ./groups.yml 13 | tasks: 14 | - name: exporting groups from db 15 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} \"SELECT GroupName FROM HostGroups GROUP BY GroupName;\"" 16 | register: db_groups 17 | delegate_to: cmdb 18 | 19 | - name: query hosts per group 20 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} \"SELECT HostName FROM HostGroups WHERE GroupName='{{ item }}';\"" 21 | delegate_to: cmdb 22 | register: db_hosts 23 | with_items: db_groups.stdout_lines 24 | 25 | - name: checking for existing inventory file 26 | stat: path="{{ create_inventory_file }}" 27 | register: inv_file_check 28 | 29 | - name: creating inventory file when missing 30 | file: path="{{ create_inventory_file }}" state=touch 31 | sudo: false 32 | when: not inv_file_check.stat.exists 33 | 34 | - name: creating usable Ansible inventory 35 | sudo: false 36 | lineinfile: dest="{{ create_inventory_file }}" line="[{{ item.item }}]{{ '\n' }}{{ item.stdout }}{{ '\n' }}" 37 | with_items: db_hosts.results 38 | -------------------------------------------------------------------------------- /playbooks/db_imports/1_create_host_groups_inventory.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ### Takes an Ansible Inventory file and exports to a usable yaml file to be used by 2_import_db_inventory_to_sqlite.yml 3 | ### ansible-playbook -i hosts 1_create_host_groups_inventory.yml 4 | - hosts: all 5 | sudo: true 6 | remote_user: remote 7 | vars: 8 | - cmdb_web_group: www-data 9 | - cmdb_web_user: www-data 10 | - db_hostvars_dir: ./db_hostvars 11 | - db_hostvars_file: ./db_hostvars.sql 12 | - db_inventory_dir: ./db_inventory 13 | - db_inventory_file: ./db_inventory.yml 14 | tasks: 15 | - name: creating folders 16 | file: path="{{ item }}" state=directory 17 | delegate_to: localhost 18 | run_once: true 19 | sudo: false 20 | with_items: 21 | - "{{ db_hostvars_dir }}" 22 | - "{{ db_inventory_dir }}" 23 | 24 | - name: removing existing files 25 | file: path="{{ item }}" state=absent 26 | delegate_to: localhost 27 | with_items: 28 | - "{{ db_hostvars_dir }}/{{ ansible_hostname }}" 29 | - "{{ db_hostvars_file }}" 30 | - "{{ db_inventory_dir }}/{{ ansible_hostname }}.yml" 31 | - "{{ db_inventory_file }}" 32 | 33 | - name: creating yaml list of groups/hosts 34 | template: src=./create_db_inventory_list.yml.j2 dest="{{ db_inventory_dir }}/{{ ansible_hostname }}.yml" 35 | delegate_to: localhost 36 | sudo: false 37 | 38 | - name: merging all host inventory groups into one 39 | assemble: src="{{ db_inventory_dir }}/" dest="{{ db_inventory_file }}" 40 | delegate_to: localhost 41 | run_once: true 42 | sudo: false 43 | 44 | - name: adding list var to inventory file 45 | lineinfile: dest="{{ db_inventory_file }}" regexp="^host_groups" line="host_groups{{ ':' }}" insertbefore=BOF 46 | delegate_to: localhost 47 | run_once: true 48 | sudo: false 49 | 50 | - name: adding yaml formatting to inventory file 51 | lineinfile: dest="{{ db_inventory_file }}" regexp="^---" line="---" insertbefore=BOF 52 | delegate_to: localhost 53 | run_once: true 54 | sudo: false 55 | 56 | - name: chmodding inventory file 57 | file: path="{{ db_inventory_file }}" mode=0775 58 | delegate_to: localhost 59 | run_once: true 60 | -------------------------------------------------------------------------------- /playbooks/db_imports/2_import_db_inventory_to_sqlite.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ### Takes an host_groups Inventory file created by 1_create_host_groups_inventory.yml and creates groups,hosts and associates 3 | ### each of them into Host_Groups DB Table 4 | ### ansible-playbook -i hosts 2_import_db_inventory_to_sqlite.yml 5 | - hosts: localhost 6 | sudo: true 7 | remote_user: remote 8 | vars: 9 | - apache2_root: /var/www/html 10 | - cmdb_sqlite_db_file: '{{ cmdb_sqlite_db_path }}/cmdb.db' 11 | - cmdb_sqlite_db_path: '{{ apache2_root }}/../db' 12 | - sql1: "\"PRAGMA foreign_keys = ON;INSERT OR IGNORE INTO Groups(GroupName,GroupDTAP,GroupCreatedOn,LastUpdateTime) VALUES ('{{ item[1] }}','U',datetime('now'),datetime('now'));\"" 13 | - sql2: "\"PRAGMA foreign_keys = ON;INSERT OR IGNORE INTO Hosts(HostName,HostCreatedOn,LastUpdateTime) VALUES ('{{ item[0].name }}',datetime('now'),datetime('now'));\"" 14 | - sql3: "\"PRAGMA foreign_keys = ON;INSERT OR IGNORE INTO HostGroups(GroupId,GroupName,HostId,HostName) VALUES ( (SELECT GroupId FROM Groups WHERE GroupName='{{ item[1] }}'),(SELECT GroupName FROM Groups WHERE GroupName='{{ item[1] }}'),(SELECT HostId FROM Hosts Where HostName='{{ item[0].name }}'),(SELECT HostName FROM Hosts Where HostName='{{ item[0].name }}') );\"" 15 | vars_files: 16 | - ./db_inventory.yml 17 | tasks: 18 | - name: importing groups into db 19 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} {{ sql1 }}" 20 | delegate_to: cmdb 21 | with_subelements: 22 | - host_groups 23 | - groups 24 | 25 | - name: importing hosts into db 26 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} {{ sql2 }}" 27 | delegate_to: cmdb 28 | with_subelements: 29 | - host_groups 30 | - groups 31 | 32 | - name: adding hosts to groups in db 33 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} {{ sql3 }}" 34 | delegate_to: cmdb 35 | with_subelements: 36 | - host_groups 37 | - groups 38 | -------------------------------------------------------------------------------- /playbooks/db_imports/add_host_details_to_db.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ### gathers info from hosts and creates a sql file to inject into db to update host details 3 | - hosts: all 4 | sudo: true 5 | remote_user: remote 6 | vars: 7 | - cmdb_web_group: www-data 8 | - cmdb_web_user: www-data 9 | - db_hostvars_dir: ./db_hostvars 10 | - db_hostvars_file: ./db_hostvars.sql 11 | - db_inventory_dir: ./db_inventory 12 | - db_inventory_file: ./db_inventory.yml 13 | tasks: 14 | - name: creating hostvars for hosts 15 | template: src=./create_db_hostdetails.sql.j2 dest="{{ db_hostvars_dir }}/{{ ansible_hostname }}" 16 | delegate_to: localhost 17 | sudo: false 18 | 19 | - name: merging all hostvars into one sql 20 | assemble: src="{{ db_hostvars_dir }}/" dest="{{ db_hostvars_file }}" 21 | delegate_to: localhost 22 | run_once: true 23 | sudo: false 24 | 25 | - hosts: cmdb 26 | sudo: true 27 | remote_user: remote 28 | vars: 29 | - apache2_root: /var/www/html 30 | - cmdb_sqlite_db_file: '{{ cmdb_sqlite_db_path }}/cmdb.db' 31 | - cmdb_sqlite_db_path: '{{ apache2_root }}/../db' 32 | - cmdb_web_group: www-data 33 | - cmdb_web_user: www-data 34 | - db_hostvars_dir: ./db_hostvars 35 | - db_hostvars_file: ./db_hostvars.sql 36 | - db_inventory_dir: ./db_inventory 37 | - db_inventory_file: ./db_inventory.yml 38 | tasks: 39 | - name: copying sql file 40 | copy: src="{{ db_hostvars_file }}" dest='{{ cmdb_sqlite_db_path }}' owner='{{ cmdb_web_user }}' group='{{ cmdb_web_group }}' 41 | 42 | - name: adding data to sqlite3 43 | shell: "cat {{ cmdb_sqlite_db_path }}/{{ db_hostvars_file }} | sqlite3 {{ cmdb_sqlite_db_file }}" 44 | -------------------------------------------------------------------------------- /playbooks/db_imports/create_db_hostdetails.sql.j2: -------------------------------------------------------------------------------- 1 | PRAGMA foreign_keys = ON;INSERT OR REPLACE INTO HostDetails(HostId,HostArchitecture,HostBIOSDate,HostBIOSVersion,HostDistribution,HostDistributionRelease,HostDistributionVersion,HostFQDN,HostKernel,HostSystemVendor,HostVirtualizationType,LastUpdateTime,HostInterface,HostInterfaceGateway,HostInterfaceMAC,HostInterfaceNetmask,HostInterfaceAddress,HostProcessor,HostProcessorCores,HostProcessorCount,HostMemFreeMB,HostMemTotalMB,HostOSFamily,HostProductName,HostSwapFree,HostSwapTotal,HostSystemVendor) VALUES( (SELECT HostId FROM Hosts WHERE HostName='{{ inventory_hostname }}'),'{{ ansible_architecture }}','{{ ansible_bios_date }}','{{ ansible_bios_version }}','{{ ansible_distribution }}','{{ ansible_distribution_release }}','{{ ansible_distribution_version }}','{{ ansible_fqdn }}','{{ ansible_kernel }}','{{ ansible_system_vendor }}','{{ ansible_virtualization_type }}',datetime('now'),'{{ ansible_default_ipv4.interface }}','{{ ansible_default_ipv4.gateway }}','{{ ansible_default_ipv4.macaddress }}','{{ ansible_default_ipv4.netmask }}','{{ ansible_default_ipv4.address }}','{{ ansible_processor|join }}','{{ ansible_processor_cores }}','{{ ansible_processor_count}}','{{ ansible_memfree_mb }}','{{ ansible_memtotal_mb }}','{{ ansible_os_family }}','{{ ansible_product_name }}','{{ ansible_swapfree_mb }}','{{ ansible_swaptotal_mb }}','{{ ansible_system_vendor }}'); 2 | -------------------------------------------------------------------------------- /playbooks/db_imports/create_db_inventory_list.yml.j2: -------------------------------------------------------------------------------- 1 | - name: {{ ansible_hostname }} 2 | groups: 3 | {% for group in group_names %} 4 | - {{ group }} 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /playbooks/db_inventory_list.yml.j2: -------------------------------------------------------------------------------- 1 | - name: {{ ansible_hostname }} 2 | groups: 3 | {% for group in group_names %} 4 | - {{ group }} 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /playbooks/generate_db_inventory.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | sudo: true 4 | remote_user: remote 5 | vars: 6 | - db_inventory_file: db_inventory 7 | - clear_inventory: true 8 | tasks: 9 | - name: pinging hosts 10 | local_action: ping 11 | register: id_hosts 12 | 13 | - name: delete inventory file 14 | file: path="{{ db_inventory_file }}" state=absent 15 | delegate_to: localhost 16 | run_once: true 17 | when: clear_inventory is defined and clear_inventory 18 | 19 | - name: checking if inventory file exists 20 | stat: path="{{ db_inventory_file }}" 21 | register: db_inventory 22 | delegate_to: localhost 23 | run_once: true 24 | 25 | - name: creating inventory file if not exists 26 | file: path="{{ db_inventory_file }}" state=touch 27 | delegate_to: localhost 28 | run_once: true 29 | when: not db_inventory.stat.exists 30 | 31 | - name: populating db inventory 32 | lineinfile: dest="{{ db_inventory_file }}" line="{{ group_names }}" 33 | delegate_to: localhost 34 | with_items: id_hosts.results 35 | 36 | - name: cleaning up groups 37 | shell: "sed -i -e \"s/[][]//g\" {{ db_inventory_file }}" 38 | delegate_to: localhost 39 | run_once: true 40 | 41 | - name: cleaning up groups 42 | shell: "sed -i -e \"s/'//g\" {{ db_inventory_file }}" 43 | delegate_to: localhost 44 | run_once: true 45 | 46 | - name: cleaning up groups 47 | shell: "tr -s ', ' '\n ' < {{ db_inventory_file }} > {{ db_inventory_file }}.clean" 48 | delegate_to: localhost 49 | run_once: true 50 | 51 | - name: removing duplicate group_names 52 | shell: "sort -u {{ db_inventory_file }}.clean > {{ db_inventory_file }}" 53 | delegate_to: localhost 54 | run_once: true 55 | 56 | - name: reformatting inventory into a usable variable list 57 | shell: "sed -i -e 's/^/ - /' {{ db_inventory_file }}" 58 | delegate_to: localhost 59 | run_once: true 60 | 61 | - name: adding variable name for list 62 | lineinfile: dest="{{ db_inventory_file }}" regexp="^host_groups" line="host_groups{{ ':' }}" insertbefore=BOF 63 | delegate_to: localhost 64 | run_once: true 65 | 66 | - name: adding yaml formatting 67 | lineinfile: dest="{{ db_inventory_file }}" regexp="^---" line="---" insertbefore=BOF 68 | delegate_to: localhost 69 | run_once: true 70 | -------------------------------------------------------------------------------- /playbooks/import_db_inventory_to_sqlite.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | sudo: true 3 | remote_user: remote 4 | vars: 5 | - apache2_root: /var/www/html 6 | - cmdb_sqlite_db_file: '{{ cmdb_sqlite_db_path }}/cmdb.db' 7 | - cmdb_sqlite_db_path: '{{ apache2_root }}/db' 8 | - sql1: "\"PRAGMA foreign_keys = ON;INSERT OR IGNORE INTO Groups(GroupName,GroupDTAP,GroupCreatedOn,LastUpdateTime) VALUES ('{{ item[1] }}','U',datetime('now'),datetime('now'));\"" 9 | # - sql2: "\"INSERT OR IGNORE INTO Hosts (HostName,HostCreatedOn,LastUpdateTime,HostGroup) VALUES ('{{ item[0].name }}',datetime('now'),datetime('now'),(SELECT GroupId from Groups WHERE '{{ item[1] }}'=GroupName));\"" 10 | - sql3: "\"PRAGMA foreign_keys = ON;INSERT OR IGNORE INTO Hosts (HostName,HostCreatedOn,LastUpdateTime) VALUES ('{{ item[0].name }}',datetime('now'),datetime('now'));\"" 11 | - sql4: "\"PRAGMA foreign_keys = ON;INSERT OR IGNORE INTO HostGroups (GroupId,GroupName,HostId,HostName) VALUES ( (SELECT GroupId FROM Groups WHERE GroupName='{{ item[1] }}'),(SELECT GroupName FROM Groups WHERE GroupName='{{ item[1] }}'),(SELECT HostId FROM Hosts Where HostName='{{ item[0].name }}'),(SELECT HostName FROM Hosts Where HostName='{{ item[0].name }}') );\"" 12 | 13 | vars_files: 14 | - ./db_inventory.yml 15 | tasks: 16 | - name: importing groups into db 17 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} {{ sql1 }}" 18 | delegate_to: cmdb 19 | with_subelements: 20 | - host_groups 21 | - groups 22 | 23 | - name: importing hosts into db 24 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} {{ sql3 }}" 25 | delegate_to: cmdb 26 | with_subelements: 27 | - host_groups 28 | - groups 29 | 30 | - name: adding hosts to groups in db 31 | shell: "sqlite3 {{ cmdb_sqlite_db_file }} {{ sql4 }}" 32 | delegate_to: cmdb 33 | with_subelements: 34 | - host_groups 35 | - groups 36 | -------------------------------------------------------------------------------- /provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo apt-get update 3 | sudo apt-get install -y git python-pip python-dev sshpass 4 | sudo pip install jinja2 5 | sudo pip install ansible 6 | 7 | sudo ansible-galaxy install -r /vagrant/requirements.yml -f 8 | 9 | ansible-playbook -i "localhost," -c local /vagrant/playbook.yml 10 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - src: https://github.com/mrlesmithjr/ansible-apache2.git 3 | - src: https://github.com/mrlesmithjr/ansible-cmdb.git 4 | - src: https://github.com/mrlesmithjr/ansible-postfix.git 5 | - src: https://github.com/mrlesmithjr/ansible-timezone.git 6 | -------------------------------------------------------------------------------- /screenshots/Ansible_Group_Actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/ansible-cmdb/ab2a0d1eb09223d5c6754925623c39d36917803c/screenshots/Ansible_Group_Actions.png -------------------------------------------------------------------------------- /screenshots/Ansible_Host_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/ansible-cmdb/ab2a0d1eb09223d5c6754925623c39d36917803c/screenshots/Ansible_Host_details.png -------------------------------------------------------------------------------- /screenshots/Jenkins_Integration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/ansible-cmdb/ab2a0d1eb09223d5c6754925623c39d36917803c/screenshots/Jenkins_Integration.png -------------------------------------------------------------------------------- /tasks/config_apache2_pages.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: config_apache2_pages | configuring cmdb web pages 3 | template: src='var/www/html/{{ item }}.j2' dest='{{ apache2_root }}/{{ item }}' owner='{{ cmdb_web_user }}' group='{{ cmdb_web_group }}' mode=0644 4 | with_items: 5 | - add_groups.php 6 | - add_group_contact.php 7 | - add_group_host.php 8 | - add_user_links.php 9 | - ansible_actions.php 10 | - ansible_test_jenkins_job.php 11 | - common.php 12 | - common_base.php 13 | - configure_user_jenkins_api.php 14 | - delete_group_contact.php 15 | - delete_group_host.php 16 | - delete_group.php 17 | - edit_group.php 18 | - edit_group_contact.php 19 | - edit_user_jenkins_api.php 20 | - edit_user_info.php 21 | - group_actions.php 22 | - index.php 23 | - login.php 24 | - logout.php 25 | - members.php 26 | - php_details.php 27 | - query_group.php 28 | - query_group_contact_info.php 29 | - query_group_details.php 30 | - query_group_hosts.php 31 | - query_host_details.php 32 | - query_users.php 33 | - register_user.php 34 | - run_group_ansible_playbook.php 35 | - send_group_email.php 36 | - validate_login.php 37 | - view_group_contact_info.php 38 | - view_user_jenkins_api.php 39 | - view_user_links.php 40 | 41 | - name: config_apache2_pages | copying files 42 | copy: src=background.jpg dest='{{ apache2_root }}' owner='{{ cmdb_web_user }}' group='{{ cmdb_web_group }}' 43 | 44 | - name: config_apache2_pages | cleaning up old pages 45 | file: path='{{ apache2_root }}/{{ item }}' state=absent 46 | with_items: 47 | - add_group_contact.html 48 | - add_group_contact_info.html 49 | - add_group_contact_info.php 50 | - add_group_host.html 51 | - add_groups.html 52 | - add_groups_db.php 53 | - add_user_links.html 54 | - ansible_actions.html 55 | - calendar.php 56 | - create_user.html 57 | - create_user.php 58 | - db_actions.php 59 | - db_query.php 60 | - db_tables.php 61 | - delete_group.html 62 | - delete_group_host.html 63 | - delete_group_hosts.html 64 | - delete_group_hosts.php 65 | - delete_groups.html 66 | - delete_groups.php 67 | - edit_group.html 68 | - edit_group_contact.html 69 | - edit_group_contact_info.html 70 | - edit_group_contact_info.php 71 | - email.html 72 | - email_groups.html 73 | - groups.html 74 | - groups.php 75 | - host_actions.php 76 | - index.html 77 | - query_groups_db.php 78 | - register_user.html 79 | - send_group_email.html 80 | - test.php 81 | - user_actions.php 82 | - version.php 83 | - view_jenkins_api.php 84 | -------------------------------------------------------------------------------- /tasks/config_php5_apache2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: config_php5_apache2 | configuring php5 for apache2 3 | template: src=etc/php5/apache2/php.ini.j2 dest=/etc/php5/apache2/php.ini owner=root group=root mode=0644 4 | notify: restart apache2 5 | 6 | - name: config_php5_apache2 | enabling php5 module 7 | apache2_module: name=php5 state=present 8 | notify: restart apache2 9 | 10 | - name: config_php5_apache2 | enabling php5-mcrypt 11 | shell: php5enmod mcrypt creates=/etc/php5/cli/conf.d/20-mcrypt.ini 12 | notify: restart apache2 13 | -------------------------------------------------------------------------------- /tasks/config_sqlite.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: config_sqlite | creating db folder cmdb 3 | file: path='{{ cmdb_sqlite_db_path }}' owner='{{ cmdb_web_user }}' group='{{ cmdb_web_group }}' mode=0774 state=directory 4 | 5 | - name: config_sqlite | checking for existing db for cmdb 6 | stat: path='{{ cmdb_sqlite_db_file }}' 7 | register: db_file 8 | 9 | - name: config_sqlite | creating db for cmdb 10 | file: path='{{ cmdb_sqlite_db_file }}' owner='{{ cmdb_web_user }}' group='{{ cmdb_web_group }}' mode=0774 state=touch 11 | when: not db_file.stat.exists 12 | 13 | - name: config_sqlite | copying cmdb schema 14 | copy: src=cmdb_schema.sql dest='{{ cmdb_sqlite_db_path }}' owner='{{ cmdb_web_user }}' group='{{ cmdb_web_group }}' 15 | 16 | #- name: config_sqlite | checking if cmdb schema already imported 17 | # stat: path='{{ cmdb_sqlite_db_path }}/.schema_imported' 18 | # register: cmdb_schema 19 | 20 | - name: config_sqlite | importing cmdb schema 21 | shell: "cat {{ cmdb_sqlite_db_path }}/cmdb_schema.sql | sqlite3 {{ cmdb_sqlite_db_file }}" 22 | # register: cmdb_schema_imported 23 | # when: not cmdb_schema.stat.exists 24 | 25 | #- name: config_sqlite | marking cmdb schema as imported 26 | # file: path='{{ cmdb_sqlite_db_path }}/.schema_imported' state=touch 27 | # when: cmdb_schema_imported.changed 28 | -------------------------------------------------------------------------------- /tasks/debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: debian | installing pre-reqs 3 | apt: name={{ item }} state=present 4 | notify: restart apache2 5 | with_items: 6 | - apache2 7 | - curl 8 | - libapache2-mod-php5 9 | - libcurl3 10 | - libsqlite3-dev 11 | - php5-curl 12 | - php5-mcrypt 13 | - php5-sqlite 14 | - sqlite3 15 | 16 | - name: debian | adding ansible ppa 17 | apt_repository: repo='ppa:ansible/ansible' 18 | when: install_ansible is defined and install_ansible 19 | 20 | - name: debian | installing ansible 21 | apt: name=ansible state=latest 22 | when: install_ansible is defined and install_ansible 23 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for ansible-cmdb 3 | - include: debian.yml 4 | 5 | - include: config_php5_apache2.yml 6 | tags: [config_php5_apache2] 7 | 8 | - include: config_sqlite.yml 9 | tags: [config_sqlite] 10 | 11 | - include: config_apache2_pages.yml 12 | tags: [config_apache2_pages] 13 | -------------------------------------------------------------------------------- /templates/var/www/html/add_group_contact.html.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 |"; 37 | echo "GroupId: "; 38 | echo ""; 40 | echo ""; 39 | echo " " . $row['GroupId']. "
"; 41 | echo "GroupName: "; 42 | echo ""; 44 | echo "" . $row['GroupName']. "
"; 43 | echo "
"; 45 | echo "GroupDescription: "; 46 | echo ""; 48 | echo "" . $row['GroupDescription']. "
"; 47 | echo "
"; 49 | echo "GroupDTAP: "; 50 | echo ""; 52 | echo "" . $row['GroupDTAP']. "
"; 51 | echo "
"; 53 | echo "GroupCreatedOn: "; 54 | echo ""; 56 | echo "" . $row['GroupCreatedOn']. "
"; 55 | echo "
"; 57 | echo "LastUpdateTime: "; 58 | echo "" . $row['LastUpdateTime']. "
"; 59 | echo "