diff --git a/.delivery/project.toml b/.delivery/project.toml deleted file mode 100644 index 4066e55..0000000 --- a/.delivery/project.toml +++ /dev/null @@ -1,9 +0,0 @@ -[local_phases] -unit = 'rspec spec/' -lint = 'cookstyle --display-cop-names --extra-details' -syntax = "berks install -e integration" -provision = "echo skipping" -deploy = "echo skipping" -smoke = "echo skipping" -functional = "echo skipping" -cleanup = "echo skipping" diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d7ee44a..0000000 --- a/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.bundle/ -berks-cookbooks/ -.kitchen -.vagrant -.coverage/ -*.swp -Berksfile.lock -Vagrantfile -Gemfile.lock diff --git a/.rubocop.yml b/.rubocop.yml deleted file mode 100644 index 389f270..0000000 --- a/.rubocop.yml +++ /dev/null @@ -1,4 +0,0 @@ -Chef/Modernize/FoodcriticComments: - Enabled: true -Chef/Style/CopyrightCommentFormat: - Enabled: true diff --git a/.zuul.yaml b/.zuul.yaml deleted file mode 100644 index f578684..0000000 --- a/.zuul.yaml +++ /dev/null @@ -1,3 +0,0 @@ -- project: - templates: - - openstack-chef-jobs diff --git a/Berksfile b/Berksfile deleted file mode 100644 index 1566a16..0000000 --- a/Berksfile +++ /dev/null @@ -1,23 +0,0 @@ -source 'https://supermarket.chef.io' - -solver :ruby, :required - -[ - %w(client dep), - %w(-common dep), - %w(-dns integration), - %w(-identity dep), - %w(-image integration), - %w(-integration-test integration), - %w(-network integration), - %w(-ops-database integration), - %w(-ops-messaging integration), -].each do |cookbook, group| - if Dir.exist?("../cookbook-openstack#{cookbook}") - cookbook "openstack#{cookbook}", path: "../cookbook-openstack#{cookbook}", group: group - else - cookbook "openstack#{cookbook}", git: "https://opendev.org/openstack/cookbook-openstack#{cookbook}", group: group - end -end - -metadata diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 6b21ad7..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,35 +0,0 @@ -Contributing -============ - -How To Get Started ------------------- - -If you would like to contribute to the development of OpenStack Chef Cookbooks, -you must follow the steps in this page: - - https://docs.openstack.org/infra/manual/developers.html - -Gerrit Workflow ---------------- - -Once those steps have been completed, changes to OpenStack -should be submitted for review via the Gerrit tool, following -the workflow documented at: - - https://docs.openstack.org/infra/manual/developers.html#development-workflow - -Pull requests submitted through GitHub will be ignored. - -Bugs ----- - -Bugs should be filed on Launchpad, not GitHub: - - https://bugs.launchpad.net/openstack-chef - -Contacts --------- - -Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-infra -IRC: #openstack-chef is our channel on irc.oftc.net -Wiki: https://wiki.openstack.org/wiki/Chef/GettingStarted diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 68c771a..0000000 --- a/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - diff --git a/README.rst b/README.rst index b7a16b8..4ee2c5f 100644 --- a/README.rst +++ b/README.rst @@ -1,145 +1,10 @@ -OpenStack Chef Cookbook - dashboard -=================================== +This project is no longer maintained. -.. image:: https://governance.openstack.org/badges/cookbook-openstack-dashboard.svg - :target: https://governance.openstack.org/reference/tags/index.html +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". -Description -=========== - -Installs the OpenStack Dashboard service **Horizon** as part of the -OpenStack reference deployment Chef for OpenStack. The `OpenStack -chef-repo`_ contains documentation for using this cookbook in the -context of a full OpenStack deployment. Horizon is currently installed -from packages. - -.. _OpenStack chef-repo: https://opendev.org/openstack/openstack-chef - -https://docs.openstack.org/horizon/latest/ - -Requirements -============ - -- Chef 16 or higher -- Chef Workstation 21.10.640 for testing (also includes Berkshelf for - cookbook dependency resolution) - -Platform -======== - -- ubuntu -- redhat -- centos - -Cookbooks -========= - -The following cookbooks are dependencies: - -- 'apache2', '~> 8.6' -- 'openstack-common', '>= 20.0.0' -- 'openstack-identity', '>= 20.0.0' - -Attributes -========== - -Please see the extensive inline documentation in ``attributes/*.rb`` for -descriptions of all the settable attributes for this cookbook. - -Note that all attributes are in the ``default['openstack']`` "namespace" - -Recipes -======= - -openstack-dashboard::horizon ----------------------------- - -- Sets up the packages needed to run the Horizon dashboard and its - dependencies. Includes openstack-dashboard::apache2-server recipe. - -openstack-dashboard::apache2-server ------------------------------------ - -- Installs the Apache webserver and sets up an ``mod_wsgi`` container to - run the Horizon dashboard. - -openstack-dashboard::neutron-lbaas-dashboard --------------------------------------------- - -- Installs the python neutron-lbaas-dashboard package. Includes - openstack-dashboard::horizon recipe at the beginning. - -License and Author -================== - -+-----------------+---------------------------------------------------+ -| **Author** | Justin Shepherd (justin.shepherd@rackspace.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Jason Cannavale (jason.cannavale@rackspace.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Ron Pedde (ron.pedde@rackspace.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Joseph Breu (joseph.breu@rackspace.com) | -+-----------------+---------------------------------------------------+ -| **Author** | William Kelly (william.kelly@rackspace.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Darren Birkett (darren.birkett@rackspace.co.uk) | -+-----------------+---------------------------------------------------+ -| **Author** | Evan Callicoat (evan.callicoat@rackspace.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Jay Pipes (jaypipes@att.com) | -+-----------------+---------------------------------------------------+ -| **Author** | John Dewey (jdewey@att.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Matt Ray (matt@opscode.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Sean Gallagher (sean.gallagher@att.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Chen Zhiwei (zhiwchen@cn.ibm.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Jian Hua Geng (gengjh@cn.ibm.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Ionut Artarisi (iartarisi@suse.cz) | -+-----------------+---------------------------------------------------+ -| **Author** | Eric Zhou (iartarisi@suse.cz) | -+-----------------+---------------------------------------------------+ -| **Author** | Jens Rosenboom (j.rosenboom@x-ion.de) | -+-----------------+---------------------------------------------------+ -| **Author** | Mark Vanderwiel (vanderwl@us.ibm.com) | -+-----------------+---------------------------------------------------+ -| **Author** | Jan Klare (j.klare@cloudbau.de) | -+-----------------+---------------------------------------------------+ -| **Author** | Christoph Albers (c.albers@x-ion.de) | -+-----------------+---------------------------------------------------+ -| **Author** | Lance Albertson (lance@osuosl.org) | -+-----------------+---------------------------------------------------+ - -+-----------------+---------------------------------------------------+ -| **Copyright** | Copyright (c) 2012, Rackspace US, Inc. | -+-----------------+---------------------------------------------------+ -| **Copyright** | Copyright (c) 2012-2013, AT&T Services, Inc. | -+-----------------+---------------------------------------------------+ -| **Copyright** | Copyright (c) 2013, Opscode, Inc. | -+-----------------+---------------------------------------------------+ -| **Copyright** | Copyright (c) 2013-2015, IBM, Corp. | -+-----------------+---------------------------------------------------+ -| **Copyright** | Copyright (c) 2013-2014, SUSE Linux GmbH. | -+-----------------+---------------------------------------------------+ -| **Copyright** | Copyright (c) 2014, x-ion GmbH. | -+-----------------+---------------------------------------------------+ -| **Copyright** | Copyright (c) 2016-2021, Oregon State University | -+-----------------+---------------------------------------------------+ - -Licensed under the Apache License, Version 2.0 (the "License"); you may -not use this file except in compliance with the License. You may obtain -a copy of the License at - -:: - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +OFTC. diff --git a/Rakefile b/Rakefile deleted file mode 100644 index 6ec521b..0000000 --- a/Rakefile +++ /dev/null @@ -1,39 +0,0 @@ -task default: ['test'] - -task test: [:syntax, :lint, :unit] - -desc 'Vendor the cookbooks in the Berksfile' -task :berks_prep do - sh %(chef exec berks vendor) -end - -desc 'Run FoodCritic (syntax) tests' -task :syntax do - sh %(chef exec foodcritic --exclude spec -f any .) -end - -desc 'Run RuboCop (lint) tests' -task :lint do - sh %(chef exec cookstyle) -end - -desc 'Run RSpec (unit) tests' -task unit: :berks_prep do - sh %(chef exec rspec --format documentation) -end - -desc 'Remove the berks-cookbooks directory and the Berksfile.lock' -task :clean do - rm_rf [ - 'berks-cookbooks', - 'Berksfile.lock', - ] -end - -desc 'All-in-One Neutron build Infra using Common task' -task :integration do - # Use the common integration task - sh %(wget -nv -t 3 -O Rakefile-Common https://opendev.org/openstack/cookbook-openstack-common/raw/branch/master/Rakefile) - load './Rakefile-Common' - Rake::Task['common_integration'].invoke -end diff --git a/TESTING.md b/TESTING.md deleted file mode 100644 index d9a964d..0000000 --- a/TESTING.md +++ /dev/null @@ -1,30 +0,0 @@ -# Testing the Cookbook # - -This cookbook uses [chefdk](https://downloads.chef.io/chef-dk/) and [berkshelf](http://berkshelf.com/) to isolate dependencies. Make sure you have chefdk and the header files for `gecode` installed before continuing. Make sure that you're using gecode version 3. More info [here](https://github.com/opscode/dep-selector-libgecode/tree/0bad63fea305ede624c58506423ced697dd2545e#using-a-system-gecode-instead). For more detailed information on what needs to be installed, you can have a quick look into the bootstrap.sh file in this repository, which does install all the needed things to get going on ubuntu trusty. The tests defined in the Rakefile include lint, style and unit. For integration testing please refere to the [openstack-chef-repo](https://github.com/stackforge/openstack-chef-repo). - -We have three test suites which you can run either, individually (there are three rake tasks): - - $ chef exec rake lint - $ chef exec rake style - $ chef exec rake unit - -or altogether: - - $ chef exec rake - -The `rake` tasks will take care of installing the needed cookbooks with `berkshelf`. - -## Rubocop ## - -[Rubocop](https://github.com/bbatsov/rubocop) is a static Ruby code analyzer, based on the community [Ruby style guide](https://github.com/bbatsov/ruby-style-guide). We are attempting to adhere to this where applicable, slowly cleaning up the cookbooks until we can turn on Rubocop for gating the commits. - -## Foodcritic ## - -[Foodcritic](http://acrmp.github.io/foodcritic/) is a lint tool for Chef cookbooks. We ignore the following rules: - -* [FC003](http://acrmp.github.io/foodcritic/#FC003) These cookbooks are not intended for Chef Solo. -* [FC023](http://acrmp.github.io/foodcritic/#FC023) Prefer conditional attributes. - -## Chefspec - -[ChefSpec](https://github.com/sethvargo/chefspec) is a unit testing framework for testing Chef cookbooks. ChefSpec makes it easy to write examples and get fast feedback on cookbook changes without the need for virtual machines or cloud servers. diff --git a/attributes/default.rb b/attributes/default.rb deleted file mode 100644 index ef515c1..0000000 --- a/attributes/default.rb +++ /dev/null @@ -1,234 +0,0 @@ -# -# Cookbook:: openstack-dashboard -# Attributes:: default -# -# Copyright:: 2012-2021, AT&T, Inc. -# Copyright:: 2013-2021, IBM, Corp. -# Copyright:: 2016-2021, Oregon State University -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Set to some text value if you want templated config files -# to contain a custom banner at the top of the written file -default['openstack']['dashboard']['custom_template_banner'] = ' -# This file is automatically generated by Chef -# Any changes will be overwritten -' -# ****************** OpenStack Dashboard Endpoints ****************************** - -# The OpenStack Dashboard non-SSL endpoint -default['openstack']['bind_service']['dashboard_http']['host'] = '0.0.0.0' -default['openstack']['bind_service']['dashboard_http']['port'] = '80' - -# The OpenStack Dashboard SSL endpoint -default['openstack']['bind_service']['dashboard_https']['host'] = '0.0.0.0' -default['openstack']['bind_service']['dashboard_https']['port'] = '443' - -# ******************************************************************************** - -default['openstack']['dashboard']['debug'] = false - -# Don't cache html pages. -# NOTE: This setting requires apache 2.4 or greater is used -default['openstack']['dashboard']['cache_html'] = false - -# The Keystone role used by default for users logging into the dashboard -default['openstack']['dashboard']['keystone_default_role'] = 'member' - -default['openstack']['dashboard']['server_hostname'] = nil -default['openstack']['dashboard']['server_aliases'] = [] -default['openstack']['dashboard']['server_admin'] = 'root@localhost' -default['openstack']['dashboard']['use_ssl'] = true -# When using a remote certificate and key, the names of the actual installed certificate -# and key in the file system are determined by the following two attributes. -# If you want the name of the installed files to match the name of the files from the URL, -# they need to be manually set below, if not the conventional horizon.* names will be used. -default['openstack']['dashboard']['ssl']['cert'] = 'horizon.pem' -default['openstack']['dashboard']['ssl']['key'] = 'horizon.key' -# Optional Chain cert -default['openstack']['dashboard']['ssl']['chain'] = nil -# Which versions of the SSL/TLS protocol will be accepted in new connections. -default['openstack']['dashboard']['ssl']['protocol'] = 'All -SSLv2 -SSLv3' -# Which ciphers to use with the SSL/TLS protocol. -# Example: 'RSA:HIGH:MEDIUM:!LOW:!kEDH:!aNULL:!ADH:!eNULL:!EXP:!SSLv2:!SEED:!CAMELLIA:!PSK!RC4:!RC4-MD5:!RC4-SHA' -default['openstack']['dashboard']['ssl']['ciphers'] = nil -# Use the 'certs' databag for managing certs to disable it to use something -# external -default['openstack']['dashboard']['ssl']['use_data_bag'] = true - -# List of hosts/domains the dashboard can serve. This should be changed, a '*' -# allows everything -default['openstack']['dashboard']['allowed_hosts'] = ['*'] - -# Allow TRACE method -# -# Set to "extended" to also reflect the request body (only for testing and -# diagnostic purposes). -# -# Set to one of: On | Off | extended -default['openstack']['dashboard']['traceenable'] = 'Off' - -default['openstack']['dashboard']['secret_key_content'] = nil - -default['openstack']['dashboard']['ssl_no_verify'] = 'True' -default['openstack']['dashboard']['ssl_cacert'] = nil - -default['openstack']['dashboard']['webroot'] = '/' - -# Dashboard specific database packages -# Put common ones here and platform specific ones below. -default['openstack']['dashboard']['db_python_packages'] = { - mysql: [], - sqlite: [], -} - -case node['platform_family'] -when 'rhel' - default['openstack']['dashboard']['key_group'] = 'root' - default['openstack']['dashboard']['horizon_user'] = 'apache' - default['openstack']['dashboard']['horizon_group'] = 'apache' - default['openstack']['dashboard']['django_path'] = '/usr/share/openstack-dashboard' - default['openstack']['dashboard']['dash_path'] = "#{node['openstack']['dashboard']['django_path']}/openstack_dashboard" - default['openstack']['dashboard']['dash_state_path'] = "#{node['openstack']['dashboard']['dash_path']}/local" - default['openstack']['dashboard']['secret_key_path'] = "#{node['openstack']['dashboard']['dash_state_path']}/.secret_key_store" - default['openstack']['dashboard']['ssl']['cert_dir'] = '/etc/pki/tls/certs/' - default['openstack']['dashboard']['ssl']['key_dir'] = '/etc/pki/tls/private/' - default['openstack']['dashboard']['local_settings_path'] = '/etc/openstack-dashboard/local_settings' - default['openstack']['dashboard']['static_path'] = '/usr/share/openstack-dashboard/static' - default['openstack']['dashboard']['policy_files_path'] = '/etc/openstack-dashboard' - default['openstack']['dashboard']['login_url'] = "#{node['openstack']['dashboard']['webroot']}auth/login/" - default['openstack']['dashboard']['logout_url'] = "#{node['openstack']['dashboard']['webroot']}auth/logout/" - default['openstack']['dashboard']['login_redirect_url'] = node['openstack']['dashboard']['webroot'] - default['openstack']['dashboard']['platform'] = { - 'horizon_packages' => %w(openstack-dashboard), - 'memcache_python_packages' => node['platform_version'].to_i >= 8 ? %w(python3-memcached) : %w(python-memcached), - 'package_overrides' => '', - } -when 'debian' - default['openstack']['dashboard']['key_group'] = 'ssl-cert' - default['openstack']['dashboard']['horizon_user'] = 'horizon' - default['openstack']['dashboard']['horizon_group'] = 'horizon' - default['openstack']['dashboard']['django_path'] = '/usr/share/openstack-dashboard' - default['openstack']['dashboard']['ssl']['cert_dir'] = '/etc/ssl/certs/' - default['openstack']['dashboard']['ssl']['key_dir'] = '/etc/ssl/private/' - default['openstack']['dashboard']['local_settings_path'] = '/etc/openstack-dashboard/local_settings.py' - default['openstack']['dashboard']['login_url'] = nil - default['openstack']['dashboard']['logout_url'] = nil - default['openstack']['dashboard']['login_redirect_url'] = nil - default['openstack']['dashboard']['platform'] = { - 'memcache_python_packages' => %w(python3-memcache), - 'package_overrides' => '', - } - default['openstack']['dashboard']['platform']['horizon_packages'] = - %w( - node-less - python3-django-horizon - openstack-dashboard - ) - if platform?('ubuntu') - default['openstack']['dashboard']['dash_path'] = "#{node['openstack']['dashboard']['django_path']}/openstack_dashboard" - default['openstack']['dashboard']['dash_state_path'] = "#{node['openstack']['dashboard']['dash_path']}/local" - default['openstack']['dashboard']['secret_key_path'] = '/var/lib/openstack-dashboard/secret_key' - default['openstack']['dashboard']['static_path'] = '/var/lib/openstack-dashboard/static' - default['openstack']['dashboard']['policy_files_path'] = '/usr/share/openstack-dashboard/openstack_dashboard/conf' - else - default['openstack']['dashboard']['dash_path'] = node['openstack']['dashboard']['django_path'] - default['openstack']['dashboard']['dash_state_path'] = '/var/lib/openstack-dashboard' - default['openstack']['dashboard']['secret_key_path'] = "#{node['openstack']['dashboard']['dash_state_path']}/secret_key" - default['openstack']['dashboard']['static_path'] = "#{node['openstack']['dashboard']['dash_state_path']}/static" - default['openstack']['dashboard']['policy_files_path'] = '/etc/openstack-dashboard/policy' - end -else - default['openstack']['dashboard']['key_group'] = 'root' -end - -default['openstack']['dashboard']['wsgi_path'] = node['openstack']['dashboard']['dash_path'] + '/wsgi.py' -default['openstack']['dashboard']['wsgi_socket_prefix'] = nil -default['openstack']['dashboard']['session_backend'] = 'memcached' - -default['openstack']['dashboard']['ssl_offload'] = true -default['openstack']['dashboard']['plugins'] = nil - -default['openstack']['dashboard']['file_upload_temp_dir'] = nil - -# disable the v2 openrc download panel by default since v2 has been deprecated for a while -# TODO: remove this option completely for Train -default['openstack']['dashboard']['show_keystone_v2_rc'] = 'False' - -default['openstack']['dashboard']['error_log'] = 'openstack-dashboard-error.log' -default['openstack']['dashboard']['access_log'] = 'openstack-dashboard-access.log' - -default['openstack']['dashboard']['help_url'] = 'https://docs.openstack.org' - -default['openstack']['dashboard']['csrf_cookie_secure'] = true -default['openstack']['dashboard']['session_cookie_secure'] = true - -default['openstack']['dashboard']['keystone_multidomain_support'] = false -default['openstack']['dashboard']['keystone_default_domain'] = 'default' -default['openstack']['dashboard']['identity_api_version'] = 3 - -default['openstack']['dashboard']['volume_api_version'] = 2 -default['openstack']['dashboard']['console_type'] = 'AUTO' - -default['openstack']['dashboard']['keystone_backend']['name'] = 'native' -default['openstack']['dashboard']['keystone_backend']['can_edit_user'] = true -default['openstack']['dashboard']['keystone_backend']['can_edit_group'] = true -default['openstack']['dashboard']['keystone_backend']['can_edit_project'] = true -default['openstack']['dashboard']['keystone_backend']['can_edit_domain'] = true -default['openstack']['dashboard']['keystone_backend']['can_edit_role'] = true - -default['openstack']['dashboard']['log_level']['horizon'] = 'INFO' -default['openstack']['dashboard']['log_level']['horizon_log'] = 'INFO' -default['openstack']['dashboard']['log_level']['openstack_dashboard'] = 'INFO' -default['openstack']['dashboard']['log_level']['novaclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['cinderclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['keystoneclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['glanceclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['neutronclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['heatclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['ceilometerclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['troveclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['swiftclient'] = 'INFO' -default['openstack']['dashboard']['log_level']['openstack_auth'] = 'INFO' -default['openstack']['dashboard']['log_level']['nose.plugins.manager'] = 'INFO' -default['openstack']['dashboard']['log_level']['django'] = 'INFO' - -default['openstack']['dashboard']['heat_stack']['enable_user_pass'] = true - -default['openstack']['dashboard']['password_autocomplete'] = 'off' -default['openstack']['dashboard']['simple_ip_management'] = false -default['openstack']['dashboard']['neutron']['enable_quotas'] = true -default['openstack']['dashboard']['neutron']['enable_lb'] = false -default['openstack']['dashboard']['neutron']['enable_vpn'] = false -# Allow for misc sections to be added to the local_settings template -# For example: { -# 'CUSTOM_CONFIG_A' => { -# 'variable1': 'value1', -# 'variable2': 'value2' -# } -# 'CUSTOM_CONFIG_B' => { -# 'variable1': 'value1', -# 'variable2': 'value2' -# } -# } -# will generate: -# CUSTOM_CONFIG_A = { -# 'varable1': 'value1', -# 'varable2': 'value2', -# } -# CUSTOM_CONFIG_A = { -# 'varable1': 'value1', -# 'varable2': 'value2', -# } -default['openstack']['dashboard']['misc_local_settings'] = nil diff --git a/files/default/css/folsom.css b/files/default/css/folsom.css deleted file mode 100644 index 12e8c67..0000000 --- a/files/default/css/folsom.css +++ /dev/null @@ -1,6363 +0,0 @@ -article,aside,details,figcaption,figure,footer,header,hgroup,nav,section -{ - display: block; -} - -audio,canvas,video -{ - display: inline-block; - *display: inline; - *zoom: 1; -} - -audio:not([controls]) -{ - display: none; -} - -html -{ - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - background-color: #ddd; -} - -a:focus -{ - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -a:hover,a:active -{ - outline: 0; -} - -sub,sup -{ - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sup -{ - top: -0.5em; -} - -sub -{ - bottom: -0.25em; -} - -img -{ - max-width: 100%; - height: auto; - border: 0; - -ms-interpolation-mode: bicubic; -} - -button,input,select,textarea -{ - margin: 0; - font-size: 100%; - vertical-align: middle; -} - -button,input -{ - *overflow: visible; - line-height: normal; -} - -button::-moz-focus-inner,input::-moz-focus-inner -{ - padding: 0; - border: 0; -} - -button,input[type="button"],input[type="reset"],input[type="submit"] -{ - cursor: pointer; - -webkit-appearance: button; -} - -input[type="search"] -{ - -webkit-appearance: textfield; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button -{ - -webkit-appearance: none; -} - -textarea -{ - overflow: auto; - vertical-align: top; -} - -.clearfix -{ - *zoom: 1; -} - -.clearfix:before,.clearfix:after -{ - display: table; - content: ""; -} - -.clearfix:after -{ - clear: both; -} - -body -{ - margin: 0; - font-family: Arial,"Helvetica Neue",Helvetica,sans-serif; - font-size: 13px; - line-height: 18px; - color: #333333; - background-color: #ffffff; -} - -a -{ - color: #1d71bf; - text-decoration: none; -} - -a:hover -{ - color: #1d71bf; - text-decoration: underline; -} - -.row -{ - margin-left: -20px; - *zoom: 1; -} - -.row:before,.row:after -{ - display: table; - content: ""; -} - -.row:after -{ - clear: both; -} - -[class*="span"] -{ - float: left; - margin-left: 20px; -} - -.span1 -{ - width: 60px; -} - -.span2 -{ - width: 140px; -} - -.span3 -{ - width: 220px; -} - -.span4 -{ - width: 300px; -} - -.span5 -{ - width: 380px; -} - -.span6 -{ - width: 460px; -} - -.span7 -{ - width: 540px; -} - -.span8 -{ - width: 620px; -} - -.span9 -{ - width: 700px; -} - -.span10 -{ - width: 780px; -} - -.span11 -{ - width: 860px; -} - -.span12,.container -{ - width: 940px; -} - -.offset1 -{ - margin-left: 100px; -} - -.offset2 -{ - margin-left: 180px; -} - -.offset3 -{ - margin-left: 260px; -} - -.offset4 -{ - margin-left: 340px; -} - -.offset5 -{ - margin-left: 420px; -} - -.offset6 -{ - margin-left: 500px; -} - -.offset7 -{ - margin-left: 580px; -} - -.offset8 -{ - margin-left: 660px; -} - -.offset9 -{ - margin-left: 740px; -} - -.offset10 -{ - margin-left: 820px; -} - -.offset11 -{ - margin-left: 900px; -} - -.row-fluid -{ - width: 100%; - *zoom: 1; -} - -.row-fluid:before,.row-fluid:after -{ - display: table; - content: ""; -} - -.row-fluid:after -{ - clear: both; -} - -.row-fluid>[class*="span"] -{ - float: left; - margin-left: 2.127659574%; -} - -.row-fluid>[class*="span"]:first-child -{ - margin-left: 0; -} - -.row-fluid>.span1 -{ - width: 6.382978723%; -} - -.row-fluid>.span2 -{ - width: 14.89361702%; -} - -.row-fluid>.span3 -{ - width: 23.404255317%; -} - -.row-fluid>.span4 -{ - width: 31.914893614%; -} - -.row-fluid>.span5 -{ - width: 40.425531911%; -} - -.row-fluid>.span6 -{ - width: 48.93617020799999%; -} - -.row-fluid>.span7 -{ - width: 57.446808505%; -} - -.row-fluid>.span8 -{ - width: 65.95744680199999%; -} - -.row-fluid>.span9 -{ - width: 74.468085099%; -} - -.row-fluid>.span10 -{ - width: 82.97872339599999%; -} - -.row-fluid>.span11 -{ - width: 91.489361693%; -} - -.row-fluid>.span12 -{ - width: 99.99999998999999%; -} - -.container -{ - width: 940px; - margin-left: auto; - margin-right: auto; - *zoom: 1; -} - -.container:before,.container:after -{ - display: table; - content: ""; -} - -.container:after -{ - clear: both; -} - -.container-fluid -{ - padding-left: 20px; - padding-right: 20px; - *zoom: 1; -} - -.container-fluid:before,.container-fluid:after -{ - display: table; - content: ""; -} - -.container-fluid:after -{ - clear: both; -} - -p -{ - margin: 0 0 9px; - font-family: Arial,"Helvetica Neue",Helvetica,sans-serif; - font-size: 13px; - line-height: 18px; -} - -p small -{ - font-size: 11px; - color: #999999; -} - -.lead -{ - margin-bottom: 18px; - font-size: 20px; - font-weight: 200; - line-height: 27px; -} - -h1,h2,h3,h4,h5,h6 -{ - margin: 0; - font-weight: bold; - color: #333333; - text-rendering: optimizelegibility; -} - -h1 small,h2 small,h3 small,h4 small,h5 small,h6 small -{ - font-weight: normal; - color: #999999; -} - -h1 -{ - font-size: 30px; - line-height: 36px; -} - -h1 small -{ - font-size: 18px; -} - -h2 -{ - font-size: 24px; - line-height: 36px; -} - -h2 small -{ - font-size: 18px; -} - -h3 -{ - line-height: 27px; - font-size: 18px; -} - -h3 small -{ - font-size: 14px; -} - -h4,h5,h6 -{ - line-height: 18px; -} - -h4 -{ - font-size: 14px; -} - -h4 small -{ - font-size: 12px; -} - -h5 -{ - font-size: 12px; -} - -h6 -{ - font-size: 11px; - color: #999999; - text-transform: uppercase; -} - -.page-header -{ - padding-bottom: 17px; - margin: 18px 0; - border-bottom: 1px solid #eeeeee; -} - -.page-header h1 -{ - line-height: 1; -} - -ul,ol -{ - padding: 0; - margin: 0 0 9px 25px; -} - -ul ul,ul ol,ol ol,ol ul -{ - margin-bottom: 0; -} - -ul -{ - list-style: disc; -} - -ol -{ - list-style: decimal; -} - -li -{ - line-height: 18px; -} - -ul.unstyled,ol.unstyled -{ - margin-left: 0; - list-style: none; -} - -dl -{ - margin-bottom: 18px; -} - -dt,dd -{ - line-height: 18px; -} - -dt -{ - font-weight: bold; -} - -dd -{ - margin-left: 9px; -} - -hr -{ - margin: 18px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; -} - -strong -{ - font-weight: bold; -} - -em -{ - font-style: italic; -} - -.muted -{ - color: #999999; -} - -abbr -{ - font-size: 90%; - text-transform: uppercase; - border-bottom: 1px dotted #ddd; - cursor: help; -} - -blockquote -{ - padding: 0 0 0 15px; - margin: 0 0 18px; - border-left: 5px solid #eeeeee; -} - -blockquote p -{ - margin-bottom: 0; - font-size: 16px; - font-weight: 300; - line-height: 22.5px; -} - -blockquote small -{ - display: block; - line-height: 18px; - color: #999999; -} - -blockquote small:before -{ - content: '\2014 \00A0'; -} - -blockquote.pull-right -{ - float: right; - padding-left: 0; - padding-right: 15px; - border-left: 0; - border-right: 5px solid #eeeeee; -} - -blockquote.pull-right p,blockquote.pull-right small -{ - text-align: right; -} - -q:before,q:after,blockquote:before,blockquote:after -{ - content: ""; -} - -address -{ - display: block; - margin-bottom: 18px; - line-height: 18px; - font-style: normal; -} - -small -{ - font-size: 100%; -} - -cite -{ - font-style: normal; -} - -code,pre -{ - padding: 0 3px 2px; - font-family: Menlo,Monaco,"Courier New",monospace; - font-size: 12px; - color: #333333; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -code -{ - padding: 3px 4px; - color: #d14; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; -} - -pre -{ - display: block; - padding: 8.5px; - margin: 0 0 9px; - font-size: 12px; - line-height: 18px; - background-color: #f5f5f5; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.15); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - white-space: pre; - white-space: pre-wrap; - word-break: break-all; - word-wrap: break-word; -} - -pre.prettyprint -{ - margin-bottom: 18px; -} - -pre code -{ - padding: 0; - color: inherit; - background-color: transparent; - border: 0; -} - -.pre-scrollable -{ - max-height: 340px; - overflow-y: scroll; -} - -form -{ - margin: 0px; -} - -fieldset -{ - padding: 0; - margin: 0; - border: 0; -} - -legend -{ - display: block; - width: 100%; - padding: 0; - margin-bottom: 27px; - font-size: 19.5px; - line-height: 36px; - color: #333333; - border: 0; - border-bottom: 1px solid #eee; -} - -legend small -{ - font-size: 13.5px; - color: #999999; -} - -label,input,button,select,textarea -{ - font-size: 13px; - font-weight: normal; - line-height: 18px; -} - -input,button,select,textarea -{ - font-family: Arial,"Helvetica Neue",Helvetica,sans-serif; -} - -label -{ - display: block; - margin-bottom: 5px; - color: #333333; -} - -input,textarea,select,.uneditable-input -{ - display: inline-block; - width: 210px; - height: 18px; - padding: 4px; - margin-bottom: 9px; - font-size: 13px; - line-height: 18px; - color: #555555; - border: 1px solid #ccc; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.uneditable-textarea -{ - width: auto; - height: auto; -} - -label input,label textarea,label select -{ - display: block; -} - -input[type="image"],input[type="checkbox"],input[type="radio"] -{ - width: auto; - height: auto; - padding: 0; - margin: 3px 0; - *margin-top: 0; - line-height: normal; - cursor: pointer; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - border: 0 \9; -} - -input[type="image"] -{ - border: 0; -} - -input[type="file"] -{ - width: auto; - padding: initial; - line-height: initial; - border: initial; - background-color: #ffffff; - background-color: initial; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -input[type="button"],input[type="reset"],input[type="submit"] -{ - width: auto; - height: auto; -} - -select,input[type="file"] -{ - height: 28px; - *margin-top: 4px; - line-height: 28px; -} - -input[type="file"] -{ - line-height: 18px \9; -} - -select -{ - width: 220px; - background-color: #ffffff; -} - -select[multiple],select[size] -{ - height: auto; -} - -input[type="image"] -{ - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -textarea -{ - height: auto; -} - -input[type="hidden"] -{ - display: none; -} - -.radio,.checkbox -{ - padding-left: 18px; -} - -.radio input[type="radio"],.checkbox input[type="checkbox"] -{ - float: left; - margin-left: -18px; -} - -.controls>.radio:first-child,.controls>.checkbox:first-child -{ - padding-top: 5px; -} - -.radio.inline,.checkbox.inline -{ - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} - -.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline -{ - margin-left: 10px; -} - -input,textarea -{ - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border linear 0.2s,box-shadow linear 0.2s; - -moz-transition: border linear 0.2s,box-shadow linear 0.2s; - -ms-transition: border linear 0.2s,box-shadow linear 0.2s; - -o-transition: border linear 0.2s,box-shadow linear 0.2s; - transition: border linear 0.2s,box-shadow linear 0.2s; -} - -input:focus,textarea:focus -{ - border-color: rgba(82, 168, 236, 0.8); - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6); - outline: 0; - outline: thin dotted \9; -} - -input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus -{ - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.input-mini -{ - width: 60px; -} - -.input-small -{ - width: 90px; -} - -.input-medium -{ - width: 150px; -} - -.input-large -{ - width: 210px; -} - -.input-xlarge -{ - width: 270px; -} - -.input-xxlarge -{ - width: 530px; -} - -input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input -{ - float: none; - margin-left: 0; -} - -input.span1,textarea.span1,.uneditable-input.span1 -{ - width: 50px; -} - -input.span2,textarea.span2,.uneditable-input.span2 -{ - width: 130px; -} - -input.span3,textarea.span3,.uneditable-input.span3 -{ - width: 210px; -} - -input.span4,textarea.span4,.uneditable-input.span4 -{ - width: 290px; -} - -input.span5,textarea.span5,.uneditable-input.span5 -{ - width: 370px; -} - -input.span6,textarea.span6,.uneditable-input.span6 -{ - width: 450px; -} - -input.span7,textarea.span7,.uneditable-input.span7 -{ - width: 530px; -} - -input.span8,textarea.span8,.uneditable-input.span8 -{ - width: 610px; -} - -input.span9,textarea.span9,.uneditable-input.span9 -{ - width: 690px; -} - -input.span10,textarea.span10,.uneditable-input.span10 -{ - width: 770px; -} - -input.span11,textarea.span11,.uneditable-input.span11 -{ - width: 850px; -} - -input.span12,textarea.span12,.uneditable-input.span12 -{ - width: 930px; -} - -input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly] -{ - background-color: #f5f5f5; - border-color: #ddd; - cursor: not-allowed; -} - -.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline -{ - color: #c09853; -} - -.control-group.warning input,.control-group.warning select,.control-group.warning textarea -{ - color: #c09853; - border-color: #c09853; -} - -.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus -{ - border-color: #a47e3c; - -webkit-box-shadow: 0 0 6px #dbc59e; - -moz-box-shadow: 0 0 6px #dbc59e; - box-shadow: 0 0 6px #dbc59e; -} - -.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on -{ - color: #c09853; - background-color: #fcf8e3; - border-color: #c09853; -} - -.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline -{ - color: #c40022; -} - -.control-group.error input,.control-group.error select,.control-group.error textarea -{ - color: #333; - border-color: #c40022; -} - -.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus -{ - border-color: #953b39; - -webkit-box-shadow: 0 0 6px #d59392; - -moz-box-shadow: 0 0 6px #d59392; - box-shadow: 0 0 6px #d59392; -} - -.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on -{ - color: #b94a48; - background-color: #f2dede; - border-color: #b94a48; -} - -.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline -{ - color: #468847; -} - -.control-group.success input,.control-group.success select,.control-group.success textarea -{ - color: #468847; - border-color: #468847; -} - -.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus -{ - border-color: #356635; - -webkit-box-shadow: 0 0 6px #7aba7b; - -moz-box-shadow: 0 0 6px #7aba7b; - box-shadow: 0 0 6px #7aba7b; -} - -.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on -{ - color: #468847; - background-color: #dff0d8; - border-color: #468847; -} - -input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid -{ - color: #b94a48; - border-color: #ee5f5b; -} - -input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus -{ - border-color: #e9322d; - -webkit-box-shadow: 0 0 6px #f8b9b7; - -moz-box-shadow: 0 0 6px #f8b9b7; - box-shadow: 0 0 6px #f8b9b7; -} - -.form-actions -{ - padding: 17px 20px 18px; - margin-top: 18px; - margin-bottom: 18px; - background-color: #f5f5f5; - border-top: 1px solid #ddd; -} - -.uneditable-input -{ - display: block; - background-color: #ffffff; - border-color: #eee; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - cursor: not-allowed; -} - -:-moz-placeholder -{ - color: #999999; -} - -::-webkit-input-placeholder -{ - color: #999999; -} - -.help-block -{ - display: block; - margin-top: 5px; - margin-bottom: 0; - color: #999999; -} - -.help-inline -{ - display: inline-block; - *display: inline; - *zoom: 1; - margin-bottom: 9px; - vertical-align: middle; - padding-left: 5px; -} - -.input-prepend,.input-append -{ - margin-bottom: 5px; - *zoom: 1; -} - -.input-prepend:before,.input-append:before,.input-prepend:after,.input-append:after -{ - display: table; - content: ""; -} - -.input-prepend:after,.input-append:after -{ - clear: both; -} - -.input-prepend input,.input-append input,.input-prepend .uneditable-input,.input-append .uneditable-input -{ - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} - -.input-prepend input:focus,.input-append input:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus -{ - position: relative; - z-index: 2; -} - -.input-prepend .uneditable-input,.input-append .uneditable-input -{ - border-left-color: #ccc; -} - -.input-prepend .add-on,.input-append .add-on -{ - float: left; - display: block; - width: auto; - min-width: 16px; - height: 18px; - margin-right: -1px; - padding: 4px 5px; - font-weight: normal; - line-height: 18px; - color: #999999; - text-align: center; - text-shadow: 0 1px 0 #ffffff; - background-color: #f5f5f5; - border: 1px solid #ccc; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} - -.input-prepend .active,.input-append .active -{ - background-color: #a9dba9; - border-color: #46a546; -} - -.input-prepend .add-on -{ - *margin-top: 1px; -} - -.input-append input,.input-append .uneditable-input -{ - float: left; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} - -.input-append .uneditable-input -{ - border-left-color: #eee; - border-right-color: #ccc; -} - -.input-append .add-on -{ - margin-right: 0; - margin-left: -1px; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} - -.input-append input:first-child -{ - *margin-left: -160px; -} - -.input-append input:first-child+.add-on -{ - *margin-left: -21px; -} - -.search-query -{ - padding-left: 14px; - padding-right: 14px; - margin-bottom: 0; - -webkit-border-radius: 14px; - -moz-border-radius: 14px; - border-radius: 14px; -} - -.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input -{ - display: inline-block; - margin-bottom: 0; -} - -.form-search .hide,.form-inline .hide,.form-horizontal .hide -{ - display: none; -} - -.form-search label,.form-inline label,.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend -{ - display: inline-block; -} - -.form-search .input-append .add-on,.form-inline .input-prepend .add-on,.form-search .input-append .add-on,.form-inline .input-prepend .add-on -{ - vertical-align: middle; -} - -.form-search .radio,.form-inline .radio,.form-search .checkbox,.form-inline .checkbox -{ - margin-bottom: 0; - vertical-align: middle; -} - -.control-group -{ - margin-bottom: 9px; -} - -legend+.control-group -{ - margin-top: 18px; - -webkit-margin-top-collapse: separate; -} - -.form-horizontal .control-group -{ - margin-bottom: 18px; - *zoom: 1; -} - -.form-horizontal .control-group:before,.form-horizontal .control-group:after -{ - display: table; - content: ""; -} - -.form-horizontal .control-group:after -{ - clear: both; -} - -.form-horizontal .control-label -{ - float: left; - width: 140px; - padding-top: 5px; - text-align: right; -} - -.form-horizontal .controls -{ - margin-left: 160px; -} - -.form-horizontal .form-actions -{ - padding-left: 160px; -} - -table -{ - max-width: 100%; - border-collapse: collapse; - border-spacing: 0; -} - -.table -{ - width: 100%; - margin-bottom: 18px; -} - -.table th,.table td -{ - padding: 10px; - line-height: 20px; - text-align: left; - border-top: 1px solid #ddd; - color: #333; -} - -.table tbody td -{ - border-left: none !important; - background-color: #fff; -} - -.table th -{ - font-weight: normal; - color: #aaa; - padding: 0px 10px; - background-color: #fff; - line-height: 20px; - -} - -.table thead th -{ - vertical-align: middle; - border-left: none; - white-space: nowrap; -} - -.table thead:first-child tr th,.table thead:first-child tr td -{ - border-top: 0; -} - -.table tbody+tbody -{ - border-top: 2px solid #ddd; -} - -.table-condensed th,.table-condensed td -{ - padding: 4px 5px; -} - -.table-bordered -{ - border: 1px solid #ddd; - border-collapse: separate; - *border-collapse: collapsed; -} - -.table-bordered th+th,.table-bordered td+td,.table-bordered th+td,.table-bordered td+th -{ - -} - -.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td -{ - border-top: 0; -} - -.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th -{ - background-color: #f9f9f9; -} - -.table tbody tr:hover td,.table tbody tr:hover th -{ - background-color: #f5f5f5; -} - -table .span1 -{ - float: none; - width: 44px; - margin-left: 0; -} - -table .span2 -{ - float: none; - width: 124px; - margin-left: 0; -} - -table .span3 -{ - float: none; - width: 204px; - margin-left: 0; -} - -table .span4 -{ - float: none; - width: 284px; - margin-left: 0; -} - -table .span5 -{ - float: none; - width: 364px; - margin-left: 0; -} - -table .span6 -{ - float: none; - width: 444px; - margin-left: 0; -} - -table .span7 -{ - float: none; - width: 524px; - margin-left: 0; -} - -table .span8 -{ - float: none; - width: 604px; - margin-left: 0; -} - -table .span9 -{ - float: none; - width: 684px; - margin-left: 0; -} - -table .span10 -{ - float: none; - width: 764px; - margin-left: 0; -} - -table .span11 -{ - float: none; - width: 844px; - margin-left: 0; -} - -table .span12 -{ - float: none; - width: 924px; - margin-left: 0; -} - -[class^="icon-"],[class*=" icon-"] -{ - display: inline-block; - width: 14px; - height: 14px; - line-height: 14px; - vertical-align: text-top; - background-image: url("../img/glyphicons-halflings.png"); - background-position: 14px 14px; - background-repeat: no-repeat; - *margin-right: .3em; -} - -[class^="icon-"]:last-child,[class*=" icon-"]:last-child -{ - *margin-left: 0; -} - -.icon-white -{ - background-image: url("../img/glyphicons-halflings-white.png"); -} - -.icon-glass -{ - background-position: 0 0; -} - -.icon-music -{ - background-position: -24px 0; -} - -.icon-search -{ - background-position: -48px 0; -} - -.icon-envelope -{ - background-position: -72px 0; -} - -.icon-heart -{ - background-position: -96px 0; -} - -.icon-star -{ - background-position: -120px 0; -} - -.icon-star-empty -{ - background-position: -144px 0; -} - -.icon-user -{ - background-position: -168px 0; -} - -.icon-film -{ - background-position: -192px 0; -} - -.icon-th-large -{ - background-position: -216px 0; -} - -.icon-th -{ - background-position: -240px 0; -} - -.icon-th-list -{ - background-position: -264px 0; -} - -.icon-ok -{ - background-position: -288px 0; -} - -.icon-remove -{ - background-position: -312px 0; -} - -.icon-zoom-in -{ - background-position: -336px 0; -} - -.icon-zoom-out -{ - background-position: -360px 0; -} - -.icon-off -{ - background-position: -384px 0; -} - -.icon-signal -{ - background-position: -408px 0; -} - -.icon-cog -{ - background-position: -432px 0; -} - -.icon-trash -{ - background-position: -456px 0; -} - -.icon-home -{ - background-position: 0 -24px; -} - -.icon-file -{ - background-position: -24px -24px; -} - -.icon-time -{ - background-position: -48px -24px; -} - -.icon-road -{ - background-position: -72px -24px; -} - -.icon-download-alt -{ - background-position: -96px -24px; -} - -.icon-download -{ - background-position: -120px -24px; -} - -.icon-upload -{ - background-position: -144px -24px; -} - -.icon-inbox -{ - background-position: -168px -24px; -} - -.icon-play-circle -{ - background-position: -192px -24px; -} - -.icon-repeat -{ - background-position: -216px -24px; -} - -.icon-refresh -{ - background-position: -240px -24px; -} - -.icon-list-alt -{ - background-position: -264px -24px; -} - -.icon-lock -{ - background-position: -287px -24px; -} - -.icon-flag -{ - background-position: -312px -24px; -} - -.icon-headphones -{ - background-position: -336px -24px; -} - -.icon-volume-off -{ - background-position: -360px -24px; -} - -.icon-volume-down -{ - background-position: -384px -24px; -} - -.icon-volume-up -{ - background-position: -408px -24px; -} - -.icon-qrcode -{ - background-position: -432px -24px; -} - -.icon-barcode -{ - background-position: -456px -24px; -} - -.icon-tag -{ - background-position: 0 -48px; -} - -.icon-tags -{ - background-position: -25px -48px; -} - -.icon-book -{ - background-position: -48px -48px; -} - -.icon-bookmark -{ - background-position: -72px -48px; -} - -.icon-print -{ - background-position: -96px -48px; -} - -.icon-camera -{ - background-position: -120px -48px; -} - -.icon-font -{ - background-position: -144px -48px; -} - -.icon-bold -{ - background-position: -167px -48px; -} - -.icon-italic -{ - background-position: -192px -48px; -} - -.icon-text-height -{ - background-position: -216px -48px; -} - -.icon-text-width -{ - background-position: -240px -48px; -} - -.icon-align-left -{ - background-position: -264px -48px; -} - -.icon-align-center -{ - background-position: -288px -48px; -} - -.icon-align-right -{ - background-position: -312px -48px; -} - -.icon-align-justify -{ - background-position: -336px -48px; -} - -.icon-list -{ - background-position: -360px -48px; -} - -.icon-indent-left -{ - background-position: -384px -48px; -} - -.icon-indent-right -{ - background-position: -408px -48px; -} - -.icon-facetime-video -{ - background-position: -432px -48px; -} - -.icon-picture -{ - background-position: -456px -48px; -} - -.icon-pencil -{ - background-position: 0 -72px; -} - -.icon-map-marker -{ - background-position: -24px -72px; -} - -.icon-adjust -{ - background-position: -48px -72px; -} - -.icon-tint -{ - background-position: -72px -72px; -} - -.icon-edit -{ - background-position: -96px -72px; -} - -.icon-share -{ - background-position: -120px -72px; -} - -.icon-check -{ - background-position: -144px -72px; -} - -.icon-move -{ - background-position: -168px -72px; -} - -.icon-step-backward -{ - background-position: -192px -72px; -} - -.icon-fast-backward -{ - background-position: -216px -72px; -} - -.icon-backward -{ - background-position: -240px -72px; -} - -.icon-play -{ - background-position: -264px -72px; -} - -.icon-pause -{ - background-position: -288px -72px; -} - -.icon-stop -{ - background-position: -312px -72px; -} - -.icon-forward -{ - background-position: -336px -72px; -} - -.icon-fast-forward -{ - background-position: -360px -72px; -} - -.icon-step-forward -{ - background-position: -384px -72px; -} - -.icon-eject -{ - background-position: -408px -72px; -} - -.icon-chevron-left -{ - background-position: -432px -72px; -} - -.icon-chevron-right -{ - background-position: -456px -72px; -} - -.icon-plus-sign -{ - background-position: 0 -96px; -} - -.icon-minus-sign -{ - background-position: -24px -96px; -} - -.icon-remove-sign -{ - background-position: -48px -96px; -} - -.icon-ok-sign -{ - background-position: -72px -96px; -} - -.icon-question-sign -{ - background-position: -96px -96px; -} - -.icon-info-sign -{ - background-position: -120px -96px; -} - -.icon-screenshot -{ - background-position: -144px -96px; -} - -.icon-remove-circle -{ - background-position: -168px -96px; -} - -.icon-ok-circle -{ - background-position: -192px -96px; -} - -.icon-ban-circle -{ - background-position: -216px -96px; -} - -.icon-arrow-left -{ - background-position: -240px -96px; -} - -.icon-arrow-right -{ - background-position: -264px -96px; -} - -.icon-arrow-up -{ - background-position: -289px -96px; -} - -.icon-arrow-down -{ - background-position: -312px -96px; -} - -.icon-share-alt -{ - background-position: -336px -96px; -} - -.icon-resize-full -{ - background-position: -360px -96px; -} - -.icon-resize-small -{ - background-position: -384px -96px; -} - -.icon-plus -{ - background-position: -408px -96px; -} - -.icon-minus -{ - background-position: -433px -96px; -} - -.icon-asterisk -{ - background-position: -456px -96px; -} - -.icon-exclamation-sign -{ - background-position: 0 -120px; -} - -.icon-gift -{ - background-position: -24px -120px; -} - -.icon-leaf -{ - background-position: -48px -120px; -} - -.icon-fire -{ - background-position: -72px -120px; -} - -.icon-eye-open -{ - background-position: -96px -120px; -} - -.icon-eye-close -{ - background-position: -120px -120px; -} - -.icon-warning-sign -{ - background-position: -144px -120px; -} - -.icon-plane -{ - background-position: -168px -120px; -} - -.icon-calendar -{ - background-position: -192px -120px; -} - -.icon-random -{ - background-position: -216px -120px; -} - -.icon-comment -{ - background-position: -240px -120px; -} - -.icon-magnet -{ - background-position: -264px -120px; -} - -.icon-chevron-up -{ - background-position: -288px -120px; -} - -.icon-chevron-down -{ - background-position: -313px -119px; -} - -.icon-retweet -{ - background-position: -336px -120px; -} - -.icon-shopping-cart -{ - background-position: -360px -120px; -} - -.icon-folder-close -{ - background-position: -384px -120px; -} - -.icon-folder-open -{ - background-position: -408px -120px; -} - -.icon-resize-vertical -{ - background-position: -432px -119px; -} - -.icon-resize-horizontal -{ - background-position: -456px -118px; -} - -.dropdown -{ - position: relative; -} - -.dropdown-toggle -{ - *margin-bottom: -3px; -} - -.dropdown-toggle:active,.open .dropdown-toggle -{ - outline: 0; -} - -.caret -{ - display: inline-block; - width: 0; - height: 0; - text-indent: -99999px; - *text-indent: 0; - vertical-align: top; - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 4px solid #000000; - opacity: 0.3; - filter: alpha(opacity=30); - content: "\2193"; -} - -.dropdown .caret -{ - margin-top: 8px; - margin-left: 2px; -} - -.dropdown:hover .caret,.open.dropdown .caret -{ - opacity: 1; - filter: alpha(opacity=100); -} - -.dropdown-menu -{ - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - float: left; - display: none; - min-width: 160px; - _width: 160px; - padding: 4px 0; - margin: 0; - list-style: none; - background-color: #ffffff; - border-color: #ccc; - border-color: rgba(0, 0, 0, 0.2); - border-style: solid; - border-width: 1px; - -webkit-border-radius: 0 0 5px 5px; - -moz-border-radius: 0 0 5px 5px; - border-radius: 0 0 5px 5px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - *border-right-width: 2px; - *border-bottom-width: 2px; -} - -.dropdown-menu.bottom-up -{ - top: auto; - bottom: 100%; - margin-bottom: 2px; -} - -.dropdown-menu .divider -{ - height: 1px; - margin: 5px 1px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #ffffff; - *width: 100%; - *margin: -5px 0 5px; -} - -.dropdown-menu a -{ - display: block; - padding: 3px 15px; - clear: both; - font-weight: normal; - line-height: 18px; - color: #555555; - white-space: nowrap; -} - -.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover -{ - color: #ffffff; - text-decoration: none; - background-color: #0088cc; -} - -.dropdown.open -{ - *z-index: 1000; -} - -.dropdown.open .dropdown-toggle -{ - color: #ffffff; - background: #ccc; - background: rgba(0, 0, 0, 0.3); -} - -.dropdown.open .dropdown-menu -{ - display: block; -} - -.typeahead -{ - margin-top: 2px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.well -{ - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #eee; - border: 1px solid rgba(0, 0, 0, 0.05); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.well blockquote -{ - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} - -.fade -{ - -webkit-transition: opacity 0.15s linear; - -moz-transition: opacity 0.15s linear; - -ms-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; - opacity: 0; -} - -.fade.in -{ - opacity: 1; -} - -.collapse -{ - -webkit-transition: height 0.35s ease; - -moz-transition: height 0.35s ease; - -ms-transition: height 0.35s ease; - -o-transition: height 0.35s ease; - transition: height 0.35s ease; - position: relative; - overflow: hidden; - height: 0; -} - -.collapse.in -{ - height: auto; -} - -.close -{ - float: right; - font-size: 20px; - font-weight: bold; - line-height: 18px; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} - -.close:hover -{ - color: #000000; - text-decoration: none !important; - opacity: 0.4; - filter: alpha(opacity=40); - cursor: pointer; -} - -.btn -{ - display: inline-block; - padding: 4px 10px 4px; - margin-bottom: 0; - font-size: 13px; - line-height: 18px; - color: #333333; - text-align: center; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - vertical-align: middle; - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(top, #ffffff, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #ccc; - border-bottom-color: #bbb; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - cursor: pointer; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - *margin-left: .3em; -} - -.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled] -{ - background-color: #e6e6e6; -} - -.btn:active,.btn.active -{ - background-color: #cccccc \9; -} - -.btn:first-child -{ - *margin-left: 0; -} - -.btn:hover -{ - color: #333333; - text-decoration: none; - background-color: #e6e6e6; - background-position: 0 -15px; - -webkit-transition: background-position 0.1s linear; - -moz-transition: background-position 0.1s linear; - -ms-transition: background-position 0.1s linear; - -o-transition: background-position 0.1s linear; - transition: background-position 0.1s linear; -} - -.btn:focus -{ - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.btn.active,.btn:active -{ - background-image: none; - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05); - background-color: #e6e6e6; - background-color: #d9d9d9 \9; - outline: 0; -} - -.btn.disabled,.btn[disabled] -{ - cursor: default; - background-image: none; - background-color: #e6e6e6; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -.btn-large -{ - padding: 9px 14px; - font-size: 15px; - line-height: normal; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.btn-large [class^="icon-"] -{ - margin-top: 1px; -} - -.btn-small -{ - padding: 5px 9px; - font-size: 11px; - line-height: 16px; -} - -.btn-small [class^="icon-"] -{ - margin-top: -1px; -} - -.btn-mini -{ - padding: 2px 6px; - font-size: 11px; - line-height: 14px; -} - -.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover -{ - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - color: #ffffff; -} - -.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-dark.active -{ - color: rgba(255, 255, 255, 0.75); -} - -.btn-primary -{ - background-color: #393939; - background-image: -moz-linear-gradient(top, #454545, #262626); - background-image: -ms-linear-gradient(top, #454545, #262626); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#454545), to(#262626)); - background-image: -webkit-linear-gradient(top, #454545, #262626); - background-image: -o-linear-gradient(top, #454545, #262626); - background-image: linear-gradient(top, #454545, #262626); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#454545', endColorstr='#262626', GradientType=0); - border-color: #262626 #262626 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled] -{ - background-color: #262626; -} - -.btn-primary:active,.btn-primary.active -{ - background-color: #003399 \9; -} - -.btn-warning -{ - background-color: #faa732; - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-image: -ms-linear-gradient(top, #fbb450, #f89406); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(top, #fbb450, #f89406); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0); - border-color: #f89406 #f89406 #ad6704; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled] -{ - background-color: #f89406; -} - -.btn-warning:active,.btn-warning.active -{ - background-color: #c67605 \9; -} - -.btn-danger -{ - background-color: #da4f49; - background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -ms-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); - background-image: linear-gradient(top, #ee5f5b, #bd362f); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0); - border-color: #bd362f #bd362f #802420; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled] -{ - background-color: #bd362f; -} - -.btn-danger:active,.btn-danger.active -{ - background-color: #942a25 \9; -} - -.btn-success -{ - background-color: #5bb75b; - background-image: -moz-linear-gradient(top, #62c462, #51a351); - background-image: -ms-linear-gradient(top, #62c462, #51a351); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); - background-image: -webkit-linear-gradient(top, #62c462, #51a351); - background-image: -o-linear-gradient(top, #62c462, #51a351); - background-image: linear-gradient(top, #62c462, #51a351); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0); - border-color: #51a351 #51a351 #387038; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled] -{ - background-color: #51a351; -} - -.btn-success:active,.btn-success.active -{ - background-color: #408140 \9; -} - -.btn-info -{ - background-color: #49afcd; - background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -ms-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); - background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); - background-image: linear-gradient(top, #5bc0de, #2f96b4); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0); - border-color: #2f96b4 #2f96b4 #1f6377; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled] -{ - background-color: #2f96b4; -} - -.btn-info:active,.btn-info.active -{ - background-color: #24748c \9; -} - -.btn-inverse -{ - background-color: #393939; - background-image: -moz-linear-gradient(top, #454545, #262626); - background-image: -ms-linear-gradient(top, #454545, #262626); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#454545), to(#262626)); - background-image: -webkit-linear-gradient(top, #454545, #262626); - background-image: -o-linear-gradient(top, #454545, #262626); - background-image: linear-gradient(top, #454545, #262626); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#454545', endColorstr='#262626', GradientType=0); - border-color: #262626 #262626 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled] -{ - background-color: #262626; -} - -.btn-inverse:active,.btn-inverse.active -{ - background-color: #0c0c0c \9; -} - -button.btn,input[type="submit"].btn -{ - *padding-top: 2px; - *padding-bottom: 2px; -} - -button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner -{ - padding: 0; - border: 0; -} - -button.btn.large,input[type="submit"].btn.large -{ - *padding-top: 7px; - *padding-bottom: 7px; -} - -button.btn.small,input[type="submit"].btn.small -{ - *padding-top: 3px; - *padding-bottom: 3px; -} - -.btn-group -{ - position: relative; - *zoom: 1; - *margin-left: .3em; -} - -.btn-group:before,.btn-group:after -{ - display: table; - content: ""; -} - -.btn-group:after -{ - clear: both; -} - -.btn-group:first-child -{ - *margin-left: 0; -} - -.btn-group+.btn-group -{ - margin-left: 5px; -} - -.btn-toolbar -{ - margin-top: 9px; - margin-bottom: 9px; -} - -.btn-toolbar .btn-group -{ - display: inline-block; - *display: inline; - *zoom: 1; -} - -.btn-group .btn -{ - position: relative; - float: left; - margin-left: -1px; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.btn-group .btn:first-child -{ - margin-left: 0; - -webkit-border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; - border-top-left-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - border-bottom-left-radius: 4px; -} - -.btn-group .btn:last-child,.btn-group .dropdown-toggle -{ - -webkit-border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; - border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - border-bottom-right-radius: 4px; -} - -.btn-group .btn.large:first-child -{ - margin-left: 0; - -webkit-border-top-left-radius: 6px; - -moz-border-radius-topleft: 6px; - border-top-left-radius: 6px; - -webkit-border-bottom-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - border-bottom-left-radius: 6px; -} - -.btn-group .btn.large:last-child,.btn-group .large.dropdown-toggle -{ - -webkit-border-top-right-radius: 6px; - -moz-border-radius-topright: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - -moz-border-radius-bottomright: 6px; - border-bottom-right-radius: 6px; -} - -.btn-group .btn:hover,.btn-group .btn:focus,.btn-group .btn:active,.btn-group .btn.active -{ - z-index: 2; -} - -.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle -{ - outline: 0; -} - -.btn-group .dropdown-toggle -{ - padding-left: 8px; - padding-right: 8px; - -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - *padding-top: 5px; - *padding-bottom: 5px; -} - -.btn-group.open -{ - *z-index: 1000; -} - -.btn-group.open .dropdown-menu -{ - display: block; - margin-top: 1px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.btn-group.open .dropdown-toggle -{ - background-image: none; - -webkit-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn .caret -{ - margin-top: 7px; - margin-left: 0; -} - -.btn:hover .caret,.open.btn-group .caret -{ - opacity: 1; - filter: alpha(opacity=100); -} - -.btn-primary .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret -{ - border-top-color: #ffffff; - opacity: 0.75; - filter: alpha(opacity=75); -} - -.btn-small .caret -{ - margin-top: 4px; -} - -.alert -{ - padding: 8px 35px 8px 14px; - margin-bottom: 18px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - background-color: #fcf8e3; - border: 1px solid #fbeed5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.alert,.alert-heading -{ - color: #c40022; -} - -.alert .close -{ - position: relative; - top: -2px; - right: -25px; - line-height: 18px; -} - -.alert-success -{ - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.alert-success,.alert-success .alert-heading -{ - color: #468847; -} - -.alert-danger,.alert-error -{ - background-color: #f2dede; - border-color: #eed3d7; -} - -.alert-danger,.alert-error,.alert-danger .alert-heading,.alert-error .alert-heading -{ - color: #c40022; -} - -.alert-info -{ - background-color: #d9edf7; - border-color: #bce8f1; -} - -.alert-info,.alert-info .alert-heading -{ - color: #3a87ad; -} - -.alert-block -{ - padding-top: 10px; - padding-bottom: 10px; -} - -.alert-block>p,.alert-block>ul -{ - margin-bottom: 0; -} - -.alert-block p+p -{ - margin-top: 5px; -} - -.nav -{ - margin-left: 0; - margin-bottom: 18px; - list-style: none; -} - -.nav>li>a -{ - display: block; -} - -.nav>li>a:hover -{ - text-decoration: none; - background-color: #eeeeee; -} - -.nav .nav-header -{ - display: block; - padding: 3px 15px; - font-size: 11px; - font-weight: bold; - line-height: 18px; - color: #999999; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - text-transform: uppercase; -} - -.nav li+.nav-header -{ - margin-top: 9px; -} - -.nav-list -{ - padding-left: 14px; - padding-right: 14px; - margin-bottom: 0; -} - -.nav-list>li>a,.nav-list .nav-header -{ - margin-left: -15px; - margin-right: -15px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} - -.nav-list>li>a -{ - padding: 3px 15px; -} - -.nav-list .active>a,.nav-list .active>a:hover -{ - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); - background-color: #0088cc; -} - -.nav-list [class^="icon-"] -{ - margin-right: 2px; -} - -.nav-tabs,.nav-pills -{ - *zoom: 1; -} - -.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after -{ - display: table; - content: ""; -} - -.nav-tabs:after,.nav-pills:after -{ - clear: both; -} - -.nav-tabs>li,.nav-pills>li -{ - float: left; -} - -.nav-tabs>li>a,.nav-pills>li>a -{ - padding-right: 12px; - padding-left: 12px; - margin-right: 2px; - line-height: 14px; -} - -.nav-tabs -{ - border-bottom: 1px solid #ddd; -} - -.nav-tabs>li -{ - margin-bottom: -1px; -} - -.nav-tabs>li>a -{ - padding-top: 9px; - padding-bottom: 9px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} - -.nav-tabs>li>a:hover -{ - border-color: #eeeeee #eeeeee #dddddd; -} - -.nav-tabs>.active>a,.nav-tabs>.active>a:hover -{ - color: #555555; - background-color: #ffffff; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} - -.nav-pills>li>a -{ - padding-top: 8px; - padding-bottom: 8px; - margin-top: 2px; - margin-bottom: 2px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.nav-pills .active>a,.nav-pills .active>a:hover -{ - color: #ffffff; - background-color: #222; -} - -.nav-stacked>li -{ - float: none; -} - -.nav-stacked>li>a -{ - margin-right: 0; -} - -.nav-tabs.nav-stacked -{ - border-bottom: 0; -} - -.nav-tabs.nav-stacked>li>a -{ - border: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.nav-tabs.nav-stacked>li:first-child>a -{ - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} - -.nav-tabs.nav-stacked>li:last-child>a -{ - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} - -.nav-tabs.nav-stacked>li>a:hover -{ - border-color: #ddd; - z-index: 2; -} - -.nav-pills.nav-stacked>li>a -{ - margin-bottom: 3px; -} - -.nav-pills.nav-stacked>li:last-child>a -{ - margin-bottom: 1px; -} - -.nav-tabs .dropdown-menu,.nav-pills .dropdown-menu -{ - margin-top: 1px; - border-width: 1px; -} - -.nav-pills .dropdown-menu -{ - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret -{ - border-top-color: #0088cc; - margin-top: 6px; -} - -.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret -{ - border-top-color: #005580; -} - -.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret -{ - border-top-color: #333333; -} - -.nav>.dropdown.active>a:hover -{ - color: #000000; - cursor: pointer; -} - -.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>.open.active>a:hover -{ - color: #ffffff; - background-color: #999999; - border-color: #999999; -} - -.nav .open .caret,.nav .open.active .caret,.nav .open a:hover .caret -{ - border-top-color: #ffffff; - opacity: 1; - filter: alpha(opacity=100); -} - -.tabs-stacked .open>a:hover -{ - border-color: #999999; -} - -.tabbable -{ - *zoom: 1; -} - -.tabbable:before,.tabbable:after -{ - display: table; - content: ""; -} - -.tabbable:after -{ - clear: both; -} - -.tab-content -{ - overflow: hidden; -} - -.tab-content.dropdown_fix -{ - overflow: visible; -} - -.tabs-below .nav-tabs,.tabs-right .nav-tabs,.tabs-left .nav-tabs -{ - border-bottom: 0; -} - -.tab-content>.tab-pane,.pill-content>.pill-pane -{ - display: none; -} - -.tab-content>.active,.pill-content>.active -{ - display: block; -} - -.tabs-below .nav-tabs -{ - border-top: 1px solid #ddd; -} - -.tabs-below .nav-tabs>li -{ - margin-top: -1px; - margin-bottom: 0; -} - -.tabs-below .nav-tabs>li>a -{ - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} - -.tabs-below .nav-tabs>li>a:hover -{ - border-bottom-color: transparent; - border-top-color: #ddd; -} - -.tabs-below .nav-tabs .active>a,.tabs-below .nav-tabs .active>a:hover -{ - border-color: transparent #ddd #ddd #ddd; -} - -.tabs-left .nav-tabs>li,.tabs-right .nav-tabs>li -{ - float: none; -} - -.tabs-left .nav-tabs>li>a,.tabs-right .nav-tabs>li>a -{ - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} - -.tabs-left .nav-tabs -{ - float: left; - margin-right: 19px; - border-right: 1px solid #ddd; -} - -.tabs-left .nav-tabs>li>a -{ - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.tabs-left .nav-tabs>li>a:hover -{ - border-color: #eeeeee #dddddd #eeeeee #eeeeee; -} - -.tabs-left .nav-tabs .active>a,.tabs-left .nav-tabs .active>a:hover -{ - border-color: #ddd transparent #ddd #ddd; - *border-right-color: #ffffff; -} - -.tabs-right .nav-tabs -{ - float: right; - margin-left: 19px; - border-left: 1px solid #ddd; -} - -.tabs-right .nav-tabs>li>a -{ - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.tabs-right .nav-tabs>li>a:hover -{ - border-color: #eeeeee #eeeeee #eeeeee #dddddd; -} - -.tabs-right .nav-tabs .active>a,.tabs-right .nav-tabs .active>a:hover -{ - border-color: #ddd #ddd #ddd transparent; - *border-left-color: #ffffff; -} - -.navbar -{ - overflow: visible; - margin-bottom: 18px; -} - -.navbar-inner -{ - padding-left: 20px; - padding-right: 20px; - background-color: #2c2c2c; - background-image: -moz-linear-gradient(top, #333333, #222222); - background-image: -ms-linear-gradient(top, #333333, #222222); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222)); - background-image: -webkit-linear-gradient(top, #333333, #222222); - background-image: -o-linear-gradient(top, #333333, #222222); - background-image: linear-gradient(top, #333333, #222222); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1); -} - -.btn-navbar -{ - display: none; - float: right; - padding: 7px 10px; - margin-left: 5px; - margin-right: 5px; - background-color: #2c2c2c; - background-image: -moz-linear-gradient(top, #333333, #222222); - background-image: -ms-linear-gradient(top, #333333, #222222); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222)); - background-image: -webkit-linear-gradient(top, #333333, #222222); - background-image: -o-linear-gradient(top, #333333, #222222); - background-image: linear-gradient(top, #333333, #222222); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); - border-color: #222222 #222222 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075); -} - -.btn-navbar:hover,.btn-navbar:active,.btn-navbar.active,.btn-navbar.disabled,.btn-navbar[disabled] -{ - background-color: #222222; -} - -.btn-navbar:active,.btn-navbar.active -{ - background-color: #080808 \9; -} - -.btn-navbar .icon-bar -{ - display: block; - width: 18px; - height: 2px; - background-color: #f5f5f5; - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; - -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); -} - -.btn-navbar .icon-bar+.icon-bar -{ - margin-top: 3px; -} - -.nav-collapse.collapse -{ - height: auto; -} - -.navbar .brand:hover -{ - text-decoration: none; -} - -.navbar .brand -{ - float: left; - display: block; - padding: 8px 20px 12px; - margin-left: -20px; - font-size: 20px; - font-weight: 200; - line-height: 1; - color: #ffffff; -} - -.navbar .navbar-text -{ - margin-bottom: 0; - line-height: 40px; - color: #999999; -} - -.navbar .navbar-text a:hover -{ - color: #ffffff; - background-color: transparent; -} - -.navbar .btn,.navbar .btn-group -{ - margin-top: 5px; -} - -.navbar .btn-group .btn -{ - margin-top: 0; -} - -.navbar-form -{ - margin-bottom: 0; - *zoom: 1; -} - -.navbar-form:before,.navbar-form:after -{ - display: table; - content: ""; -} - -.navbar-form:after -{ - clear: both; -} - -.navbar-form input,.navbar-form select -{ - display: inline-block; - margin-top: 5px; - margin-bottom: 0; -} - -.navbar-form .radio,.navbar-form .checkbox -{ - margin-top: 5px; -} - -.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"] -{ - margin-top: 3px; -} - -.navbar-form .input-append,.navbar-form .input-prepend -{ - margin-top: 6px; - white-space: nowrap; -} - -.navbar-form .input-append input,.navbar-form .input-prepend input -{ - margin-top: 0; -} - -.navbar-search -{ - position: relative; - float: left; - margin-top: 6px; - margin-bottom: 0; -} - -.navbar-search .search-query -{ - padding: 4px 9px; - font-family: Arial,"Helvetica Neue",Helvetica,sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 1; - color: #ffffff; - color: rgba(255, 255, 255, 0.75); - background: #666; - background: rgba(255, 255, 255, 0.3); - border: 1px solid #111; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15); - -webkit-transition: none; - -moz-transition: none; - -ms-transition: none; - -o-transition: none; - transition: none; -} - -.navbar-search .search-query :-moz-placeholder -{ - color: #eeeeee; -} - -.navbar-search .search-query::-webkit-input-placeholder -{ - color: #eeeeee; -} - -.navbar-search .search-query:hover -{ - color: #ffffff; - background-color: #999999; - background-color: rgba(255, 255, 255, 0.5); -} - -.navbar-search .search-query:focus,.navbar-search .search-query.focused -{ - padding: 5px 10px; - color: #333333; - text-shadow: 0 1px 0 #ffffff; - background-color: #ffffff; - border: 0; - -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - outline: 0; -} - -.navbar-fixed-top -{ - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 1030; -} - -.navbar-fixed-top .navbar-inner -{ - padding-left: 0; - padding-right: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.navbar .nav -{ - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; -} - -.navbar .nav.pull-right -{ - float: right; -} - -.navbar .nav>li -{ - display: block; - float: left; -} - -.navbar .nav>li>a -{ - float: none; - padding: 10px 10px 11px; - line-height: 19px; - color: #999999; - text-decoration: none; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} - -.navbar .nav>li>a:hover -{ - background-color: transparent; - color: #ffffff; - text-decoration: none; -} - -.navbar .nav .active>a,.navbar .nav .active>a:hover -{ - color: #ffffff; - text-decoration: none; - background-color: #222222; -} - -.navbar .divider-vertical -{ - height: 40px; - width: 1px; - margin: 0 9px; - overflow: hidden; - background-color: #222222; - border-right: 1px solid #333333; -} - -.navbar .nav.pull-right -{ - margin-left: 10px; - margin-right: 0; -} - -.navbar .dropdown-menu -{ - margin-top: 1px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.navbar .dropdown-menu:before -{ - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-bottom-color: rgba(0, 0, 0, 0.2); - position: absolute; - top: -7px; - left: 9px; -} - -.navbar .dropdown-menu:after -{ - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #ffffff; - position: absolute; - top: -6px; - left: 10px; -} - -.navbar .nav .dropdown-toggle .caret,.navbar .nav .open.dropdown .caret -{ - border-top-color: #ffffff; -} - -.navbar .nav .active .caret -{ - opacity: 1; - filter: alpha(opacity=100); -} - -.navbar .nav .open>.dropdown-toggle,.navbar .nav .active>.dropdown-toggle,.navbar .nav .open.active>.dropdown-toggle -{ - background-color: transparent; -} - -.navbar .nav .active>.dropdown-toggle:hover -{ - color: #ffffff; -} - -.navbar .nav.pull-right .dropdown-menu -{ - left: auto; - right: 0; -} - -.navbar .nav.pull-right .dropdown-menu:before -{ - left: auto; - right: 12px; -} - -.navbar .nav.pull-right .dropdown-menu:after -{ - left: auto; - right: 13px; -} - -.breadcrumb -{ - padding: 7px 14px; - margin: 0 0 18px; - background-color: #fbfbfb; - background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5); - background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5)); - background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5); - background-image: -o-linear-gradient(top, #ffffff, #f5f5f5); - background-image: linear-gradient(top, #ffffff, #f5f5f5); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0); - border: 1px solid #ddd; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: inset 0 1px 0 #ffffff; - -moz-box-shadow: inset 0 1px 0 #ffffff; - box-shadow: inset 0 1px 0 #ffffff; -} - -.breadcrumb li -{ - display: inline-block; - text-shadow: 0 1px 0 #ffffff; -} - -.breadcrumb .divider -{ - padding: 0 5px; - color: #999999; -} - -.breadcrumb .active a -{ - color: #333333; -} - -.pagination -{ - height: 36px; - margin: 18px 0; -} - -.pagination ul -{ - display: inline-block; - *display: inline; - *zoom: 1; - margin-left: 0; - margin-bottom: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.pagination li -{ - display: inline; -} - -.pagination a -{ - float: left; - padding: 0 14px; - line-height: 34px; - text-decoration: none; - border: 1px solid #ddd; - border-left-width: 0; -} - -.pagination a:hover,.pagination .active a -{ - background-color: #f5f5f5; -} - -.pagination .active a -{ - color: #999999; - cursor: default; -} - -.pagination .disabled a,.pagination .disabled a:hover -{ - color: #999999; - background-color: transparent; - cursor: default; -} - -.pagination li:first-child a -{ - border-left-width: 1px; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} - -.pagination li:last-child a -{ - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} - -.pagination-centered -{ - text-align: center; -} - -.pagination-right -{ - text-align: right; -} - -.pager -{ - margin-left: 0; - margin-bottom: 18px; - list-style: none; - text-align: center; - *zoom: 1; -} - -.pager:before,.pager:after -{ - display: table; - content: ""; -} - -.pager:after -{ - clear: both; -} - -.pager li -{ - display: inline; -} - -.pager a -{ - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} - -.pager a:hover -{ - text-decoration: none; - background-color: #f5f5f5; -} - -.pager .next a -{ - float: right; -} - -.pager .previous a -{ - float: left; -} - -.modal-open .dropdown-menu -{ - z-index: 2050; -} - -.modal-open .dropdown.open -{ - *z-index: 2050; -} - -.modal-open .popover -{ - z-index: 2060; -} - -.modal-open .tooltip -{ - z-index: 2070; -} - -.modal-backdrop -{ - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000; -} - -.modal-backdrop.fade -{ - opacity: 0; -} - -.modal-backdrop,.modal-backdrop.fade.in -{ - opacity: 0.3; - filter: alpha(opacity=30); -} - -.modal -{ - position: fixed; - top: 50%; - left: 50%; - z-index: 1050; - max-height: 500px; - overflow: auto; - width: 560px; - margin: -250px 0 0 -280px; - background-color: #ffffff; - border: 1px solid #999; - border: 1px solid rgba(0, 0, 0, 0.3); - *border: 1px solid #999; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} - -.modal.loading -{ - height: 200px; - overflow: hidden; -} - -.modal.loading p -{ - font-size: 18px; - font-weight: bold; - text-align: center; - margin: 20px; - color: #999; -} - -.modal.fade -{ - -webkit-transition: opacity .3s linear, top .3s ease-out; - -moz-transition: opacity .3s linear, top .3s ease-out; - -ms-transition: opacity .3s linear, top .3s ease-out; - -o-transition: opacity .3s linear, top .3s ease-out; - transition: opacity .3s linear, top .3s ease-out; - top: -25%; -} - -.modal.fade.in -{ - top: 50%; -} - -.modal-header -{ - padding: 10px 20px; -} - -.modal-header .close -{ - margin-top: 2px; -} - -.modal-body -{ - padding: 10px 20px; - max-height: 300px; - overflow-y:auto; - border-top: 1px #ccc solid; -} - -.modal-body .modal-form -{ - margin-bottom: 0; -} - -.modal-footer -{ - margin-bottom: 0; - background-color: #fff; - *zoom: 1; - padding: 10px 20px; - border-top: 1px #ccc solid; -} - -.modal-footer:before,.modal-footer:after -{ - display: table; - content: ""; -} - -.modal-footer:after -{ - clear: both; -} - -.modal-footer .btn -{ - float: left; - margin-right: 5px; - margin-bottom: 0; -} - -.tooltip -{ - position: absolute; - z-index: 1020; - display: block; - visibility: visible; - padding: 5px; - font-size: 11px; - opacity: 0; - filter: alpha(opacity=0); -} - -.tooltip.in -{ - opacity: 0.8; - filter: alpha(opacity=80); -} - -.tooltip.top -{ - margin-top: -2px; -} - -.tooltip.right -{ - margin-left: 2px; -} - -.tooltip.bottom -{ - margin-top: 2px; -} - -.tooltip.left -{ - margin-left: -2px; -} - -.tooltip.top .tooltip-arrow -{ - bottom: 0; - left: 50%; - margin-left: -5px; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid #000000; -} - -.tooltip.left .tooltip-arrow -{ - top: 50%; - right: 0; - margin-top: -5px; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid #000000; -} - -.tooltip.bottom .tooltip-arrow -{ - top: 0; - left: 50%; - margin-left: -5px; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid #000000; -} - -.tooltip.right .tooltip-arrow -{ - top: 50%; - left: 0; - margin-top: -5px; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-right: 5px solid #000000; -} - -.tooltip-inner -{ - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.tooltip-arrow -{ - position: absolute; - width: 0; - height: 0; -} - -.popover -{ - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - padding: 5px; -} - -.popover.top -{ - margin-top: -5px; -} - -.popover.right -{ - margin-left: 5px; -} - -.popover.bottom -{ - margin-top: 5px; -} - -.popover.left -{ - margin-left: -5px; -} - -.popover.top .arrow -{ - bottom: 0; - left: 50%; - margin-left: -5px; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid #000000; -} - -.popover.right .arrow -{ - top: 50%; - left: 0; - margin-top: -5px; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-right: 5px solid #000000; -} - -.popover.bottom .arrow -{ - top: 0; - left: 50%; - margin-left: -5px; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid #000000; -} - -.popover.left .arrow -{ - top: 50%; - right: 0; - margin-top: -5px; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid #000000; -} - -.popover .arrow -{ - position: absolute; - width: 0; - height: 0; -} - -.popover-inner -{ - padding: 3px; - width: 280px; - overflow: hidden; - background: #000000; - background: rgba(0, 0, 0, 0.8); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); -} - -.popover-title -{ - padding: 9px 15px; - line-height: 1; - background-color: #f5f5f5; - border-bottom: 1px solid #eee; - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} - -.popover-content -{ - padding: 14px; - background-color: #ffffff; - -webkit-border-radius: 0 0 3px 3px; - -moz-border-radius: 0 0 3px 3px; - border-radius: 0 0 3px 3px; - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} - -.popover-content p,.popover-content ul,.popover-content ol -{ - margin-bottom: 0; -} - -.thumbnails -{ - margin-left: -20px; - list-style: none; - *zoom: 1; -} - -.thumbnails:before,.thumbnails:after -{ - display: table; - content: ""; -} - -.thumbnails:after -{ - clear: both; -} - -.thumbnails>li -{ - float: left; - margin: 0 0 18px 20px; -} - -.thumbnail -{ - display: block; - padding: 4px; - line-height: 1; - border: 1px solid #ddd; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); -} - -a.thumbnail:hover -{ - border-color: #0088cc; - -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); -} - -.thumbnail>img -{ - display: block; - max-width: 100%; - margin-left: auto; - margin-right: auto; -} - -.thumbnail .caption -{ - padding: 9px; -} - -.label -{ - padding: 2px 4px 3px; - font-size: 11.049999999999999px; - font-weight: bold; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #999999; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.label:hover -{ - color: #ffffff; - text-decoration: none; -} - -.label-important -{ - background-color: #b94a48; -} - -.label-important:hover -{ - background-color: #953b39; -} - -.label-warning -{ - background-color: #f89406; -} - -.label-warning:hover -{ - background-color: #c67605; -} - -.label-success -{ - background-color: #468847; -} - -.label-success:hover -{ - background-color: #356635; -} - -.label-info -{ - background-color: #3a87ad; -} - -.label-info:hover -{ - background-color: #2d6987; -} - -@-webkit-keyframes progress-bar-stripes -{ - from{background-position: 0 0; -} - -to -{ - background-position: 40px 0; -} - -}@-moz-keyframes progress-bar-stripes -{ - from{background-position: 0 0; -} - -to -{ - background-position: 40px 0; -} - -}@keyframes progress-bar-stripes -{ - from{background-position: 0 0; -} - -to -{ - background-position: 40px 0; -} - -}.progress -{ - overflow: hidden; - height: 18px; - margin-bottom: 18px; - background-color: #f7f7f7; - background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -ms-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); - background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: linear-gradient(top, #f5f5f5, #f9f9f9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0); - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.progress .bar -{ - width: 0%; - height: 18px; - color: #ffffff; - font-size: 12px; - text-align: center; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #0e90d2; - background-image: -moz-linear-gradient(top, #149bdf, #0480be); - background-image: -ms-linear-gradient(top, #149bdf, #0480be); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); - background-image: -webkit-linear-gradient(top, #149bdf, #0480be); - background-image: -o-linear-gradient(top, #149bdf, #0480be); - background-image: linear-gradient(top, #149bdf, #0480be); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0); - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: width 0.6s ease; - -moz-transition: width 0.6s ease; - -ms-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; -} - -.progress-striped .bar -{ - background-color: #62c462; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - -webkit-background-size: 40px 40px; - -moz-background-size: 40px 40px; - -o-background-size: 40px 40px; - background-size: 40px 40px; -} - -.progress.active .bar -{ - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} - -.progress-danger .bar -{ - background-color: #dd514c; - background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); - background-image: linear-gradient(top, #ee5f5b, #c43c35); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); -} - -.progress-danger.progress-striped .bar -{ - background-color: #ee5f5b; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-success .bar -{ - background-color: #5eb95e; - background-image: -moz-linear-gradient(top, #62c462, #57a957); - background-image: -ms-linear-gradient(top, #62c462, #57a957); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); - background-image: -webkit-linear-gradient(top, #62c462, #57a957); - background-image: -o-linear-gradient(top, #62c462, #57a957); - background-image: linear-gradient(top, #62c462, #57a957); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); -} - -.progress-success.progress-striped .bar -{ - background-color: #62c462; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-info .bar -{ - background-color: #4bb1cf; - background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); - background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); - background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); - background-image: -o-linear-gradient(top, #5bc0de, #339bb9); - background-image: linear-gradient(top, #5bc0de, #339bb9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); -} - -.progress-info.progress-striped .bar -{ - background-color: #5bc0de; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.accordion -{ - margin-bottom: 18px; -} - -.accordion-group -{ - margin-bottom: 2px; - border: 1px solid #e5e5e5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.accordion-heading -{ - border-bottom: 0; -} - -.accordion-heading .accordion-toggle -{ - display: block; - padding: 8px 15px; -} - -.accordion-inner -{ - padding: 9px 15px; - border-top: 1px solid #e5e5e5; -} - -.carousel -{ - position: relative; - margin-bottom: 18px; - line-height: 1; -} - -.carousel-inner -{ - overflow: hidden; - width: 100%; - position: relative; -} - -.carousel .item -{ - display: none; - position: relative; - -webkit-transition: 0.6s ease-in-out left; - -moz-transition: 0.6s ease-in-out left; - -ms-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} - -.carousel .item>img -{ - display: block; - line-height: 1; -} - -.carousel .active,.carousel .next,.carousel .prev -{ - display: block; -} - -.carousel .active -{ - left: 0; -} - -.carousel .next,.carousel .prev -{ - position: absolute; - top: 0; - width: 100%; -} - -.carousel .next -{ - left: 100%; -} - -.carousel .prev -{ - left: -100%; -} - -.carousel .next.left,.carousel .prev.right -{ - left: 0; -} - -.carousel .active.left -{ - left: -100%; -} - -.carousel .active.right -{ - left: 100%; -} - -.carousel-control -{ - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: #ffffff; - text-align: center; - background: #222222; - border: 3px solid #ffffff; - -webkit-border-radius: 23px; - -moz-border-radius: 23px; - border-radius: 23px; - opacity: 0.5; - filter: alpha(opacity=50); -} - -.carousel-control.right -{ - left: auto; - right: 15px; -} - -.carousel-control:hover -{ - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} - -.carousel-caption -{ - position: absolute; - left: 0; - right: 0; - bottom: 0; - padding: 10px 15px 5px; - background: #333333; - background: rgba(0, 0, 0, 0.75); -} - -.carousel-caption h4,.carousel-caption p -{ - color: #ffffff; -} - -.hero-unit -{ - padding: 60px; - margin-bottom: 30px; - background-color: #f5f5f5; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.hero-unit h1 -{ - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; -} - -.hero-unit p -{ - font-size: 18px; - font-weight: 200; - line-height: 27px; -} - -.pull-right -{ - float: right; -} - -.pull-left -{ - float: left; -} - -.hide -{ - display: none; -} - -.show -{ - display: block; -} - -.invisible -{ - visibility: hidden; -} - -/* new clearfix */ - -.clearfix:after -{ - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; -} - -* html .clearfix -{ - zoom: 1; -} - -/* IE6 */ - -*:first-child+html .clearfix -{ - zoom: 1; -} - - -a -{ - color: #1d71bf; -} - -ul -{ - list-style: none; - margin: 0; -} - -dt -{ - font-weight: bold; -} - -#main_content -{ - /*padding-left: 250px; - padding-right: 25px;*/ - width: 970px; - padding: 30px; - margin: 0 auto; - background-color: #fff; - border: 1px #ccc solid; - margin-top: 52px; -} - -.topbar -{ - -} - -.topbar .switcher_bar -{ - display: inline-block; - height: auto; - width: 160px; - background-position: 140px center; - margin-bottom: 0; - font-size: 11px; - padding: 0; -} - -.topbar .switcher_bar a -{ - padding: 2px 10px 1px; - margin-left: 0; - display: block; -} - -.topbar .switcher_bar ul -{ - width: 130px; -} - -#user_info -{ - color: #ccc; - margin: auto 0; - margin-top: -170px; -} - -#user_info > a -{ - margin-left: 25px; - font-size: 13px !important; - color: #ccc; -} - -.page-header -{ - margin: 0; - padding: 0; - border: 0; - font-family: Arial,"Helvetica Neue",Helvetica,sans-serif; -} - -h2 -{ - color: #c40022; - font-size: 24px; - font-weight: bold; - margin-bottom: 10px; -} - -body -{ - background-color: #ddd; - min-width: 890px; -} - -/* Login Splash Page */ - -#splash -{ - -} - -#splash .login -{ - padding-left: 290px; - background: #fff url(../img/Rackspace_Cloud_Company.png) no-repeat 49px 135px; - width: 360px; - min-height: 364px; - position: absolute; - top: 50%; - left: 50%; - margin: -192px 0 0 -325px; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.2); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} - -#splash .login .alert -{ - margin-left: 50px; - margin-right: 70px; - padding: 10px; -} - -#splash .login form -{ - border-left: 1px #ddd solid; - padding: 0; -} - -#splash .login .modal-body -{ - padding: 0; - border-top: none; -} - -#splash .login .modal-header -{ - margin-top: 28px; - border-bottom: none; - border-left: 1px #ddd solid; - padding-left: 49px; - padding-top: 45px; - padding-bottom: 20px; -} - -#splash .login .modal-header h3 -{ - font-size: 13px; -} - -#splash .alert-block -{ - margin-left: 48px; - margin-right: 49px; - padding-right: 20px; - padding-left: 6px; -} - -#splash .alert-block .close -{ - right: -10px; - top: 0; -} - -#splash .modal-footer -{ - background-color: #fff; - border-top: none; - padding-bottom: 45px; - margin-bottom: 28px; - padding-left: 45px; -} - -#splash .modal-footer button -{ - cursor: pointer; - margin: 0; - line-height: 20px; - font-size: 13px; - text-align: center; - padding: 1px 10px 2px; - border-radius: 3px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-width: 1px; - border-style: solid; - text-shadow: 0 -1px 1px rgba(0,0,0,0.4); - background-color: #a60004; - border-color: #a60004; - color: #fff; - background: #d81436; - background: -moz-linear-gradient(top,#d81436 0,#a60004 100%); - background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#d81436),color-stop(100%,#a60004)); - background: -webkit-linear-gradient(top,#d81436 0,#a60004 100%); - background: -o-linear-gradient(top,#d81436 0,#a60004 100%); - background: -ms-linear-gradient(top,#d81436 0,#a60004 100%); - background: linear-gradient(top,#d81436 0,#a60004 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#d81436',endColorstr='#a60004',GradientType=0); -} - -#splash .modal-footer button::-moz-focus-inner -{ - border: none; - padding: 0; -} - -#splash .modal-footer button[disabled] -{ - cursor: default; - color: #fff; - background-color: #e9a7b2; - border-color: #e9a7b2; - background-image: none; -} - -#splash .modal-footer button:not([disabled]):hover -{ - background: #d81436; - background: -moz-linear-gradient(top,#d81436 0,#c40022 100%); - background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#d81436),color-stop(100%,#c40022)); - background: -webkit-linear-gradient(top,#d81436 0,#c40022 100%); - background: -o-linear-gradient(top,#d81436 0,#c40022 100%); - background: -ms-linear-gradient(top,#d81436 0,#c40022 100%); - background: linear-gradient(top,#d81436 0,#c40022 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#d81436',endColorstr='#c40022',GradientType=0); -} - -#splash .modal-footer button:not([disabled]):active -{ - background-color: #c40022; - background-image: none; - box-shadow: inset 0 0 4px 0 rgba(0,0,0,0.5); - -moz-box-shadow: inset 0 0 4px 0 rgba(0,0,0,0.5); - -webkit-box-shadow: inset 0 0 4px 0 rgba(0,0,0,0.5); -} - -#splash .modal-footer .pull-right -{ - float: none; -} - - -#splash .login form .control-group -{ - padding-left: 49px; -} - -#splash .login input -{ - width: 244px; -} - - -#splash .help-block -{ - display: none; -} - -#container -{ - background: url(../img/body_bkg.gif) repeat-x 0 0; -} - -.nav li a -{ - text-shadow: none; -} - -.container-fluid -{ - padding-left: 0; -} - -.sidebar -{ - width: 1030px; - margin: 0 auto; -} - -.sidebar h4 -{ -display: none; -} - -.sidebar .nav-tabs -{ - margin: 0; - float: left; - margin-top: 55px; - border-bottom: none; -} - -.sidebar .nav-tabs li -{ - margin-left: 20px; -} - -.sidebar .nav-tabs li a -{ - background-color: transparent; - border: none; - font-weight: bold; - color: #888; - font-size: 14px; - display: inline-block; - padding: 6px 10px; - text-decoration: none; - text-shadow: 0 1px #fff; - margin: 0; - outline: none; -} - -.sidebar .nav-tabs li.active a -{ - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border: 1px #ccc solid; - background-color: #fff; - color: #333; - margin-top: -1px; -} - - - - - -h1.brand -{ - margin: 0; - float: left; - margin-top: 20px; -} - -h1.brand:before { - content: ''; - display: block; - height: 20px; - margin-bottom: -20px; - background-color: #fff; - border-radius: 2px 2px 0 0; - -moz-border-radius: 2px 2px 0 0; - -webkit-border-radius: 2px 2px 0 0; -} - - -h1.brand a -{ - display: block; - float: left; - width: 150px; - height: 46px; - text-indent: -9999px; - position: ; - background: url(../img/Rackspace_Cloud_Company_Small.png) no-repeat center center; - padding: 24px 24px 8px 16px; -} - -/* Tenant Dropdown */ - -a.current_item -{ - width: 163px; - float: left; -} - -a.current_item:hover -{ - text-decoration: none; -} - -a.current_item:hover h3, a.current_item:hover h4 -{ - color: #39738c; -} - -.switcher_bar -{ - width: 226px; - height: 25px; - float: left; - margin-bottom: 0; - font-size: 13px; - line-height: 18px; - color: #333333; - text-align: left; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - vertical-align: middle; - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(top, #ffffff, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #ccc; - border-bottom-color: #bbb; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); - cursor: pointer; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - *margin-left: .3em; - margin-top: 2px; -} - -.switcher_bar:hover -{ - background-image: none; - background-color: #fefefe; - background-image: -moz-linear-gradient(top, #ffffff, #efefef); - background-image: -ms-linear-gradient(top, #ffffff, #efefef); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#efefef)); - background-image: -webkit-linear-gradient(top, #ffffff, #efefef); - background-image: -o-linear-gradient(top, #ffffff, #efefef); - background-image: linear-gradient(top, #ffffff, #efefef); - background-repeat: repeat-x; -} - -a.dropdown-toggle:hover h3 -{ - text-decoration: none; - color: #c41022; -} - -.switcher_bar:focus -{ - outline: none; -} - -.switcher_bar h3 -{ - color: #666; - font-size: 16px; - margin: 0; - padding: 0px 0 0 16px; - text-shadow: 0 1px #fff; - text-align: left; - width: 176px; - overflow: hidden; - border-right: 1px #ccc solid; -} - -.switcher_bar .dropdown-toggle, .switcher_bar .open .dropdown-toggle -{ - text-decoration: none; - background-image: url(../img/drop_arrow.png) !important; - background-color: transparent !important; - background-repeat: no-repeat !important; - background-position: 202px center !important; - width: 100%; - display: inline-block; -} - -.switcher_bar h4 -{ - color: #6fabc4; - font-size: 10px; - text-transform: uppercase; - font-weight: normal; - padding: 0; -} - -.switcher_bar ul -{ - border: 1px solid #ccc; - - width: 224px; - margin-top: 0; - padding-top: 0; - padding-bottom: 10px; -} - -.switcher_bar .dropdown-menu li a -{ - color: #1d71bf; - font-size: 16px !important; - line-height: 26px; - padding-top: 0; - padding-bottom: 0; -} - -.switcher_bar .dropdown-menu li a:hover -{ - text-decoration: underline !important; - background: transparent !important; - color: #1d71bf !important; -} - -#usage -{ - margin-bottom: 25px; - height: 125px; -} - -.usage_block -{ - background: #e8f8ff; - color: #84b6c5; - border: 1px solid #afe3fb; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - float: left; - width: 29%; - margin-right: 5%; - min-height: 125px; -} - -.usage_block.last -{ - margin-right: 0; -} - -.usage_block h3 -{ - background: #cef0ff; - color: #4fa5bf; - font-weight: normal; - padding: 0 0 0 10px; - border-bottom: 1px solid #c6e7f5; - -webkit-border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topleft: 5px; - -moz-border-radius-topright: 5px; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - -.usage_block ul -{ - margin: 10px; -} - -.usage_block .quantity -{ - font-size: 25px; -} - -.usage_block li -{ - font-size: 11px; - margin: 0 0 15px 0; -} - -.usage_block .unit -{ - font-size: 11px; - text-transform: uppercase; - padding: 0 0 0 1px; -} - -.table-bordered -{ - border: none; -} - -.table_header -{ - min-height: 35px; - padding: 0 !important; -} - -.table_caption th -{ - background-color: transparent; - border: none; -} - -.table-bordered tr.table_caption + tr th -{ - border-top: 1px solid #ddd; -} - -.table-bordered tr.table_caption + tr th:first-child, -.table-bordered tr.table_caption + tr th.hide + th -{ - border-left: 1px solid #ddd; -} - -.table-bordered tr.table_caption + tr th:last-child -{ - border-right: 1px solid #ddd; -} - -.table-bordered tbody tr td:first-child, -.table-bordered tfoot tr td:first-child -{ - border-left: 1px solid #ddd !important; -} - -.table-bordered tbody tr td:last-child, -.table-bordered tfoot tr td:last-child -{ - border-right: 1px solid #ddd; -} - -.table-bordered tfoot tr td:first-child -{ - border-bottom: 1px solid #ddd; -} - -.table-bordered tfoot tr td:last-child -{ - border-bottom: 1px solid #ddd; -} - -.table_title h3, .table_header h3 -{ - color: #333; - font-size: 18px; - font-weight: bold; - margin-bottom: 5px; - float: left; -} - -th -{ - background: #f1f1f1; -} - -small -{ - font-size: 11px; -} - -.main_nav -{ - list-style: none; - float: left; - margin: 0; - padding-left: 10px; - height: 30px; -} - -.main_nav a -{ - color: #888; - font-size: 13px; - font-weight: bold; - float: left; - padding: 7px 20px; - outline: none; - text-shadow: 0 1px #fff; -} - -.main_nav a:hover -{ - text-decoration: none; - color: #c41022; -} - -.main_nav li -{ - float: left; -} - -.main_nav a.active -{ - background: url(../img/selected_arrow.png) no-repeat center bottom; -} - -table form -{ - margin-bottom: 0; - width: 1px; -} - -.alert-block .alert-actions -{ - margin-top: -23px; - margin-right: -23px; -} - -.modal > form, -.login > form, -.alert-actions > form -{ - margin-bottom: 0; -} - -.alert-block p -{ - overflow: hidden; - word-wrap: break-word; -} - -.alert-block p:last-child -{ - margin-bottom: 0; -} - -#actions.single -{ - width: 90px; -} - -.table-striped tr td -{ - transition: background 0.2s; - -webkit-transition: background 0.2s; - -moz-transition: background 0.2s; - -o-transition: background 0.2s; -} - -.inspect -{ - float: left; - display: block; - margin-top: 5px; - margin-right: 25px; -} - -.table -{ - margin-bottom: 0px; - margin-top: 30px; -} - -.table tr td -{ - vertical-align: middle; -} - -.table tr.empty td -{ - text-align: center; -} - -.table tfoot tr td -{ - border-top: 1px solid #DDD; - font-size: 13px; - line-height: 20px; - padding: 2px 10px; - color: #aaa; -} - -.table_actions -{ - float: right; - min-width: 400px; - margin-bottom: 10px; -} - -.table_actions .table_search -{ - display: inline-block; -} - -.table_search input -{ - background: url(../img/search.png) no-repeat 190px 5px; - display: inline-block; - margin-bottom: 0; -} - -.table_actions a, .table_actions button -{ - float: right; - margin-left: 10px; -} - -.table_actions button.filter -{ - margin-left: 0; -} - -.table_header .table_actions -{ - min-width: 0; -} - -.table_header .table_actions a, .table_header .table_actions button -{ - display: inline-block; - float: none; -} - -.table_actions form -{ - float: right; - margin-left: 10px; -} - -.hidden -{ - display: none; -} - -.table-striped tbody tr.status_unknown:nth-child(odd) td -{ - background-color: #ffffb5; -} - -.table-striped tbody tr.status_unknown:nth-child(even) td -{ - background-color: #ffffc6; -} - -tbody .nowrap-col -{ - white-space: nowrap; - max-width: 100px; - overflow: hidden; - text-overflow: ellipsis; - cursor: default; -} - -tbody .nowrap-col:hover -{ - overflow: visible; - max-width: none; - background-color: #eee !important; -} - -.icon-updating.ajax-updating -{ - background: transparent url(../img/spinner.gif) no-repeat center center; - padding: 1px; -} - -td .icon-updating.ajax-updating -{ - margin-right: 5px; -} - -.overview -{ - font-size: 24px; -} - -#monitoring -{ - background: #f8f8f8; - font-size: 14px; - height: 20px; - margin: -18px 0 25px; - padding: 10px; - border: 1px solid #e1e1e1; - font-family: "anivers"; -} - -#monitoring h3 -{ - font-size: 14px; - font-weight: normal; - float: left; - line-height: 18px; -} - -#external_links, #external_links li -{ - float: left; -} - -#external_links li -{ - margin: 0 0 0 15px; -} - -/* Forms */ - -form label -{ - text-align: left; - color: #333; -} - -.modal -{ - max-height: none; - /* Prevents large modals from scrolling unnecessarily */ - top: 80px; - margin-top: 0; - position: absolute; - width: auto; - width: 560px -} - - -form.horizontal .form-field -{ - float: left; -} - -form.horizontal.split_half .form-field -{ - width: 334px; -/* - -Fits 2 fields to a row */ -} - -form.horizontal.split_quarter .form-field -{ - width: 167px; -/* - -Fits 4 fields to a row */ -} - -form.horizontal.split_five .form-field -{ - width: 133px; -/* - -Fits 5 fields to a row */ -} - -form.horizontal fieldset -{ - width: 100%; -} - -.modal-body table td -{ - vertical-align: top; -} - -.modal-body ~ hr -{ - margin-bottom: 0; -} - -.static_page -{ - width: 700px; - background-color: #FFF; - border: 1px solid #DDD; -} - -.static_page > form -{ - margin-bottom: 0; -} - -.left -{ - float: left; - width: 347px; - margin-right: 15px; -} - -.left form -{ - margin: 0; -} - -.right -{ - float: left; - width: 308px; -} - -.clear -{ - clear: both; - width: 0; - height: 0; - padding: 0; - margin: 0; -} - -.modal-body fieldset -{ - margin: 0; - padding: 0; -} - -.modal-body fieldset ul -{ - width: 90%; -} - -.modal-body .left, .modal-body .right -{ - float: left; - width: 48%; - margin: 0; - margin-right: 1%; -} - - - -.modal-body fieldset .form-field input, -.modal-body fieldset .form-field select, -.modal-body fieldset .form-field textarea -{ - width: 90%; -} - -.modal-footer input -{ - width: auto; -} - -.modal-body .modal-footer -{ - width: 670px; - margin-left: -25px; - margin-right: -15px; -} - -.modal-footer a.close -{ - margin-top: 0; - margin-right: 5px; - font-size: 12px; - color: #666; - font-weight: normal; - filter: alpha(opacity=100); - -khtml-opacity: 1; - -moz-opacity: 1; - opacity: 1; - float: left; -} - -.modal-footer .pull-right -{ - float: left; -} - -.modal-footer a.close:hover -{ - color: #333; - text-decoration: underline; -} - -.modal-body .help-block -{ - text-align: left; - float: left; - width: 100%; - margin-bottom: 10px; -} - -#create_keypair_modal .clearfix -{ - margin-bottom: 115px; -} - -#actions -{ - width: 90px; -} - -#actions .btn -{ - margin-bottom: 5px; -} - -#actions a.btn -{ - width: 70px; -} - -#actions input.btn -{ - text-align: left; -} - -#images #actions -{ - width: 100px; -} - -/*New List Patches*/ - -.details-modal .modal-body -{ - padding-bottom: 20px; -} - -.form-inline -{ - display: inline; -} - -td.select -{ - width: 10px; -} - -/* Actions dropdown */ - -td.actions_column -{ - padding: 10px; - position: relative; - min-width: 115px; - min-height: 20px; -} - -td.actions_column .row_actions a, -td.actions_column .row_actions input, -td.actions_column .row_actions button -{ - background: none; - float: none; - display: block; - padding: 5px 10px; - color: #1d71bf; - text-align: left; - border-radius: 0; - border: 0 none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - font-size: 13px; -} - -td.actions_column .row_actions .hide -{ - display: none; -} - -/* Makes size consistent across browsers when mixing "btn-group" and "small" */ - -.btn.hide, .btn-group .hide -{ - display: none; -} - -.btn-group .dropdown-toggle:focus -{ - outline: none; -} - -.dropdown-menu button -{ - line-height: 18px; - - -/* Matches rule for ".dropdown-menu a" in bootstrap */ - width: 100%; -} - -.btn-group .dropdown-menu .btn -{ - border-radius: 0; -} - -.dropdown-menu .btn.btn-danger, -.dropdown-menu .btn.btn-danger:hover, -.dropdown-menu .btn.btn-success, -.dropdown-menu .btn.btn-success:hover, -.dropdown-menu .btn.btn-info, -.dropdown-menu .btn.btn-info:hover -{ - text-shadow: none; -/ - -* remove default bootstrap shadowing from button text. */ -} - -.dropdown-menu li.divider -{ - margin-bottom: 10px; - margin-top: 0; -} - -.dropdown-menu li:hover -{ - background: none; -} - -.dropdown-menu li.divider:hover -{ - background-color: #E5E5E5; -} - -td.actions_column .dropdown-menu a:hover, -td.actions_column .dropdown-menu button:hover -{ - text-decoration: underline; -} - -.dropdown-menu .btn.btn-danger -{ - color: #C43C35; -} - -.dropdown-menu .btn.btn-danger:hover -{ -} - -/* Overrides for single-action rows (no dropdown) */ - -tr td.actions_column ul.row_actions.single, -tr:hover td.actions_column ul.row_actions.single, -td.actions_column ul.row_actions.single, -td.actions_column ul.row_actions.single:hover -{ - border: none; -} - -td.actions_column ul.row_actions.single li.action -{ - display: block; -} - -td.actions_column ul.row_actions.single li.action:hover -{ - background-color: transparent; -} - -td.actions_column ul.row_actions.single a, -td.actions_column ul.row_actions.single input, -td.actions_column ul.row_actions.single button -{ - color: #43a1d6; -} - -td.actions_column ul.row_actions.single a:hover, -td.actions_column ul.row_actions.single input:hover, -td.actions_column ul.row_actions.single button:hover -{ - color: black; -} - -th.multi_select_column, td.multi_select_column -{ - -} - -th.multi_select_column, td.multi_select_column -{ - text-align: center; -} - -.table input[type="checkbox"] -{ - display: inline; -} - -div.input input[type="checkbox"] -{ - float: left; - width: 25px; -} - -.table_title a -{ - font-size: 11px; - float: right; - margin-left: 10px; - margin-top: 10px; -} - -tr.terminated -{ - color: #999999; -} - -#instance_tabs -{ - float: left; - width: 100%; - border-bottom: 1px solid #e1e1e1; -} - -#instance_tabs li a -{ - background: #f2f2f2; - display: block; - font-size: 14px; - float: left; - padding: 5px 10px; - margin-right: 10px; - border: 1px solid #e1e1e1; - border-bottom: none; -} - -#instance_tabs li.active a -{ - background: #fff; - padding-bottom: 8px; - margin-bottom: -5px; -} - -#main_content .nav-tabs -{ - margin-bottom: 0; -} - -#main_content .tab-content -{ - border: 1px solid #ddd; - border-top: 0 none; - padding: 30px; -} - -.tab_wrapper -{ - padding-top: 50px; -} - -/* Fix tooltip z-index to show above modals. Bootstrap bug 582*/ - -.tooltip -{ - z-index: 12000; -} - -.volume_boot_disclosure -{ - font-weight: bold; - color: #555; - cursor: pointer; - background-image: url(../img/right_droparrow.png); - background-repeat: no-repeat; - background-position: 130px center; -} - -.volume_boot_disclosure.on -{ - width: 334px; - margin-bottom: 10px; - border-bottom: solid 1px #E1E1E1; - background-image: url(../img/drop_arrow.png); -} - -#splash form div.clearfix.error -{ - width: 254px; -} - -/* Region selector in header */ - -#region_selector -{ - position: absolute; - z-index: 9999; - right: 0; - top: 24px; -} - -#region_selector a -{ - margin-left: 0; -} - -#region_selector ul -{ - float: left; - margin-left: 5px; - padding-right: 21px; - width: 125px; -} - -#region_selector ul:hover a -{ - display: block; -} - -#region_selector li a -{ - padding: 3px 3px 3px 5px; - display: none; - background: #E1E1E1; - margin-top: -10px; -} - -#region_selector li:first-child p -{ - background: #EDEDED url(../img/drop_arrow.png) no-repeat 106px 9px !important; - display: block; - border: 1px solid #e1e1e1; - padding: 5px; -} - -iframe -{ - border: none; -} - -.item_detail ul li label -{ - color: #000; - font-weight: bold; - display: block; - margin-top: 5px; -} - -.progress_bar -{ - width: 100%; - height: 15px; - border: 1px solid #ddd; - background-color: #efefef; -} - -.progress_bar_fill -{ - height: 100%; - background-color: #006dcc; - background-image: -moz-linear-gradient(top, #0088cc, #0044cc); - background-image: -ms-linear-gradient(top, #0088cc, #0044cc); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); - background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); - background-image: -o-linear-gradient(top, #0088cc, #0044cc); - background-image: linear-gradient(top, #0088cc, #0044cc); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); -} - -.quota_title -{ - color: #999; -} - -.quota_title strong -{ - color: #000; -} - -.quota_title strong span -{ - font-weight: normal; -} - -.quota_title p -{ - float: right; -} - -.quota_bar -{ - height: 15px; - margin: -5px 0 20px; -} - -#main_content .row-fluid -{ - margin: 0px; - -} - - -#main_content .tab-content .row-fluid h4 -{ - border-top: 1px solid #ccc; - color: #333; - font-size: 18px; - font-weight: bold; - margin-right: -30px; - margin-left: -30px; - padding-top: 20px; - padding-left: 30px; - margin-top: 0px; -} - -#main_content h3 -{ - margin-bottom: 20px; -} - -#main_content .row-fluid:last-child -{ - margin-bottom: 0; -} - -#main_content dt -{ - position: absolute; - width: 150px; - text-align: right; - line-height: 30px; - color: #999; - font-weight: normal; -} - -#main_content dd -{ - margin-left: 170px; - line-height: 30px; - color: #333; -} - -#main_content dd li -{ - line-height: 30px; -} - -.header_rule -{ - display: none; -} - -.item_detail .detail_section -{ - margin-bottom: 25px; - float: left; - margin-right: 50px; -} - -.error .help-inline -{ - display: block; - background: url(../img/alert_red.png) no-repeat 0 center; - padding-left: 20px; -} - -label.log-length -{ - line-height: 28px; - margin-right: 10px; -} - -.split_five div.control-group input[type="text"], -.split_five div.control-group select -{ - width: 120px; -} - -.form-row -{ - -} - -#activity -{ - padding: 10px 10px 0; - border: 1px #e6e6e6 solid; - margin-top: 20px; -} - -#activity span -{ - display: block; - margin-bottom: 10px; -} - -#activity span strong -{ - float: left; - width: 200px; - text-align: right; - margin-right: 20px; - font-weight: normal; - color: #999; -} - -.fake_table -{ - border: 1px #ccc solid; - margin: 0; -} - -.fake_table ul -{ - margin: 0 !important; - padding: 0; - width: 100% !important; -} - -.fake_table.fake_table_header -{ - padding: 5px 10px; - background-color: #eee; - border-bottom: none; -} - -.fake_table ul li .user_name -{ - float: left; - padding: 7px; - width: 90px; - overflow: hidden; -} - -.fake_table ul .active -{ - float: right; - padding: 2px; -} - -.fake_table ul .active .btn -{ - padding: 4px 8px; -} - -.fake_table .dropdown-menu li -{ - color: #006ec5; - line-height: 20px; - padding: 2px 10px; - cursor: pointer; -} - -.fake_table .dropdown-menu li:hover -{ - text-decoration: underline; -} - -.fake_table .dark_stripe -{ - background-color: #EFEFEF; -} - -.project_membership .header .help_text -{ - margin: 10px 0px; -} - -.no_results -{ - padding: 5px !important; -} diff --git a/files/default/horizon.key b/files/default/horizon.key deleted file mode 100644 index 22609cb..0000000 --- a/files/default/horizon.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAw9dXolAH4h0XFzlhcjU0+UHIdwMw85u+CPDyhoeUPJTd/Qjz -2OYSe1Q/ctvz2ufod2jI/XbSmUhIK8blBDAvKIoDz+Q3wXc9a042RJB+0GDIQfMb -C++9WeHkSr+DxTm69lMi1LngWPsKP9jN9AtUcDhT9PCellYsr8Jct1M4SB8yEETa -8p+qgUIoddzPVAHaAJw26Qm3B1RRLFsR95t4IdXhnemCrMXLyI/0CESllKpt+509 -wGVDTdi/A2uk7o1jfoU5Y7huWo0IK0Fmym4x3QwIyLU2TSXScFoiCZ17WmaVtmo+ -pARb2CVCTPm1bjWKmUmu4IRzjxGLm77UWag2kQIDAQABAoIBAEKrwerBAh4JNz4x -y6nc0T72FS/nBzg30hcrJ/WCnIWPTI+DB7jUgoA36y3IEZl5j9tu8dXQKNwEDoXQ -vVCSsstDSQ7yK8USOfeY9cKbyoBYInTJNXD32eeKjnSgBFUVVT/ch6QR7317YT7h -KSQm40Uc+AAQFn0psybWrUe/7g4m78ViJgh1SdFmjxjo1tvCb4zq1TJ6Kcbfd4Ou -1dus5+NFdMDIJKghMuFuceWEWITo5HIKR+GUZKghqU2SIx89NiWXWPN4eFRWywKM -1TEiaUFea3Twp6vpyU5VGAFnmGKwxVfMnaB9owSwsTyFQtMI9xv7MyjEKWPlNt5T -K1J+SJECgYEA8HiHEt1EoyUh7sCDQbOWaoD53PPPfiK1nmpds/cE+grFYBmXeg8/ -yxUldu4YKix8R3OP/zkHcUWCtqoQyXLjmwR76awCNfKVR49jk3BPxDZaFq65KGVa -sad6nL3wktczMyXYduLq6mBW2s0raSOzDPXNUKA68SMvEuktZDxlIU0CgYEA0Hz+ -+RUlNjZiDvY2xxgF38rJGSvXHfOIlUdoQRfQdBsE5M/AtVgeLzW5amlJCnPPcz+b -ZgZBjo74YCKbTL18lPuhn+mhi9NRkW9Eq+SMNWhHhl3RjAjMo+AmTQg2QaEIIIY+ -QUah9PsngIKuHtmYTS8QwBpoQidsQYMZXWpQyFUCgYACTPTl3k4QzYMkmJzo3QH8 -ZN1/GqoKh+R67oOU/DEE/2NiBvynA0xV8g7Ys3Bxvtk1icp/45jJoaOdgcUFWF8L -FaDl3Gps/7Qj6iBGwdVRiD+WZfeJhma2umZ2525MyVhJDfyjLoqW0XMjRsE6kUfe -QN/E/LNzqSWDJc30XouNJQKBgGyesrhSq/BypOPmouNXQLg3jk3u6URRfPdJHKfN -IG1dJk+PbXcNUayG8PLfp44qiAojOXMOD1mWYxCy9vYkQqPb9Xi6389ZaUW8Eqr7 -h5DLo3f9qQ6sBvHZ9hpsDNhkbTeEuSqJAhgAQbRSYSTxeMe9nZx4JZlRsLTw+GYS -3cOBAoGAI1wTP0/OhYUbpxkqvP4gqvEiveaSwSAcackoIRTAwDPDXEDjwToAkGKZ -F+/izeSPdMvYPcm3JKjsgfArjsvLJ+4jIoSLQNMzr0VLHstxsyJ7pCddesem8o3R -CgE0Yfkw93N6enWr3U+IVff9COwEce+WwEzJdNBVP/r6c+DaJWY= ------END RSA PRIVATE KEY----- diff --git a/files/default/horizon.pem b/files/default/horizon.pem deleted file mode 100644 index 4d1b7b6..0000000 --- a/files/default/horizon.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICvjCCAaYCCQCnQkgewKj1UTANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZj -b250cm9sbGVyLmV4YW1wbGUuY29tMB4XDTE1MDUwNjAyMDUzN1oXDTI1MDUwMzAy -MDUzN1owITEfMB0GA1UEAwwWY29udHJvbGxlci5leGFtcGxlLmNvbTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMPXV6JQB+IdFxc5YXI1NPlByHcDMPOb -vgjw8oaHlDyU3f0I89jmEntUP3Lb89rn6HdoyP120plISCvG5QQwLyiKA8/kN8F3 -PWtONkSQftBgyEHzGwvvvVnh5Eq/g8U5uvZTItS54Fj7Cj/YzfQLVHA4U/TwnpZW -LK/CXLdTOEgfMhBE2vKfqoFCKHXcz1QB2gCcNukJtwdUUSxbEfebeCHV4Z3pgqzF -y8iP9AhEpZSqbfudPcBlQ03YvwNrpO6NY36FOWO4blqNCCtBZspuMd0MCMi1Nk0l -0nBaIgmde1pmlbZqPqQEW9glQkz5tW41iplJruCEc48Ri5u+1FmoNpECAwEAATAN -BgkqhkiG9w0BAQsFAAOCAQEAs38vH/ZxpdrvOFB5A3+/hXK6u7PHMKNgZRbE5jZv -j4HdTPLR+rQmI+Mrwu22N3ng0Nmhkl8GHvp5bQi+9KXAssCaSLjJaKMaDc6l1pRR -uQxvXA/dj9DsPmSsxzG2bL2uYO1cgUK4NmpwXkn3aaW1l/VTPntQOjs+4n6MWiJs -dX7CRY8rncH/PxDtmSUz/HiWLTIoOv26tGg56hEEWod0A2UiWqV11AJY/XvZaTs0 -DcyyIS2L5eFjOvLdx8pN8XcNRfgXX4Zor5f1uMUwFHzGecDnuQF+LxN7r5j/CFNu -bvQlWJpu3FeJPccQpyBRK5VCuKUeLVun3Mym33D7B5VFRg== ------END CERTIFICATE----- diff --git a/metadata.rb b/metadata.rb deleted file mode 100644 index 71f3624..0000000 --- a/metadata.rb +++ /dev/null @@ -1,18 +0,0 @@ -name 'openstack-dashboard' -maintainer 'openstack-chef' -maintainer_email 'openstack-discuss@lists.openstack.org' -license 'Apache-2.0' -description 'Installs/Configures the OpenStack Dashboard (Horizon)' -version '20.0.0' - -%w(ubuntu redhat centos).each do |os| - supports os -end - -depends 'apache2', '~> 8.6' -depends 'openstack-common', '>= 20.0.0' -depends 'openstack-identity', '>= 20.0.0' - -issues_url 'https://launchpad.net/openstack-chef' -source_url 'https://opendev.org/openstack/cookbook-openstack-dashboard' -chef_version '>= 16.0' diff --git a/recipes/apache2-server.rb b/recipes/apache2-server.rb deleted file mode 100644 index f301596..0000000 --- a/recipes/apache2-server.rb +++ /dev/null @@ -1,184 +0,0 @@ -# -# Cookbook:: openstack-dashboard -# Recipe:: apache2-server -# -# Copyright:: 2012-2021, Rackspace US, Inc. -# Copyright:: 2012-2021, AT&T Services, Inc. -# Copyright:: 2013-2021, IBM, Corp. -# Copyright:: 2014-2021, SUSE Linux, GmbH. -# Copyright:: 2014-2021, x-ion GmbH. -# Copyright:: 2016-2021, Oregon State University -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -class ::Chef::Recipe - include ::Openstack - include Apache2::Cookbook::Helpers -end - -http_bind = node['openstack']['bind_service']['dashboard_http'] -http_bind_address = bind_address http_bind -https_bind = node['openstack']['bind_service']['dashboard_https'] -https_bind_address = bind_address https_bind - -# service['apache2'] is defined in the apache2_default_install resource -# but other resources are currently unable to reference it. To work -# around this issue, define the following helper in your cookbook: -service 'apache2' do - extend Apache2::Cookbook::Helpers - service_name lazy { apache_platform_service_name } - supports restart: true, status: true, reload: true - action :nothing -end - -# Finds and appends the listen port to the apache2_install[openstack] -# resource which is defined in openstack-identity::server-apache. -apache_resource = find_resource(:apache2_install, 'openstack') - -apache_port = - if node['openstack']['dashboard']['use_ssl'] - ["#{http_bind_address}:#{http_bind['port']}", "#{https_bind_address}:#{https_bind['port']}"] - else - "#{http_bind_address}:#{http_bind['port']}" - end - -if apache_resource - apache_resource.listen = [apache_resource.listen, apache_port].flatten -else - apache2_install 'openstack' do - listen apache_port - end -end - -apache2_mod_wsgi 'dashboard' -apache2_module 'rewrite' -apache2_module 'headers' -apache2_module 'ssl' if node['openstack']['dashboard']['use_ssl'] - -# delete the openstack-dashboard.conf before reload apache2 service on redhat and centos -# since this file is not valid on those platforms for the apache2 service. -file "#{apache_dir}/conf.d/openstack-dashboard.conf" do - action :delete - backup false - only_if { platform_family?('rhel') } # :pragma-foodcritic: ~FC024 - won't fix this -end - -if node['openstack']['dashboard']['ssl']['use_data_bag'] - ssl_cert = secret('certs', node['openstack']['dashboard']['ssl']['cert']) - ssl_key = secret('certs', node['openstack']['dashboard']['ssl']['key']) - if node['openstack']['dashboard']['ssl']['chain'] - ssl_chain = secret('certs', node['openstack']['dashboard']['ssl']['chain']) - end -end -ssl_cert_file = - File.join(node['openstack']['dashboard']['ssl']['cert_dir'], node['openstack']['dashboard']['ssl']['cert']) -ssl_key_file = - File.join(node['openstack']['dashboard']['ssl']['key_dir'], node['openstack']['dashboard']['ssl']['key']) -ssl_chain_file = - if node['openstack']['dashboard']['ssl']['chain'] - File.join(node['openstack']['dashboard']['ssl']['cert_dir'], node['openstack']['dashboard']['ssl']['chain']) - end - -if node['openstack']['dashboard']['use_ssl'] && - node['openstack']['dashboard']['ssl']['use_data_bag'] - unless ssl_cert_file == ssl_key_file - cert_mode = '644' - cert_owner = 'root' - cert_group = 'root' - - file ssl_cert_file do - content ssl_cert - mode cert_mode - owner cert_owner - group cert_group - end - end - - if ssl_chain_file - cert_mode = '644' - cert_owner = 'root' - cert_group = 'root' - - file ssl_chain_file do - content ssl_chain - mode cert_mode - owner cert_owner - group cert_group - end - end - - key_mode = '640' - key_owner = 'root' - key_group = node['openstack']['dashboard']['key_group'] - - file ssl_key_file do - content ssl_key - mode key_mode - owner key_owner - group key_group - end -end - -# make sure this file has correct permission -file node['openstack']['dashboard']['secret_key_path'] do - owner node['openstack']['dashboard']['horizon_user'] - group node['openstack']['dashboard']['horizon_group'] - mode '600' - # the only time the file should be created is if we have secret_key_content - # set, otherwise let apache create it when someone first accesses the - # dashboard - if node['openstack']['dashboard']['secret_key_content'].nil? - only_if { ::File.exist?(node['openstack']['dashboard']['secret_key_path']) } - else - content node['openstack']['dashboard']['secret_key_content'] - notifies :restart, 'service[apache2]' - end -end - -# stop apache bitching -directory "#{node['openstack']['dashboard']['dash_path']}/.blackhole" do - owner 'root' -end - -template "#{apache_dir}/sites-available/openstack-dashboard.conf" do - extend Apache2::Cookbook::Helpers - source 'dash-site.erb' - variables( - apache_admin: node['openstack']['dashboard']['server_admin'], - log_dir: default_log_dir, - ssl_cert_file: ssl_cert_file.to_s, - ssl_key_file: ssl_key_file.to_s, - ssl_chain_file: ssl_chain_file.to_s, - http_bind_address: http_bind_address, - http_bind_port: http_bind['port'].to_i, - https_bind_address: https_bind_address, - https_bind_port: https_bind['port'].to_i - ) - notifies :reload, 'service[apache2]', :immediately -end - -case node['platform_family'] -when 'debian' - apache2_site '000-default' do - action :disable - end -when 'rhel' - apache2_site 'default' do - action :disable - end -end - -apache2_site 'openstack-dashboard' do - notifies :reload, 'service[apache2]', :immediately -end diff --git a/recipes/horizon.rb b/recipes/horizon.rb deleted file mode 100644 index 0a4afe5..0000000 --- a/recipes/horizon.rb +++ /dev/null @@ -1,122 +0,0 @@ -# -# Cookbook:: openstack-dashboard -# Recipe:: horizon -# -# Copyright:: 2012-2021, Rackspace US, Inc. -# Copyright:: 2012-2021, AT&T Services, Inc. -# Copyright:: 2013-2021, IBM, Corp. -# Copyright:: 2014-2021, SUSE Linux, GmbH. -# Copyright:: 2014-2021, x-ion, GmbH. -# Copyright:: 2019-2021, Oregon State University -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -class ::Chef::Recipe - include ::Openstack -end - -platform_options = node['openstack']['dashboard']['platform'] - -identity_endpoint = internal_endpoint 'identity' -auth_url = identity_endpoint.to_s - -http_bind = node['openstack']['bind_service']['dashboard_http'] -http_bind_address = bind_address http_bind -https_bind = node['openstack']['bind_service']['dashboard_https'] -https_bind_address = bind_address https_bind - -horizon_host = - if node['openstack']['dashboard']['use_ssl'] - https_bind_address - else - http_bind_address - end - -db_pass = get_password 'db', 'horizon' -db_info = db 'dashboard' - -python_packages = node['openstack']['db']['python_packages'][db_info['service_type']] -# Add dashboard specific database packages -python_packages += Array(node['openstack']['dashboard']['db_python_packages'][db_info['service_type']]) -package platform_options['horizon_packages'] + python_packages do - action :upgrade - options platform_options['package_overrides'] -end - -if node['openstack']['dashboard']['session_backend'] == 'memcached' - platform_options['memcache_python_packages'].each do |pkg| - package pkg - end -end - -django_path = node['openstack']['dashboard']['django_path'] -memcached = memcached_servers - -template node['openstack']['dashboard']['local_settings_path'] do - source 'local_settings.py.erb' - owner 'root' - group node['openstack']['dashboard']['horizon_group'] - mode '640' - sensitive true - - variables( - db_pass: db_pass, - db_info: db_info, - auth_url: auth_url, - memcached_servers: memcached, - host: horizon_host - ) - - notifies :restart, 'service[apache2]', :delayed -end - -execute 'openstack-dashboard syncdb' do - cwd django_path - environment 'PYTHONPATH' => "/etc/openstack-dashboard:#{django_path}:$PYTHONPATH" - command 'python manage.py syncdb --noinput' - action :run - only_if do - (node['openstack']['dashboard']['session_backend'] == 'sql' && - node['openstack']['db']['dashboard']['migrate'] || - db_info['service_type'] == 'sqlite') - end -end - -directory node['openstack']['dashboard']['dash_state_path'] do - owner 'root' - group node['openstack']['dashboard']['horizon_group'] - mode '2771' -end - -# resource can be triggered from other recipes (e.g. in -# recipes/neutron-lbaas-dashboard.rb) -execute 'openstack-dashboard collectstatic' do - cwd django_path - environment 'PYTHONPATH' => "/etc/openstack-dashboard:#{django_path}:$PYTHONPATH" - command 'python manage.py collectstatic --noinput' - action :nothing -end - -# workaround for -# https://bugs.launchpad.net/openstack-chef/+bug/1496158 -secret_file = node['openstack']['dashboard']['secret_key_path'] -file secret_file do - owner node['openstack']['dashboard']['horizon_user'] - group node['openstack']['dashboard']['horizon_user'] - mode '600' - subscribes :create, 'service[apache2]', :immediately - only_if { ::File.exist?(secret_file) } -end - -include_recipe 'openstack-dashboard::apache2-server' diff --git a/recipes/neutron-lbaas-dashboard.rb b/recipes/neutron-lbaas-dashboard.rb deleted file mode 100644 index 124a8f9..0000000 --- a/recipes/neutron-lbaas-dashboard.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# Cookbook:: openstack-dashboard -# Recipe:: neutron-lbaas-dashboard -# -# Copyright:: 2020-2021, Oregon State University -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -include_recipe 'openstack-dashboard::horizon' - -case node['platform_family'] -when 'debian' - package 'python3-neutron-lbaas-dashboard' -when 'rhel' - package 'openstack-neutron-lbaas-ui' -end diff --git a/spec/apache2-server-redhat_spec.rb b/spec/apache2-server-redhat_spec.rb deleted file mode 100644 index 6bb03bc..0000000 --- a/spec/apache2-server-redhat_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require_relative 'spec_helper' - -describe 'openstack-dashboard::apache2-server' do - ALL_RHEL.each do |p| - context "redhat #{p[:version]}" do - let(:runner) { ChefSpec::SoloRunner.new(p) } - let(:node) { runner.node } - cached(:chef_run) do - runner.converge(described_recipe) - end - include_context 'dashboard_stubs' - include_context 'redhat_stubs' - - describe 'certs' do - describe 'get secret' do - let(:pem) { chef_run.file('/etc/pki/tls/certs/horizon.pem') } - let(:key) { chef_run.file('/etc/pki/tls/private/horizon.key') } - - it 'create files and restarts apache' do - expect(chef_run).to create_file('/etc/pki/tls/certs/horizon.pem').with( - user: 'root', - group: 'root', - mode: '644' - ) - expect(chef_run).to create_file('/etc/pki/tls/private/horizon.key').with( - user: 'root', - group: 'root', - mode: '640' - ) - end - - context 'does not mess with certs if ssl not enabled' do - cached(:chef_run) do - node.override['openstack']['dashboard']['use_ssl'] = false - runner.converge(described_recipe) - end - it do - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.pem') - expect(chef_run).not_to create_file('/etc/pki/tls/private/horizon.key') - end - end - end - end - it 'deletes openstack-dashboard.conf' do - file = '/etc/httpd/conf.d/openstack-dashboard.conf' - expect(chef_run).to delete_file(file) - end - - it do - expect(chef_run).to_not disable_apache2_site('000-default') - end - - it do - expect(chef_run).to disable_apache2_site('default') - end - - it 'sets the WSGI daemon user to attribute default' do - file = chef_run.template('/etc/httpd/sites-available/openstack-dashboard.conf') - expect(chef_run).to render_file(file.name).with_content('WSGIDaemonProcess dashboard user=apache') - end - - it 'has correct ownership on file with attribute defaults' do - file = chef_run.file('/usr/share/openstack-dashboard/openstack_dashboard/local/.secret_key_store') - expect(file.owner).to eq('apache') - expect(file.group).to eq('apache') - end - end - end -end diff --git a/spec/apache2-server_spec.rb b/spec/apache2-server_spec.rb deleted file mode 100644 index 7c7c059..0000000 --- a/spec/apache2-server_spec.rb +++ /dev/null @@ -1,612 +0,0 @@ -require_relative 'spec_helper' - -shared_examples 'virtualhost port configurator' do |port_attribute_name, port_attribute_value| - let(:virtualhost_directive) { "" } - cached(:chef_run) do - node.override['openstack']['endpoints'][port_attribute_name]['port'] = port_attribute_value - node.override['openstack']['dashboard']['server_aliases'] = %w(server_aliases_value) - node.override['openstack']['dashboard']['server_hostname'] = 'server_hostname_value' - runner.converge(described_recipe) - end - - it 'does not set NameVirtualHost directives when apache 2.4' do - expect(chef_run).not_to render_file(file.name).with_content(/^NameVirtualHost/) - end - - it 'sets the VirtualHost directive' do - expect(chef_run).to render_file(file.name).with_content(/^#{virtualhost_directive}$/) - end - - describe 'server_hostname' do - it 'sets the value if the server_hostname is present' do - expect(chef_run).to render_file(file.name) - .with_content(/^#{virtualhost_directive}\s*ServerName server_hostname_value$/) - end - - it 'does not set the value if the server_hostname is not present' do - expect(chef_run).not_to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerName$/) - end - end - describe 'server_aliases' do - it 'sets the value if the server_aliases is present' do - expect(chef_run).to render_file(file.name) - .with_content(/^#{virtualhost_directive}\s*ServerName.*\s*ServerAlias server_aliases_value$/) - end - context 'sets the value if multiple server_aliases is present' do - cached(:chef_run) do - node.override['openstack']['dashboard']['server_aliases'] = %w(server_aliases_value1 server_aliases_value2) - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name) - .with_content(/^#{virtualhost_directive}\s*ServerAlias server_aliases_value1 server_aliases_value2$/) - end - end - it 'does not set the value if the server_aliases is not present' do - expect(chef_run).not_to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerAlias$/) - end - end -end - -describe 'openstack-dashboard::apache2-server' do - describe 'ubuntu' do - let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } - let(:node) { runner.node } - cached(:chef_run) do - node.override['openstack']['dashboard']['custom_template_banner'] = 'custom_template_banner_value' - node.override['openstack']['dashboard']['traceenable'] = 'value' - node.override['openstack']['dashboard']['error_log'] = 'error_log_value' - node.override['openstack']['dashboard']['access_log'] = 'access_log_value' - runner.converge(described_recipe) - end - - cached(:chef_run_no_ssl) do - node.override['openstack']['dashboard']['use_ssl'] = false - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - runner.converge(described_recipe) - end - - cached(:chef_run_chain) do - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - runner.converge(described_recipe) - end - - include_context 'non_redhat_stubs' - include_context 'dashboard_stubs' - - it do - expect(chef_run).to install_apache2_install('openstack').with(listen: %w(0.0.0.0:80 0.0.0.0:443)) - end - - it 'enables apache modules' do - expect(chef_run).to create_apache2_mod_wsgi 'dashboard' - expect(chef_run).to enable_apache2_module('rewrite') - expect(chef_run).to enable_apache2_module('headers') - end - - it 'does not include the apache mod_ssl package when ssl disabled' do - expect(chef_run_no_ssl).not_to enable_apache2_module('ssl') - end - - describe 'certs' do - describe 'get secret' do - let(:pem) { chef_run.file('/etc/ssl/certs/horizon.pem') } - let(:key) { chef_run.file('/etc/ssl/private/horizon.key') } - - it 'create files and restarts apache' do - expect(chef_run).to create_file('/etc/ssl/certs/horizon.pem').with( - content: 'horizon_pem_value', - user: 'root', - group: 'root', - mode: '644' - ) - expect(chef_run).to create_file('/etc/ssl/private/horizon.key').with( - content: 'horizon_key_value', - user: 'root', - group: 'ssl-cert', - mode: '640' - ) - end - end - describe 'set ssl chain' do - let(:chain) { chef_run_chain.file('/etc/ssl/certs/horizon-chain.pem') } - - it 'create files and restarts apache' do - expect(chef_run_chain).to create_file('/etc/ssl/certs/horizon-chain.pem').with( - content: 'horizon_chain_pem_value', - user: 'root', - group: 'root', - mode: '644' - ) - end - end - describe 'get secret with only one pem' do - let(:key) { chef_run.file('/etc/ssl/private/horizon.pem') } - - cached(:chef_run) do - node.override['openstack']['dashboard']['ssl'].tap do |ssl| - ssl['cert_dir'] = ssl['key_dir'] = '/etc/ssl/private' - ssl['cert'] = ssl['key'] = 'horizon.pem' - end - runner.converge(described_recipe) - end - - it do - expect(chef_run).not_to create_file('/etc/ssl/private/horizon.pem') - .with( - content: 'horizon_pem_value', - user: 'root', - group: 'root', - mode: '644' - ) - end - - it do - expect(chef_run).to create_file('/etc/ssl/private/horizon.pem').with( - content: 'horizon_pem_value', - user: 'root', - group: 'ssl-cert', - mode: '640' - ) - end - - it 'does not mess with certs if ssl not enabled' do - expect(chef_run_no_ssl).not_to create_file('/etc/ssl/certs/horizon.pem') - expect(chef_run_no_ssl).not_to create_file('/etc/ssl/certs/horizon.key') - expect(chef_run_no_ssl).not_to create_file('/etc/ssl/certs/horizon-chain.pem') - end - end - - context 'get different secret' do - let(:pem) { chef_run.file('/etc/anypath/any.pem') } - let(:key) { chef_run.file('/etc/anypath/any.key') } - - cached(:chef_run) do - node.override['openstack']['dashboard']['ssl']['cert_dir'] = '/etc/anypath' - node.override['openstack']['dashboard']['ssl']['key_dir'] = '/etc/anypath' - node.override['openstack']['dashboard']['ssl']['cert'] = 'any.pem' - node.override['openstack']['dashboard']['ssl']['key'] = 'any.key' - node.override['openstack']['dashboard']['ssl']['chain'] = 'any-chain.pem' - runner.converge(described_recipe) - end - - before do - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'any.pem') - .and_return('any_pem_value') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'any.key') - .and_return('any_key_value') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'any-chain.pem') - .and_return('any_chain_pem_value') - node.override['openstack']['dashboard'] - end - it 'create files and restarts apache' do - expect(chef_run).to create_file('/etc/anypath/any.pem').with( - content: 'any_pem_value', - user: 'root', - group: 'root', - mode: '644' - ) - expect(chef_run).to create_file('/etc/anypath/any.key').with( - content: 'any_key_value', - user: 'root', - group: 'ssl-cert', - mode: '640' - ) - end - describe 'set ssl chain' do - let(:chain) { chef_run.file('/etc/anypath/any-chain.pem') } - it 'create files and restarts apache' do - expect(chef_run).to create_file('/etc/anypath/any-chain.pem').with( - content: 'any_chain_pem_value', - user: 'root', - group: 'root', - mode: '644' - ) - end - end - it 'does not mess with certs if ssl not enabled' do - expect(chef_run_no_ssl).not_to create_file('/etc/anypath/any.key') - expect(chef_run_no_ssl).not_to create_file('/etc/anypath/any.pem') - expect(chef_run_no_ssl).not_to create_file('/etc/anypath/any-chain.pem') - end - context 'does not create certs if certs data bag is disabled' do - cached(:chef_run) do - node.override['openstack']['dashboard']['ssl']['use_data_bag'] = false - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - runner.converge(described_recipe) - end - it do - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.pem') - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.key') - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon-chain.pem') - end - end - end - end - - it 'creates .blackhole dir with proper owner' do - dir = '/usr/share/openstack-dashboard/openstack_dashboard/.blackhole' - - expect(chef_run.directory(dir).owner).to eq('root') - end - - describe 'openstack-dashboard virtual host' do - let(:file) { chef_run.template('/etc/apache2/sites-available/openstack-dashboard.conf') } - - it 'creates openstack-dashboard.conf' do - expect(chef_run).to create_template('/etc/apache2/sites-available/openstack-dashboard.conf').with( - source: 'dash-site.erb', - variables: { - apache_admin: 'root@localhost', - http_bind_address: '0.0.0.0', - http_bind_port: 80, - https_bind_address: '0.0.0.0', - https_bind_port: 443, - log_dir: '/var/log/apache2', - ssl_cert_file: '/etc/ssl/certs/horizon.pem', - ssl_chain_file: '', - ssl_key_file: '/etc/ssl/private/horizon.key', - } - ) - end - - it do - expect(chef_run.template('/etc/apache2/sites-available/openstack-dashboard.conf')).to \ - notify('service[apache2]').to(:reload).immediately - end - - describe 'template content' do - let(:rewrite_ssl_directive) { /^\s*RewriteEngine On\s*RewriteCond \%\{HTTPS\} off$/ } - let(:default_rewrite_rule) { %r(^\s*RewriteRule \^\(\.\*\)\$ https\://%\{HTTP_HOST\}%\{REQUEST_URI\} \[L,R\]$) } - - it 'has the default banner' do - expect(chef_run).to render_file(file.name).with_content(/^custom_template_banner_value$/) - end - - describe 'cache_html' do - it 'prevents html page caching' do - expect(chef_run).to render_file(file.name) - .with_content(%r{^\s*SetEnvIfExpr "req\('accept'\) =~/html/" NO_CACHE$}) - expect(chef_run).to render_file(file.name) - .with_content(/^\s*Header merge Cache-Control no-cache env=NO_CACHE$/) - expect(chef_run).to render_file(file.name) - .with_content(/^\s*Header merge Cache-Control no-store env=NO_CACHE$/) - end - - context 'allows html page caching' do - cached(:chef_run) do - node.override['openstack']['dashboard']['cache_html'] = true - runner.converge(described_recipe) - end - it do - expect(chef_run).not_to render_file(file.name) - .with_content(%r{^\s*SetEnvIfExpr "req\('accept'\) =~/html/" NO_CACHE$}) - expect(chef_run).not_to render_file(file.name) - .with_content(/^\s*Header merge Cache-Control no-cache env=NO_CACHE$/) - expect(chef_run).not_to render_file(file.name) - .with_content(/^\s*Header merge Cache-Control no-store env=NO_CACHE$/) - end - end - end - - it_should_behave_like 'virtualhost port configurator', 'dashboard-http-bind', 80 - - describe 'with use_ssl enabled' do - it_should_behave_like 'virtualhost port configurator', 'dashboard-https-bind', 443 - - it 'shows rewrite ssl directive' do - expect(chef_run).to render_file(file.name).with_content(rewrite_ssl_directive) - end - - describe 'rewrite rule' do - it 'shows the default SSL rewrite rule when http_port is 80 and https_port is 443' do - expect(chef_run).to render_file(file.name).with_content(default_rewrite_rule) - end - - context 'shows the parameterized SSL rewrite rule when http_port is different from 80' do - https_port_value = 443 - cached(:chef_run) do - node.override['openstack']['dashboard']['use_ssl'] = true - node.override['openstack']['bind_service']['dashboard_http']['port'] = 81 - node.override['openstack']['bind_service']['dashboard_https']['port'] = https_port_value - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name) - .with_content(%r{^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$}) - end - end - - context 'shows the parameterized SSL rewrite rule when https_port is different from 443' do - https_port_value = 444 - cached(:chef_run) do - node.override['openstack']['dashboard']['use_ssl'] = true - node.override['openstack']['bind_service']['dashboard_http']['port'] = 80 - node.override['openstack']['bind_service']['dashboard_https']['port'] = https_port_value - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name) - .with_content(%r{^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$}) - end - end - end - - it 'shows ssl certificate related directives defaults' do - [ - /^\s*SSLEngine on$/, - %r{^\s*SSLCertificateFile /etc/ssl/certs/horizon.pem$}, - %r{^\s*SSLCertificateKeyFile /etc/ssl/private/horizon.key$}, - /^\s*SSLProtocol All -SSLv2 -SSLv3$/, - ].each do |ssl_certificate_directive| - expect(chef_run).to render_file(file.name).with_content(ssl_certificate_directive) - end - expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) - end - describe 'set ssl chain' do - it 'shows chain directive' do - expect(chef_run_chain).to render_file(file.name) - .with_content(%r{^\s*SSLCertificateChainFile /etc/ssl/certs/horizon-chain.pem$}) - end - end - context 'set use_data_bag to false' do - cached(:chef_run) do - node.override['openstack']['dashboard']['ssl']['use_data_bag'] = false - runner.converge(described_recipe) - end - it 'shows ssl certificate related directives defaults' do - [ - /^\s*SSLEngine on$/, - %r{^\s*SSLCertificateFile /etc/ssl/certs/horizon.pem$}, - %r{^\s*SSLCertificateKeyFile /etc/ssl/private/horizon.key$}, - /^\s*SSLProtocol All -SSLv2 -SSLv3$/, - ].each do |ssl_certificate_directive| - expect(chef_run).to render_file(file.name).with_content(ssl_certificate_directive) - end - expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) - end - context 'set ssl chain' do - cached(:chef_run) do - node.override['openstack']['dashboard']['ssl']['use_data_bag'] = false - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - runner.converge(described_recipe) - end - it 'shows chain directive' do - expect(chef_run).to render_file(file.name) - .with_content(%r{^\s*SSLCertificateChainFile /etc/ssl/certs/horizon-chain.pem$}) - end - end - end - it 'has no ssl ciphers configured by default' do - expect(chef_run).not_to render_file(file.name).with_content(/^\s*SSLCipherSuite.*$/) - end - # noinspection CookbookSourceRoot - context 'override attributes' do - cached(:chef_run) do - node.override['openstack']['dashboard']['ssl']['cert'] = 'ssl.cert' - node.override['openstack']['dashboard']['ssl']['key'] = 'ssl.key' - node.override['openstack']['dashboard']['ssl']['cert_dir'] = 'ssl_dir_value/certs' - node.override['openstack']['dashboard']['ssl']['key_dir'] = 'ssl_dir_value/private' - node.override['openstack']['dashboard']['ssl']['protocol'] = 'ssl_protocol_value' - node.override['openstack']['dashboard']['ssl']['ciphers'] = 'ssl_ciphers_value' - runner.converge(described_recipe) - end - before do - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'ssl.cert') - .and_return('ssl_cert_value') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'ssl.key') - .and_return('ssl_key_value') - end - it 'shows ssl related directives overrides' do - [ - /^\s*SSLEngine on$/, - %r{^\s*SSLCertificateFile ssl_dir_value/certs/ssl.cert$}, - %r{^\s*SSLCertificateKeyFile ssl_dir_value/private/ssl.key$}, - /^\s*SSLProtocol ssl_protocol_value$/, - /^\s*SSLCipherSuite ssl_ciphers_value$/, - ].each do |ssl_directive| - expect(chef_run).to render_file(file.name).with_content(ssl_directive) - end - expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) - end - end - end - context 'with use_ssl disabled' do - cached(:chef_run) do - node.override['openstack']['dashboard']['use_ssl'] = false - runner.converge(described_recipe) - end - - it 'does not show rewrite ssl directive' do - expect(chef_run).not_to render_file(file.name).with_content(rewrite_ssl_directive) - end - - context 'does not show the default rewrite rule' do - cached(:chef_run) do - node.override['openstack']['dashboard']['use_ssl'] = false - node.override['openstack']['endpoints']['dashboard-http-bind']['port'] = 80 - node.override['openstack']['endpoints']['dashboard-https-bind']['port'] = 443 - runner.converge(described_recipe) - end - it do - expect(chef_run).not_to render_file(file.name).with_content(default_rewrite_rule) - end - end - - it 'does not show ssl certificate related directives' do - [ - /^\s*SSLEngine on$/, - /^\s*SSLCertificateFile/, - /^\s*SSLCertificateKeyFile/, - ].each do |ssl_certificate_directive| - expect(chef_run).not_to render_file(file.name).with_content(ssl_certificate_directive) - end - expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) - end - end - - it 'shows the ServerAdmin' do - expect(chef_run).to render_file(file.name).with_content(/\s*ServerAdmin root@localhost$/) - end - - it 'sets the WSGI script alias defaults' do - expect(chef_run).to render_file(file.name) - .with_content(%r{^\s*WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py$}) - end - - context 'sets the WSGI script alias' do - cached(:chef_run) do - node.override['openstack']['dashboard']['wsgi_path'] = 'wsgi_path_value' - node.override['openstack']['dashboard']['webroot'] = 'root' - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name).with_content(/^\s*WSGIScriptAlias root wsgi_path_value$/) - end - end - - context 'sets the WSGI daemon process' do - cached(:chef_run) do - node.override['openstack']['dashboard']['horizon_user'] = 'horizon_user_value' - node.override['openstack']['dashboard']['horizon_group'] = 'horizon_group_value' - node.override['openstack']['dashboard']['dash_path'] = 'dash_path_value' - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name).with_content( - /^\s*WSGIDaemonProcess dashboard user=horizon_user_value group=horizon_group_value processes=3 threads=10 python-path=dash_path_value$/ - ) - end - end - - context 'has the default DocRoot' do - cached(:chef_run) do - node.override['openstack']['dashboard']['dash_path'] = 'dash_path_value' - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name).with_content(%r{\s*DocumentRoot dash_path_value/.blackhole/$}) - end - end - - it 'has TraceEnable set' do - expect(chef_run).to render_file(file.name).with_content(/^ TraceEnable value$/) - end - - context 'sets the right Alias path for /static' do - cached(:chef_run) do - node.override['openstack']['dashboard']['static_path'] = 'static_path_value' - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name).with_content(%r{^\s+Alias /static static_path_value$}) - end - end - - context 'sets the directory directive' do - cached(:chef_run) do - %w(dash_path static_path).each do |dir_attribute| - node.override['openstack']['dashboard'][dir_attribute] = "#{dir_attribute}_value" - end - runner.converge(described_recipe) - end - %w(dash_path static_path).each do |dir_attribute| - it do - expect(chef_run).to render_file(file.name).with_content(/^\s*$/) - end - end - end - - describe 'directory options' do - it 'sets default options for apache 2.4' do - expect(chef_run).to render_file(file.name).with_content(/^\s*Require all granted$/) - end - end - - context 'sets wsgi socket prefix if wsgi_socket_prefix attribute is preset' do - cached(:chef_run) do - node.override['openstack']['dashboard']['wsgi_socket_prefix'] = '/var/run/wsgi' - runner.converge(described_recipe) - end - it do - expect(chef_run).to render_file(file.name).with_content(%r{^WSGISocketPrefix /var/run/wsgi$}) - end - end - - it 'omits wsgi socket prefix if wsgi_socket_prefix attribute is not preset' do - expect(chef_run).not_to render_file(file.name).with_content(/^WSGISocketPrefix $/) - end - end - end - - describe 'secret_key_path file' do - secret_key_path = '/var/lib/openstack-dashboard/secret_key' - let(:file) { chef_run.file(secret_key_path) } - - it 'has correct ownership' do - expect(file.owner).to eq('horizon') - expect(file.group).to eq('horizon') - end - - it 'has correct mode' do - expect(file.mode).to eq('600') - end - - it 'does not notify apache2 restart' do - expect(file).not_to notify('service[apache2]').to(:restart) - end - - context 'has configurable path and ownership settings' do - cached(:chef_run) do - node.override['openstack']['dashboard']['secret_key_path'] = 'somerandompath' - node.override['openstack']['dashboard']['horizon_user'] = 'somerandomuser' - node.override['openstack']['dashboard']['horizon_group'] = 'somerandomgroup' - node.override['openstack']['dashboard']['secret_key_content'] = 'somerandomcontent' - runner.converge(described_recipe) - end - it do - file = chef_run.file('somerandompath') - expect(file.owner).to eq('somerandomuser') - expect(file.group).to eq('somerandomgroup') - end - - describe 'secret_key_content set' do - it 'has configurable secret_key_content setting' do - expect(chef_run).to render_file('somerandompath').with_content('somerandomcontent') - end - - it 'notifies apache2 restart when secret_key_content set' do - expect(chef_run.file('somerandompath')).to notify('service[apache2]').to(:restart) - end - end - end - end - - it 'does not delete openstack-dashboard.conf' do - file = '/etc/httpd/conf.d/openstack-dashboard.conf' - - expect(chef_run).not_to delete_file(file) - end - - it do - expect(chef_run).to disable_apache2_site('000-default') - end - - it do - expect(chef_run).to_not disable_apache2_site('default') - end - - it do - expect(chef_run).to enable_apache2_site('openstack-dashboard') - end - - it do - expect(chef_run.apache2_site('openstack-dashboard')).to notify('service[apache2]').to(:reload).immediately - end - end -end diff --git a/spec/horizon-redhat_spec.rb b/spec/horizon-redhat_spec.rb deleted file mode 100644 index 32574ae..0000000 --- a/spec/horizon-redhat_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -require_relative 'spec_helper' - -describe 'openstack-dashboard::horizon' do - ALL_RHEL.each do |p| - context "redhat #{p[:version]}" do - let(:runner) { ChefSpec::SoloRunner.new(p) } - let(:node) { runner.node } - cached(:chef_run) do - runner.converge('openstack-identity::server-apache', described_recipe) - end - - include_context 'dashboard_stubs' - include_context 'redhat_stubs' - - case p - when REDHAT_7 - it 'installs packages' do - expect(chef_run).to upgrade_package %w(openstack-dashboard MySQL-python) - end - when REDHAT_8 - it 'installs packages' do - expect(chef_run).to upgrade_package %w(openstack-dashboard python3-PyMySQL) - end - end - - describe 'local_settings' do - let(:file) { chef_run.template('/etc/openstack-dashboard/local_settings') } - - it 'creates local_settings' do - expect(chef_run).to create_template(file.name).with( - user: 'root', - group: 'apache', - mode: '640' - ) - end - - it 'has urls set' do - [ - %r{^LOGIN_URL = '/auth/login/'$}, - %r{^LOGOUT_URL = '/auth/logout/'$}, - %r{^LOGIN_REDIRECT_URL = '/'$}, - ].each do |line| - expect(chef_run).to render_file(file.name).with_content(line) - end - end - - it 'has policy file path set' do - expect(chef_run).to render_file(file.name) - .with_content(%r{^POLICY_FILES_PATH = '/etc/openstack-dashboard'$}) - end - end - end - end -end diff --git a/spec/horizon_spec.rb b/spec/horizon_spec.rb deleted file mode 100644 index 2d03c0b..0000000 --- a/spec/horizon_spec.rb +++ /dev/null @@ -1,555 +0,0 @@ -require_relative 'spec_helper' - -describe 'openstack-dashboard::horizon' do - describe 'ubuntu' do - let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } - let(:node) { runner.node } - cached(:chef_run) do - node.override['openstack']['dashboard']['custom_template_banner'] = 'custom_template_banner_value' - node.override['openstack']['dashboard']['allowed_hosts'] = ['dashboard.example.net'] - node.override['openstack']['dashboard']['ssl_cacert'] = '/path_to_cacert.pem' - node.override['openstack']['dashboard']['identity_api_version'] = 'identity_api_version_value' - node.override['openstack']['dashboard']['volume_api_version'] = 'volume_api_version_value' - node.override['openstack']['dashboard']['keystone_default_domain'] = 'keystone_default_domain_value' - node.override['openstack']['dashboard']['console_type'] = 'console_type_value' - node.override['openstack']['dashboard']['help_url'] = 'help_url_value' - node.override['openstack']['dashboard']['password_autocomplete'] = 'password_autocomplete_value' - node.override['openstack']['dashboard']['secret_key_path'] = 'secret_key_path_value' - node.override['openstack']['dashboard']['use_ssl'] = true - node.override['openstack']['dashboard']['keystone_backend']['name'] = 'native' - node.override['openstack']['dashboard']['misc_local_settings'] = { - 'CUSTOM_CONFIG_A' => { - 'variable1' => 'value1', - 'variable2' => 'value2', - }, - 'CUSTOM_CONFIG_B' => { - 'variable1' => 'value1', - 'variable2' => 'value2', - }, - } - runner.converge('openstack-identity::server-apache', described_recipe) - end - - cached(:chef_run2) do - node.override['openstack']['dashboard']['debug'] = true - node.override['openstack']['dashboard']['ssl_no_verify'] = 'False' - node.override['openstack']['dashboard']['use_ssl'] = false - node.override['openstack']['dashboard']['ssl_offload'] = false - node.override['openstack']['dashboard']['file_upload_temp_dir'] = '/foobar' - node.override['openstack']['dashboard']['keystone_multidomain_support'] = true - node.override['openstack']['dashboard']['simple_ip_management'] = true - node.override['openstack']['dashboard']['session_backend'] = 'file' - node.override['openstack']['dashboard']['keystone_default_role'] = 'keystone_default_role_value' - node.override['openstack']['dashboard']['keystone_backend']['name'] = 'ldap' - node.override['openstack']['dashboard']['neutron']['enable_quotas'] = false - node.override['openstack']['dashboard']['neutron']['enable_lb'] = true - node.override['openstack']['dashboard']['plugins'] = %w(testPlugin1 testPlugin2) - node.override['openstack']['db']['dashboard']['migrate'] = false - runner.converge('openstack-identity::server-apache', described_recipe) - end - - cached(:chef_run_sql) do - node.override['openstack']['dashboard']['session_backend'] = 'sql' - runner.converge('openstack-identity::server-apache', described_recipe) - end - - include_context 'non_redhat_stubs' - include_context 'dashboard_stubs' - - it 'installs packages' do - expect(chef_run).to upgrade_package %w(node-less python3-django-horizon openstack-dashboard python3-mysqldb) - end - - describe 'local_settings.py' do - let(:file) { chef_run.template('/etc/openstack-dashboard/local_settings.py') } - - it 'creates local_settings' do - expect(chef_run).to create_template(file.name).with( - sensitive: true, - user: 'root', - group: 'horizon', - mode: '640' - ) - end - - it 'notifies web service to restart delayed' do - expect(file).to notify('service[apache2]').to(:restart).delayed - end - - describe 'template contents' do - it 'has the customer banner' do - expect(chef_run).to render_file(file.name).with_content(/^custom_template_banner_value$/) - end - - it 'sets misc settings properly' do - [ - ['CUSTOM_CONFIG_A = {', - ' \'variable1\': \'value1\',', - ' \'variable2\': \'value2\',', - '}', - ], - ['CUSTOM_CONFIG_B = {', - ' \'variable1\': \'value1\',', - ' \'variable2\': \'value2\',', - '}', - ], - ].each do |content| - expect(chef_run).to render_file(file.name).with_content(build_section(content)) - end - end - - describe 'debug setting' do - describe 'set to true' do - it 'has a true value for the DEBUG attribute' do - expect(chef_run2).to render_file(file.name).with_content(/^DEBUG = True$/) - end - - it 'sets the console logging level to DEBUG' do - expect(chef_run2).to render_file(file.name).with_content(/^\s*'level': 'DEBUG',$/) - end - end - - describe 'set to false' do - it 'has a false value for the DEBUG attribute' do - expect(chef_run).to render_file(file.name).with_content(/^DEBUG = False$/) - end - - it 'sets the console logging level to INFO' do - expect(chef_run).to render_file(file.name).with_content(/^\s*'level': 'INFO',$/) - end - end - end - - describe 'config ssl_no_verify' do - describe 'set to the default value' do - it 'has a True value for the OPENSTACK_SSL_NO_VERIFY attribute' do - expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_SSL_NO_VERIFY = True$/) - end - end - - context 'set to False' do - cached(:chef_run) do - node.override['openstack']['dashboard']['use_ssl'] = true - node.override['openstack']['dashboard']['ssl_no_verify'] = 'False' - runner.converge('openstack-identity::server-apache', described_recipe) - end - it 'has a False value for the OPENSTACK_SSL_NO_VERIFY attribute' do - expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_SSL_NO_VERIFY = False$/) - end - end - - describe 'not set when ssl disabled' do - it 'has a True value for the OPENSTACK_SSL_NO_VERIFY attribute' do - expect(chef_run2).not_to render_file(file.name).with_content(/^OPENSTACK_SSL_NO_VERIFY = True$/) - end - end - end - - it 'config ssl_cacert' do - expect(chef_run).to render_file(file.name).with_content(%r{^OPENSTACK_SSL_CACERT = '/path_to_cacert.pem'$}) - end - - it 'does not config ssl_cacert when ssl disabled' do - expect(chef_run2).not_to render_file(file.name) - .with_content(%r{^OPENSTACK_SSL_CACERT = '/path_to_cacert.pem'$}) - end - - it 'has some allowed hosts set' do - expect(chef_run).to render_file(file.name).with_content(/^ALLOWED_HOSTS = \["dashboard.example.net"\]$/) - end - - describe 'ssl offload' do - let(:secure_proxy_string) { 'SECURE_PROXY_SSL_HEADER = \(\'HTTP_X_FORWARDED_PROTOCOL\', \'https\'\)' } - - it 'configures ssl proxy when ssl_offload is set to true' do - expect(chef_run).to render_file(file.name).with_content(/^#{secure_proxy_string}$/) - end - - it 'does not configure ssl proxy when ssl_offload is false' do - expect(chef_run2).not_to render_file(file.name).with_content(/^#{secure_proxy_string}$/) - end - end - - describe 'temp dir override' do - describe 'temp dir is nil' do - it 'does not override temp dir when it is nil' do - expect(chef_run).not_to render_file(file.name).with_content(/^FILE_UPLOAD_TEMP_DIR =/) - end - it 'does override temp dir when it is not nil' do - expect(chef_run2).to render_file(file.name).with_content(%r{^FILE_UPLOAD_TEMP_DIR = "/foobar"$}) - end - end - end - - describe 'ssl settings' do - describe 'use_ssl enabled' do - it 'sets secure csrf cookie to true when the attribute is enabled' do - expect(chef_run).to render_file(file.name).with_content(/^CSRF_COOKIE_SECURE = True$/) - end - - it 'set secure csrf cookie to true when the attribute is enabled' do - expect(chef_run).to render_file(file.name).with_content(/^SESSION_COOKIE_SECURE = True$/) - end - - context 'sets secure csrf & session cookie to false when the attribute is disabled' do - cached(:chef_run) do - node.override['openstack']['dashboard']['csrf_cookie_secure'] = false - node.override['openstack']['dashboard']['session_cookie_secure'] = false - runner.converge('openstack-identity::server-apache', described_recipe) - end - it do - expect(chef_run).to render_file(file.name).with_content(/^CSRF_COOKIE_SECURE = False$/) - end - it do - expect(chef_run).to render_file(file.name).with_content(/^SESSION_COOKIE_SECURE = False$/) - end - end - end - - it 'does not set secure csrf nor secure session cookie settings when use_ssl is disabled' do - [ - /^CSRF_COOKIE_SECURE$/, - /^SESSION_COOKIE_SECURE$/, - ].each do |setting| - expect(chef_run2).not_to render_file(file.name).with_content(setting) - end - end - end - - it 'does have webroot set' do - expect(chef_run).to render_file(file.name).with_content(%r{^WEBROOT = '/'$}) - end - - it 'does not have urls set' do - [ - /^LOGIN_URL =$/, - /^LOGOUT_URL =$/, - /^LOGIN_REDIRECT_URL =$/, - ].each do |line| - expect(chef_run).to_not render_file(file.name).with_content(line) - end - end - - it 'has policy file path set' do - expect(chef_run).to render_file(file.name) - .with_content(%r{^POLICY_FILES_PATH = '/usr/share/openstack-dashboard/openstack_dashboard/conf'$}) - end - - describe 'identity and volume api version setting' do - it 'is configurable directly' do - [ - /^\s*"identity": identity_api_version_value,$/, - /^\s*"volume": volume_api_version_value$/, - ].each do |line| - expect(chef_run).to render_file(file.name).with_content(line) - end - end - end - - describe 'keystone multidomain support' do - it 'sets to true when the attribute is enabled' do - expect(chef_run2).to render_file(file.name).with_content(/^OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True$/) - end - it 'sets to false when the attribute is disabled' do - expect(chef_run).to render_file(file.name) - .with_content(/^OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = False$/) - end - end - - it 'has a keystone default domain setting' do - expect(chef_run).to render_file(file.name) - .with_content(/^OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "keystone_default_domain_value"$/) - end - - it 'has a console_type setting' do - expect(chef_run).to render_file(file.name).with_content(/^CONSOLE_TYPE = "console_type_value"$/) - end - - it 'has a help_url setting' do - expect(chef_run).to render_file(file.name).with_content(/\s*'help_url': "help_url_value",$/) - end - - it 'allows HORIZON_CONFIG to use INSTALLED_APPS to determine default dashboards' do - expect(chef_run).not_to render_file(file.name).with_content(/\s*'dashboards':/) - expect(chef_run).not_to render_file(file.name).with_content(/\s*'default_dashboard':/) - end - - describe 'simple ip management' do - it 'disables the setting when the attribute is not set' do - expect(chef_run).to render_file(file.name).with_content('HORIZON_CONFIG["simple_ip_management"] = False') - end - it 'enables the setting when the attribute is set' do - expect(chef_run2).to render_file(file.name).with_content('HORIZON_CONFIG["simple_ip_management"] = True') - end - end - - it 'has default password_autocomplete setting' do - expect(chef_run).to render_file(file.name) - .with_content(/^HORIZON_CONFIG\["password_autocomplete"\] = "password_autocomplete_value"$/) - end - - it 'has configurable secret_key_path setting' do - expect(chef_run).to render_file(file.name) - .with_content( - /^SECRET_KEY = secret_key.generate_or_read_from_file\(os.path.realpath\('secret_key_path_value'\)\)$/ - ) - end - - describe 'session backend' do - describe 'file as session backend' do - it 'sets the session engine to file when it is the session backend' do - expect(chef_run2).to render_file(file.name) - .with_content(/^SESSION_ENGINE = 'django.contrib.sessions.backends.file'$/) - end - end - - describe 'memcached as session backend' do - let(:memcached_session_engine_setting) { /^SESSION_ENGINE = 'django.contrib.sessions.backends.cache'$/ } - describe 'with memcache servers' do - it 'sets the session engine attribute' do - expect(chef_run).to render_file(file.name).with_content(memcached_session_engine_setting) - end - - it 'sets the location of the caches to the memcached servers addresses' do - expect(chef_run).to render_file(file.name) - .with_content(/^\s*'LOCATION': \[\s*'hostA:port',\s*'hostB:port',\s*\]$/) - end - end - - context 'without memcache servers' do - cached(:chef_run) do - allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers).and_return([]) - runner.converge('openstack-identity::server-apache', described_recipe) - end - it 'does not configure caching when backend == memcache and memcached_servers == []' do - expect(chef_run).to_not render_file(file.name) - .with_content(/^\s*'LOCATION': \[\s*'hostA:port',\s*'hostB:port',\s*\]$/) - end - end - end - - it 'sets the session engine to db when sql is the session backend' do - expect(chef_run_sql).to render_file(file.name) - .with_content(/^SESSION_ENGINE = 'django.contrib.sessions.backends.db'$/) - end - end - - it 'has a keystone url' do - expect(chef_run).to render_file(file.name) - .with_content(%r{OPENSTACK_KEYSTONE_URL = "http://127.0.0.1:5000/v3"}) - end - - it 'has a keystone default role' do - expect(chef_run2).to render_file(file.name) - .with_content(/^OPENSTACK_KEYSTONE_DEFAULT_ROLE = "keystone_default_role_value"$/) - end - - it 'sets the backend name to native' do - expect(chef_run).to render_file(file.name).with_content(/^\s*'name': 'native',$/) - end - - it 'sets the backend name to ldap' do - expect(chef_run2).to render_file(file.name).with_content(/^\s*'name': 'ldap',$/) - end - - keystone_settings = %w(can_edit_user can_edit_group can_edit_project can_edit_domain can_edit_role) - context 'enables the keystone backend settings when the attribute is True' do - cached(:chef_run) do - keystone_settings.each do |keystone_setting| - node.override['openstack']['dashboard']['keystone_backend'][keystone_setting] = true - end - runner.converge('openstack-identity::server-apache', described_recipe) - end - keystone_settings.each do |keystone_setting| - it do - expect(chef_run).to render_file(file.name).with_content(/^\s*\'#{keystone_setting}\': True,$/) - end - end - end - - context 'disables the keystone backend settings when the attribute is False' do - cached(:chef_run) do - keystone_settings.each do |keystone_setting| - node.override['openstack']['dashboard']['keystone_backend'][keystone_setting] = false - end - runner.converge('openstack-identity::server-apache', described_recipe) - end - keystone_settings.each do |keystone_setting| - it do - expect(chef_run).to render_file(file.name).with_content(/^\s*\'#{keystone_setting}\': False,$/) - end - end - end - - describe 'neutron settings' do - it 'enables the enable_quotas setting when the attributes is True' do - expect(chef_run).to render_file(file.name).with_content(/^\s*'enable_quotas': True,$/) - end - - it 'disables the enable_quotas setting when the attributes is False' do - expect(chef_run2).to render_file(file.name).with_content(/^\s*'enable_quotas': False,$/) - end - - describe 'lbaas setting' do - it 'enables the enable_lb setting when the attribute is true' do - expect(chef_run2).to render_file(file.name).with_content(/^\s*'enable_lb': True,$/) - end - it 'disables the enable_lb setting when the attribute is false' do - expect(chef_run).to render_file(file.name).with_content(/^\s*'enable_lb': False,$/) - end - end - end - - context 'sets the logger level for components' do - components = %w( - ceilometerclient - cinderclient - django - glanceclient - heatclient - horizon - keystoneclient - neutronclient - nose.plugins.manager - novaclient - openstack_auth - openstack_dashboard - swiftclient - troveclient - ) - cached(:chef_run) do - components.each do |component| - node.override['openstack']['dashboard']['log_level'][component] = "#{component}_log_level_value" - end - runner.converge('openstack-identity::server-apache', described_recipe) - end - components.each do |component| - it do - expect(chef_run).to render_file(file.name).with_content( - /^\s*'#{component}': {\s*'handlers': \['console'\],\s*'level': '#{component}_log_level_value',$/ - ) - end - end - end - - { - 'mysql' => 'django.db.backends.mysql', - 'sqlite' => 'django.db.backends.sqlite3', - }.each do |service_type, backend| - context "#{service_type} database settings" do - cached(:chef_run) do - node.override['openstack']['db']['dashboard']['username'] = "#{service_type}_user" - node.override['openstack']['db']['python_packages'][service_type] = %w(pkg1 pkg2) - runner.converge('openstack-identity::server-apache', described_recipe) - end - before do - allow_any_instance_of(Chef::Recipe).to receive(:db) - .with('dashboard') - .and_return( - 'service_type' => service_type, - 'db_name' => "#{service_type}_db", - 'host' => "#{service_type}_host", - 'port' => "#{service_type}_port" - ) - end - - [ - /^\s*'ENGINE': '#{backend}',$/, - /^\s*'NAME': '#{service_type}_db',$/, - ].each do |cfg| - it "configures the #{service_type} backend with #{cfg}" do - expect(chef_run).to render_file(file.name).with_content(cfg) - end - end - - [ - /^\s*'USER': '#{service_type}_user',$/, - /^\s*'PASSWORD': 'test-passes',$/, - /^\s*'HOST': '#{service_type}_host',$/, - /^\s*'PORT': '#{service_type}_port',$/, - ].each do |cfg| - next if service_type == 'sqlite' - it "configures the #{service_type} backend with #{cfg}" do - expect(chef_run).to render_file(file.name).with_content(cfg) - end - end - end - end - - describe 'plugins' do - let(:mod_regex) { /^mod = sys.modules\['openstack_dashboard.settings'\]$/ } - describe 'plugins enabled' do - it 'shows the mod setting' do - expect(chef_run2).to render_file(file.name).with_content(mod_regex) - end - - it 'shows enabled plugins as installed apps' do - %w(testPlugin1 testPlugin2).each do |plugin| - expect(chef_run2).to render_file(file.name) - .with_content(/^mod\.INSTALLED_APPS \+= \('#{plugin}', \)$/) - end - end - end - - it 'does not show the mod setting if there are no plugins' do - expect(chef_run).not_to render_file(file.name).with_content(mod_regex) - end - end - end - end - - describe 'openstack-dashboard syncdb' do - sync_db_cmd = 'python manage.py syncdb --noinput' - sync_db_environment = { - 'PYTHONPATH' => '/etc/openstack-dashboard:' \ - '/usr/share/openstack-dashboard:' \ - '$PYTHONPATH', - } - - it 'does not execute when session_backend is not sql' do - expect(chef_run).not_to run_execute(sync_db_cmd).with( - cwd: '/usr/share/openstack-dashboard', - environment: sync_db_environment - ) - end - - describe 'with sql session' do - it 'executes when session_backend is sql' do - expect(chef_run_sql).to run_execute(sync_db_cmd).with( - cwd: '/usr/share/openstack-dashboard', - environment: sync_db_environment - ) - end - - it 'does not execute when the migrate attribute is set to false' do - expect(chef_run2).not_to run_execute(sync_db_cmd).with( - cwd: '/usr/share/openstack-dashboard', - environment: sync_db_environment - ) - end - end - - context 'executes when database backend is sqlite' do - cached(:chef_run) do - node.override['openstack']['db']['dashboard']['service_type'] = 'sqlite' - runner.converge('openstack-identity::server-apache', described_recipe) - end - it do - expect(chef_run).to run_execute(sync_db_cmd).with( - cwd: '/usr/share/openstack-dashboard', - environment: sync_db_environment - ) - end - end - end - - it 'has group write mode on path' do - expect(chef_run).to create_directory('/usr/share/openstack-dashboard/openstack_dashboard/local') - .with( - owner: 'root', - group: 'horizon', - mode: '2771' - ) - end - end -end diff --git a/spec/neutron-lbaas-dashboard-redhat_spec.rb b/spec/neutron-lbaas-dashboard-redhat_spec.rb deleted file mode 100644 index d7e455a..0000000 --- a/spec/neutron-lbaas-dashboard-redhat_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require_relative 'spec_helper' - -describe 'openstack-dashboard::neutron-lbaas-dashboard' do - ALL_RHEL.each do |p| - context "redhat #{p[:version]}" do - cached(:runner) { ChefSpec::SoloRunner.new(p) } - cached(:node) { runner.node } - cached(:chef_run) do - runner.converge('openstack-identity::server-apache', described_recipe) - end - - include_context 'redhat_stubs' - include_context 'dashboard_stubs' - - it do - expect(chef_run).to include_recipe('openstack-dashboard::horizon') - end - - it do - expect(chef_run).to install_package('openstack-neutron-lbaas-ui') - end - end - end -end diff --git a/spec/neutron-lbaas-dashboard_spec.rb b/spec/neutron-lbaas-dashboard_spec.rb deleted file mode 100644 index d0ad174..0000000 --- a/spec/neutron-lbaas-dashboard_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require_relative 'spec_helper' - -describe 'openstack-dashboard::neutron-lbaas-dashboard' do - describe 'ubuntu' do - cached(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } - cached(:node) { runner.node } - cached(:chef_run) do - runner.converge('openstack-identity::server-apache', described_recipe) - end - - include_context 'non_redhat_stubs' - include_context 'dashboard_stubs' - - it do - expect(chef_run).to include_recipe('openstack-dashboard::horizon') - end - - it do - expect(chef_run).to install_package('python3-neutron-lbaas-dashboard') - end - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index 93ffd53..0000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,122 +0,0 @@ -require 'chefspec' -require 'chefspec/berkshelf' - -RSpec.configure do |config| - config.color = true - config.formatter = :documentation - config.log_level = :warn -end - -REDHAT_7 = { - platform: 'redhat', - version: '7', -}.freeze - -REDHAT_8 = { - platform: 'redhat', - version: '8', -}.freeze - -ALL_RHEL = [ - REDHAT_7, - REDHAT_8, -].freeze - -UBUNTU_OPTS = { - platform: 'ubuntu', - version: '18.04', -}.freeze - -# Build a regex for a section of lines -def build_section(lines) - lines.map! { |line| Regexp.quote(line) } - /^#{lines.join('\n')}/ -end - -shared_context 'dashboard_stubs' do - before do - allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers) - .and_return ['hostA:port', 'hostB:port'] - allow_any_instance_of(Chef::Recipe).to receive(:get_password) - .with('db', 'horizon') - .and_return('test-passes') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'horizon.pem') - .and_return('horizon_pem_value') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'horizon-chain.pem') - .and_return('horizon_chain_pem_value') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'horizon.key') - .and_return('horizon_key_value') - # identity stubs - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('secrets', 'credential_key0') - .and_return('thisiscredentialkey0') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('secrets', 'credential_key1') - .and_return('thisiscredentialkey1') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('secrets', 'fernet_key0') - .and_return('thisisfernetkey0') - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('secrets', 'fernet_key1') - .and_return('thisisfernetkey1') - allow_any_instance_of(Chef::Recipe).to receive(:search_for) - .with('os-identity').and_return( - [{ - 'openstack' => { - 'identity' => { - 'admin_tenant_name' => 'admin', - 'admin_user' => 'admin', - }, - }, - }] - ) - allow_any_instance_of(Chef::Recipe).to receive(:rabbit_transport_url) - .with('identity') - .and_return('rabbit://openstack:mypass@127.0.0.1:5672') - allow_any_instance_of(Chef::Recipe).to receive(:get_password) - .with('user', anything) - .and_return('') - allow_any_instance_of(Chef::Recipe).to receive(:get_password) - .with('db', anything) - .and_return('test-passes') - allow_any_instance_of(Chef::Recipe).to receive(:db_uri) - .with(anything, anything, anything) - .and_return('') - end -end - -shared_context 'redhat_stubs' do - before do - stub_command("[ ! -e /etc/httpd/conf/httpd.conf ] && [ -e /etc/redhat-release ] && [ $(/sbin/sestatus | grep -c '^Current mode:.*enforcing') -eq 1 ]").and_return(true) - stub_command("[ -e /etc/httpd/conf/httpd.conf ] && [ -e /etc/redhat-release ] && [ $(/sbin/sestatus | grep -c '^Current mode:.*permissive') -eq 1 ] && [ $(/sbin/sestatus | grep -c '^Mode from config file:.*enforcing') -eq 1 ]").and_return(true) - stub_command('/usr/sbin/httpd -t').and_return(true) - end -end - -shared_context 'non_redhat_stubs' do - before do - stub_command("[ ! -e /etc/httpd/conf/httpd.conf ] && [ -e /etc/redhat-release ] && [ $(/sbin/sestatus | grep -c '^Current mode:.*enforcing') -eq 1 ]").and_return(false) - stub_command("[ -e /etc/httpd/conf/httpd.conf ] && [ -e /etc/redhat-release ] && [ $(/sbin/sestatus | grep -c '^Current mode:.*permissive') -eq 1 ] && [ $(/sbin/sestatus | grep -c '^Mode from config file:.*enforcing') -eq 1 ]").and_return(false) - stub_command('/usr/sbin/httpd2 -t').and_return(true) - stub_command('/usr/sbin/apache2 -t').and_return(true) - end -end - -shared_context 'postgresql_backend' do - before do - allow_any_instance_of(Chef::Recipe).to receive(:db) - .with('dashboard') - .and_return('service_type' => 'postgresql', 'db_name' => 'flying_elephant') - end -end - -shared_context 'mysql_backend' do - before do - allow_any_instance_of(Chef::Recipe).to receive(:db) - .with('dashboard') - .and_return('service_type' => 'mysql', 'db_name' => 'flying_dolphin') - end -end diff --git a/templates/default/dash-site.erb b/templates/default/dash-site.erb deleted file mode 100644 index bd60509..0000000 --- a/templates/default/dash-site.erb +++ /dev/null @@ -1,88 +0,0 @@ -<%= node["openstack"]["dashboard"]["custom_template_banner"] %> - -:<%= @http_bind_port %>> -<% if node["openstack"]["dashboard"]["server_hostname"] -%> - ServerName <%= node["openstack"]["dashboard"]["server_hostname"] %> -<% end -%> -<% unless node["openstack"]["dashboard"]["server_aliases"].empty? -%> - ServerAlias <%= node["openstack"]["dashboard"]["server_aliases"].join(" ") %> -<% end -%> -<% if node["openstack"]["dashboard"]["use_ssl"] %> - RewriteEngine On - RewriteCond %{HTTPS} off - <% if @http_bind_port != 80 or @https_bind_port != 443 %> - RewriteRule ^(.*)$ https://%{SERVER_NAME}:<%= @https_bind_port %>%{REQUEST_URI} [L,R] - <% else -%> - RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R] - <% end -%> - TraceEnable <%= node['openstack']['dashboard']['traceenable'] %> - - -:<%= @https_bind_port %>> - <% if node["openstack"]["dashboard"]["server_hostname"] -%> - ServerName <%= node["openstack"]["dashboard"]["server_hostname"] %> - <% end -%> - <% unless node["openstack"]["dashboard"]["server_aliases"].empty? -%> - ServerAlias <%= node["openstack"]["dashboard"]["server_aliases"].join(" ") %> - <% end -%> -<% end %> - ServerAdmin <%= @apache_admin %> - # Note(jr): This is needed when SSL is used for the services, see - # https://bugs.launchpad.net/openstack-ansible/+bug/1624791/comments/17 - WSGIApplicationGroup %{GLOBAL} - WSGIScriptAlias <%= node["openstack"]["dashboard"]["webroot"] %> <%= node["openstack"]["dashboard"]["wsgi_path"] %> - WSGIDaemonProcess dashboard user=<%= node['openstack']['dashboard']['horizon_user'] %> group=<%= node['openstack']['dashboard']['horizon_group'] %> processes=3 threads=10 python-path=<%= node["openstack"]["dashboard"]["dash_path"] %> - WSGIProcessGroup dashboard - - DocumentRoot <%= node["openstack"]["dashboard"]["dash_path"] %>/.blackhole/ - Alias /static <%= node["openstack"]["dashboard"]["static_path"] %> - - - Options FollowSymLinks - AllowOverride None - - - > - Options Indexes FollowSymLinks MultiViews - AllowOverride None - Require all granted - - - > - Options FollowSymLinks MultiViews - AllowOverride None - Require all granted - - <% if node["openstack"]["dashboard"]["use_ssl"] -%> - - SSLEngine on - SSLCertificateFile <%= @ssl_cert_file %> - SSLCertificateKeyFile <%= @ssl_key_file %> - <% if node['openstack']['dashboard']['ssl']['chain'] -%> - SSLCertificateChainFile <%= @ssl_chain_file %> - <% end -%> - SSLProtocol <%= node["openstack"]["dashboard"]["ssl"]["protocol"] %> - <% if node["openstack"]["dashboard"]["ssl"]["ciphers"] -%> - SSLCipherSuite <%= node["openstack"]["dashboard"]["ssl"]["ciphers"] %> - <% end -%> - <% end -%> - - # Allow custom files to overlay the site (such as logo.png) - RewriteEngine On - RewriteCond /opt/dash/site_overlay%{REQUEST_FILENAME} -s - RewriteRule ^/(.+) /opt/dash/site_overlay/$1 [L] - - ErrorLog <%= @log_dir %>/<%= node["openstack"]["dashboard"]["error_log"] %> - LogLevel warn - CustomLog <%= @log_dir %>/<%= node["openstack"]["dashboard"]["access_log"] %> combined - TraceEnable <%= node['openstack']['dashboard']['traceenable'] %> - <% unless node["openstack"]["dashboard"]["cache_html"] %> - SetEnvIfExpr "req('accept') =~/html/" NO_CACHE - Header merge Cache-Control no-cache env=NO_CACHE - Header merge Cache-Control no-store env=NO_CACHE - <% end -%> - -<% unless node["openstack"]["dashboard"]["wsgi_socket_prefix"].nil? %> - -WSGISocketPrefix <%= node["openstack"]["dashboard"]["wsgi_socket_prefix"] %> -<% end %> diff --git a/templates/default/default_stylesheets.html.erb b/templates/default/default_stylesheets.html.erb deleted file mode 100644 index 66c40a6..0000000 --- a/templates/default/default_stylesheets.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -{% load compress %} - -{% compress css %} - -{% endcompress %} - - diff --git a/templates/default/local_settings.py.erb b/templates/default/local_settings.py.erb deleted file mode 100644 index 326199b..0000000 --- a/templates/default/local_settings.py.erb +++ /dev/null @@ -1,645 +0,0 @@ -<%= node["openstack"]["dashboard"]["custom_template_banner"] %> - -import os - -from django.utils.translation import ugettext_lazy as _ - -from horizon.utils import secret_key - -from openstack_dashboard import exceptions -from openstack_dashboard.settings import HORIZON_CONFIG - -DEBUG = <%= node["openstack"]["dashboard"]["debug"] ? "True" : "False" %> -TEMPLATE_DEBUG = DEBUG - -WEBROOT = '<%= node['openstack']['dashboard']['webroot'] %>' - -<% if node["openstack"]["dashboard"]["login_url"] %> -LOGIN_URL = '<%= node['openstack']['dashboard']['login_url'] %>' -<% end %> -<% if node["openstack"]["dashboard"]["logout_url"] %> -LOGOUT_URL = '<%= node['openstack']['dashboard']['logout_url'] %>' -<% end %> -<% if node["openstack"]["dashboard"]["login_redirect_url"] %> -LOGIN_REDIRECT_URL = '<%= node['openstack']['dashboard']['login_redirect_url'] %>' -<% end %> - -# Required for Django 1.5. -# If horizon is running in production (DEBUG is False), set this -# with the list of host/domain names that the application can serve. -# For more information see: -# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = <%= node['openstack']['dashboard']['allowed_hosts'] %> - -<% if node["openstack"]["dashboard"]["ssl_offload"] %> -# Set SSL proxy settings: -# For Django 1.4+ pass this header from the proxy after terminating the SSL, -# and don't forget to strip it from the client's request. -# For more information see: -# https://docs.djangoproject.com/en/1.4/ref/settings/#secure-proxy-ssl-header -SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') -<% end %> - -# If Horizon is being served through SSL, then uncomment the following two -# settings to better secure the cookies from security exploits -<% if node["openstack"]["dashboard"]["use_ssl"] %> -CSRF_COOKIE_SECURE = <%= node["openstack"]["dashboard"]["csrf_cookie_secure"] ? "True" : "False" %> -SESSION_COOKIE_SECURE = <%= node["openstack"]["dashboard"]["session_cookie_secure"] ? "True" : "False" %> -<% end %> - -# Overrides for OpenStack API versions. Use this setting to force the -# OpenStack dashboard to use a specific API version for a given service API. -# NOTE: The version should be formatted as it appears in the URL for the -# service API. For example, The identity service APIs have inconsistent -# use of the decimal point, so valid options would be "2.0" or "3". -OPENSTACK_API_VERSIONS = { - "identity": <%= node["openstack"]["dashboard"]["identity_api_version"] %>, - "volume": <%= node["openstack"]["dashboard"]["volume_api_version"] %> -} - -# Set this to True if running on multi-domain model. When this is enabled, it -# will require user to enter the Domain name in addition to username for login. -OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = <%= node["openstack"]["dashboard"]["keystone_multidomain_support"] ? "True" : "False" %> - -# Overrides the default domain used when running on single-domain model -# with Keystone V3. All entities will be created in the default domain. -# NOTE: This value must be the ID of the default domain, NOT the name. -# Also, you will most likely have a value in the keystone policy file like this -# "cloud_admin": "rule:admin_required and domain_id:" -# This value must match the domain id specified there. -OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "<%= node["openstack"]["dashboard"]["keystone_default_domain"] %>" - -# Set Console type: -# valid options would be "AUTO", "VNC", "SPICE" or "RDP" -CONSOLE_TYPE = "<%= node["openstack"]["dashboard"]["console_type"] %>" - -# Default OpenStack Dashboard configuration. -HORIZON_CONFIG = { - 'user_home': 'openstack_dashboard.views.get_user_home', - 'ajax_queue_limit': 10, - 'auto_fade_alerts': { - 'delay': 3000, - 'fade_duration': 1500, - 'types': ['alert-success', 'alert-info'] - }, - 'help_url': "<%= node["openstack"]["dashboard"]["help_url"] %>", - 'exceptions': {'recoverable': exceptions.RECOVERABLE, - 'not_found': exceptions.NOT_FOUND, - 'unauthorized': exceptions.UNAUTHORIZED}, - 'angular_modules': [], - 'js_files': [], -} - -# Specify a regular expression to validate user passwords. -# HORIZON_CONFIG["password_validator"] = { -# "regex": '.*', -# "help_text": _("Your password does not meet the requirements.") -# } - -# Disable simplified floating IP address management for deployments with -# multiple floating IP pools or complex network requirements. -HORIZON_CONFIG["simple_ip_management"] = <%= node['openstack']['dashboard']['simple_ip_management'] ? 'True' : 'False' %> - -# Turn off browser autocompletion for forms including the login form and -# the database creation workflow if so desired. -HORIZON_CONFIG["password_autocomplete"] = "<%= node['openstack']['dashboard']['password_autocomplete'] %>" - -LOCAL_PATH = os.path.dirname(os.path.abspath(__file__)) - -# Set custom secret key: -# You can either set it to a specific value or you can let horizion generate a -# default secret key that is unique on this machine, e.i. regardless of the -# amount of Python WSGI workers (if used behind Apache+mod_wsgi): However, there -# may be situations where you would want to set this explicitly, e.g. when -# multiple dashboard instances are distributed on different machines (usually -# behind a load-balancer). Either you have to make sure that a session gets all -# requests routed to the same dashboard instance or you set the same SECRET_KEY -# for all of them. -from horizon.utils import secret_key -SECRET_KEY = secret_key.generate_or_read_from_file(os.path.realpath('<%= node['openstack']['dashboard']['secret_key_path'] %>')) - -# We recommend you use memcached for development; otherwise after every reload -# of the django development server, you will have to login again. To use -# memcached set CACHES to something like -#CACHES = { -# 'default': { -# 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', -# 'LOCATION': '127.0.0.1:11211', -# }, -#} -<% case node["openstack"]["dashboard"]["session_backend"] - when "file" %> -SESSION_ENGINE = 'django.contrib.sessions.backends.file' -<% when "memcached" - if @memcached_servers && !@memcached_servers.empty? -%> -SESSION_ENGINE = 'django.contrib.sessions.backends.cache' -CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', - 'LOCATION': [ -<% @memcached_servers.each do |address| %> - '<%= address %>', -<% end %> - ] - } -} -<% end - when "sql" -%> -SESSION_ENGINE = 'django.contrib.sessions.backends.db' -<% end %> - -# Send email to the console by default -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' -# Or send them to /dev/null -#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' - -# Configure these for your outgoing email host -# EMAIL_HOST = 'smtp.my-company.com' -# EMAIL_PORT = 25 -# EMAIL_HOST_USER = 'djangomail' -# EMAIL_HOST_PASSWORD = 'top-secret!' - -# For multiple regions uncomment this configuration, and add (endpoint, title). -# AVAILABLE_REGIONS = [ -# ('http://cluster1.example.com:5000/v2.0', 'cluster1'), -# ('http://cluster2.example.com:5000/v2.0', 'cluster2'), -# ] - -OPENSTACK_HOST = "<%= @host %>" -OPENSTACK_KEYSTONE_URL = "<%= @auth_url %>" -OPENSTACK_KEYSTONE_DEFAULT_ROLE = "<%= node["openstack"]["dashboard"]["keystone_default_role"] %>" -OPENSTACK_KEYSTONE_ADMIN_ROLES = ["admin"] - -<% if node["openstack"]["dashboard"]["use_ssl"] %> -# Disable SSL certificate checks (useful for self-signed certificates): -# OPENSTACK_SSL_NO_VERIFY = True -OPENSTACK_SSL_NO_VERIFY = <%= node['openstack']['dashboard']['ssl_no_verify'] %> - -# The CA certificate to use to verify SSL connections -# OPENSTACK_SSL_CACERT = '/path/to/cacert.pem' -<% if node['openstack']['dashboard']['ssl_cacert'] %> -OPENSTACK_SSL_CACERT = '<%= node['openstack']['dashboard']['ssl_cacert'] %>' -<% end %> -<% end %> - -# The OPENSTACK_KEYSTONE_BACKEND settings can be used to identify the -# capabilities of the auth backend for Keystone. -# If Keystone has been configured to use LDAP as the auth backend then set -# can_edit_user to False and name to 'ldap'. -# -# TODO(tres): Remove these once Keystone has an API to identify auth backend. -OPENSTACK_KEYSTONE_BACKEND = { - 'name': '<%= node["openstack"]["dashboard"]["keystone_backend"]["name"] %>', - 'can_edit_user': <%= node["openstack"]["dashboard"]["keystone_backend"]["can_edit_user"] ? "True" : "False" %>, - 'can_edit_group': <%= node["openstack"]["dashboard"]["keystone_backend"]["can_edit_group"] ? "True" : "False" %>, - 'can_edit_project': <%= node["openstack"]["dashboard"]["keystone_backend"]["can_edit_project"] ? "True" : "False" %>, - 'can_edit_domain': <%= node["openstack"]["dashboard"]["keystone_backend"]["can_edit_domain"] ? "True" : "False" %>, - 'can_edit_role': <%= node["openstack"]["dashboard"]["keystone_backend"]["can_edit_role"] ? "True" : "False" %>, -} - -#Setting this to True, will add a new "Retrieve Password" action on instance, -#allowing Admin session password retrieval/decryption. -#OPENSTACK_ENABLE_PASSWORD_RETRIEVE = False - -# The Xen Hypervisor has the ability to set the mount point for volumes -# attached to instances (other Hypervisors currently do not). Setting -# can_set_mount_point to True will add the option to set the mount point -# from the UI. -OPENSTACK_HYPERVISOR_FEATURES = { - 'can_set_mount_point': False, - 'can_set_password': False, -} - -# The OPENSTACK_CINDER_FEATURES settings can be used to enable optional -# services provided by cinder that is not exposed by its extension API. -OPENSTACK_CINDER_FEATURES = { - 'enable_backup': False, -} - -# The OPENSTACK_NEUTRON_NETWORK settings can be used to enable optional -# services provided by neutron. Options currently available are load -# balancer service, security groups, quotas, VPN service. -OPENSTACK_NEUTRON_NETWORK = { - 'enable_lb': <%= node['openstack']['dashboard']['neutron']['enable_lb'].to_s.capitalize %>, - 'enable_vpn': <%= node['openstack']['dashboard']['neutron']['enable_vpn'].to_s.capitalize %>, - 'enable_quotas': <%= node['openstack']['dashboard']['neutron']['enable_quotas'] ? 'True' : 'False' %>, - # The profile_support option is used to detect if an external router can be - # configured via the dashboard. When using specific plugins the - # profile_support can be turned on if needed. - 'profile_support': None, - #'profile_support': 'cisco', - # Set which provider network types are supported. Only the network types - # in this list will be available to choose from when creating a network. - # Network types include local, flat, vlan, gre, and vxlan. - 'supported_provider_types': ['*'], -} - -# The OPENSTACK_HEAT_STACK settings can be used to disable password -# field required while launching the stack. -OPENSTACK_HEAT_STACK = { - 'enable_user_pass': <%= node['openstack']['dashboard']['heat_stack']['enable_user_pass'] ? 'True' : 'False' %>, -} - -# The OPENSTACK_IMAGE_BACKEND settings can be used to customize features -# in the OpenStack Dashboard related to the Image service, such as the list -# of supported image formats. -# OPENSTACK_IMAGE_BACKEND = { -# 'image_formats': [ -# ('', _('Select format')), -# ('aki', _('AKI - Amazon Kernel Image')), -# ('ami', _('AMI - Amazon Machine Image')), -# ('ari', _('ARI - Amazon Ramdisk Image')), -# ('iso', _('ISO - Optical Disk Image')), -# ('qcow2', _('QCOW2 - QEMU Emulator')), -# ('raw', _('Raw')), -# ('vdi', _('VDI')), -# ('vhd', _('VHD')), -# ('vmdk', _('VMDK')) -# ] -# } - -# The IMAGE_CUSTOM_PROPERTY_TITLES settings is used to customize the titles for -# image custom property attributes that appear on image detail pages. -IMAGE_CUSTOM_PROPERTY_TITLES = { - "architecture": _("Architecture"), - "kernel_id": _("Kernel ID"), - "ramdisk_id": _("Ramdisk ID"), - "image_state": _("Euca2ools state"), - "project_id": _("Project ID"), - "image_type": _("Image Type") -} - -# The IMAGE_RESERVED_CUSTOM_PROPERTIES setting is used to specify which image -# custom properties should not be displayed in the Image Custom Properties -# table. -IMAGE_RESERVED_CUSTOM_PROPERTIES = [] - -# OPENSTACK_ENDPOINT_TYPE specifies the endpoint type to use for the endpoints -# in the Keystone service catalog. Use this setting when Horizon is running -# external to the OpenStack environment. The default is 'publicURL'. -#OPENSTACK_ENDPOINT_TYPE = "publicURL" - -# SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the -# case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints -# in the Keystone service catalog. Use this setting when Horizon is running -# external to the OpenStack environment. The default is None. This -# value should differ from OPENSTACK_ENDPOINT_TYPE if used. -#SECONDARY_ENDPOINT_TYPE = "publicURL" - -# The number of objects (Swift containers/objects or images) to display -# on a single page before providing a paging element (a "more" link) -# to paginate results. -API_RESULT_LIMIT = 1000 -API_RESULT_PAGE_SIZE = 20 - -# The timezone of the server. This should correspond with the timezone -# of your entire OpenStack installation, and hopefully be in UTC. -TIME_ZONE = "UTC" - -# When launching an instance, the menu of available flavors is -# sorted by RAM usage, ascending. If you would like a different sort order, -# you can provide another flavor attribute as sorting key. Alternatively, you -# can provide a custom callback method to use for sorting. You can also provide -# a flag for reverse sort. For more info, see -# http://docs.python.org/2/library/functions.html#sorted -# CREATE_INSTANCE_FLAVOR_SORT = { -# 'key': 'name', -# # or -# 'key': my_awesome_callback_method, -# 'reverse': False, -# } - -# The Horizon Policy Enforcement engine uses these values to load per service -# policy rule files. The content of these files should match the files the -# OpenStack services are using to determine role based access control in the -# target installation. - -# Path to directory containing policy.json files -POLICY_FILES_PATH = '<%= node['openstack']['dashboard']['policy_files_path'] %>' -# Map of local copy of service policy files -#POLICY_FILES = { -# 'identity': 'keystone_policy.json', -# 'compute': 'nova_policy.json', -# 'volume': 'cinder_policy.json', -# 'image': 'glance_policy.json', -# 'orchestration': 'heat_policy.json', -# 'network': 'neutron_policy.json', -#} - -# Trove user and database extension support. By default support for -# creating users and databases on database instances is turned on. -# To disable these extensions set the permission here to something -# unusable such as ["!"]. -# TROVE_ADD_USER_PERMS = [] -# TROVE_ADD_DATABASE_PERMS = [] - -LOGGING = { - 'version': 1, - # When set to True this will disable all logging except - # for loggers specified in this configuration dictionary. Note that - # if nothing is specified here and disable_existing_loggers is True, - # django.db.backends will still log unless it is disabled explicitly. - 'disable_existing_loggers': False, - 'formatters': { - 'operation': { - # The format of "%(message)s" is defined by - # OPERATION_LOG_OPTIONS['format'] - 'format': '%(asctime)s %(message)s' - }, - }, - 'handlers': { - 'null': { - 'level': 'DEBUG', - 'class': 'logging.NullHandler', - }, - 'console': { - # Set the level to "DEBUG" for verbose output logging. - 'level': '<%= node["openstack"]["dashboard"]["debug"] ? "DEBUG" : "INFO" %>', - 'class': 'logging.StreamHandler', - }, - 'operation': { - 'level': '<%= node["openstack"]["dashboard"]["debug"] ? "DEBUG" : "INFO" %>', - 'class': 'logging.StreamHandler', - 'formatter': 'operation', - }, - }, - 'loggers': { - # Logging from django.db.backends is VERY verbose, send to null - # by default. - 'django.db.backends': { - 'handlers': ['null'], - 'propagate': False, - }, - 'requests': { - 'handlers': ['null'], - 'propagate': False, - }, - 'horizon': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["horizon"] %>', - 'propagate': False, - }, - 'horizon.operation_log': { - 'handlers': ['operation'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["horizon_log"] %>', - 'propagate': False, - }, - 'openstack_dashboard': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["openstack_dashboard"] %>', - 'propagate': False, - }, - 'novaclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["novaclient"] %>', - 'propagate': False, - }, - 'cinderclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["cinderclient"] %>', - 'propagate': False, - }, - 'keystoneclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["keystoneclient"] %>', - 'propagate': False, - }, - 'glanceclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["glanceclient"] %>', - 'propagate': False, - }, - 'neutronclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["neutronclient"] %>', - 'propagate': False, - }, - 'heatclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["heatclient"] %>', - 'propagate': False, - }, - 'ceilometerclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["ceilometerclient"] %>', - 'propagate': False, - }, - 'troveclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["troveclient"] %>', - 'propagate': False, - }, - 'swiftclient': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["swiftclient"] %>', - 'propagate': False, - }, - 'openstack_auth': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["openstack_auth"] %>', - 'propagate': False, - }, - 'nose.plugins.manager': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["nose.plugins.manager"] %>', - 'propagate': False, - }, - 'django': { - 'handlers': ['console'], - 'level': '<%= node["openstack"]["dashboard"]["log_level"]["django"] %>', - 'propagate': False, - }, - 'iso8601': { - 'handlers': ['null'], - 'propagate': False, - }, - 'scss': { - 'handlers': ['null'], - 'propagate': False, - }, - } -} - -# 'direction' should not be specified for all_tcp/udp/icmp. -# It is specified in the form. -SECURITY_GROUP_RULES = { - 'all_tcp': { - 'name': _('All TCP'), - 'ip_protocol': 'tcp', - 'from_port': '1', - 'to_port': '65535', - }, - 'all_udp': { - 'name': _('All UDP'), - 'ip_protocol': 'udp', - 'from_port': '1', - 'to_port': '65535', - }, - 'all_icmp': { - 'name': _('All ICMP'), - 'ip_protocol': 'icmp', - 'from_port': '-1', - 'to_port': '-1', - }, - 'ssh': { - 'name': 'SSH', - 'ip_protocol': 'tcp', - 'from_port': '22', - 'to_port': '22', - }, - 'smtp': { - 'name': 'SMTP', - 'ip_protocol': 'tcp', - 'from_port': '25', - 'to_port': '25', - }, - 'dns': { - 'name': 'DNS', - 'ip_protocol': 'tcp', - 'from_port': '53', - 'to_port': '53', - }, - 'http': { - 'name': 'HTTP', - 'ip_protocol': 'tcp', - 'from_port': '80', - 'to_port': '80', - }, - 'pop3': { - 'name': 'POP3', - 'ip_protocol': 'tcp', - 'from_port': '110', - 'to_port': '110', - }, - 'imap': { - 'name': 'IMAP', - 'ip_protocol': 'tcp', - 'from_port': '143', - 'to_port': '143', - }, - 'ldap': { - 'name': 'LDAP', - 'ip_protocol': 'tcp', - 'from_port': '389', - 'to_port': '389', - }, - 'https': { - 'name': 'HTTPS', - 'ip_protocol': 'tcp', - 'from_port': '443', - 'to_port': '443', - }, - 'smtps': { - 'name': 'SMTPS', - 'ip_protocol': 'tcp', - 'from_port': '465', - 'to_port': '465', - }, - 'imaps': { - 'name': 'IMAPS', - 'ip_protocol': 'tcp', - 'from_port': '993', - 'to_port': '993', - }, - 'pop3s': { - 'name': 'POP3S', - 'ip_protocol': 'tcp', - 'from_port': '995', - 'to_port': '995', - }, - 'ms_sql': { - 'name': 'MS SQL', - 'ip_protocol': 'tcp', - 'from_port': '1433', - 'to_port': '1433', - }, - 'mysql': { - 'name': 'MYSQL', - 'ip_protocol': 'tcp', - 'from_port': '3306', - 'to_port': '3306', - }, - 'rdp': { - 'name': 'RDP', - 'ip_protocol': 'tcp', - 'from_port': '3389', - 'to_port': '3389', - }, -} - -# You may remove settings from this list for security purposes, but do so at -# the risk of breaking a built-in horizon feature. These settings are required -# for horizon to function properly. Only remove them if you know what you -# are doing. These settings may in the future be moved to be defined within -# the enabled panel configuration. -# You should not add settings to this list for out of tree extensions. -# See: https://wiki.openstack.org/wiki/Horizon/RESTAPI -REST_API_REQUIRED_SETTINGS = ['OPENSTACK_HYPERVISOR_FEATURES', -'LAUNCH_INSTANCE_DEFAULTS', -'OPENSTACK_IMAGE_FORMATS'] - -# Indicate to the Sahara data processing service whether or not -# automatic floating IP allocation is in effect. If it is not -# in effect, the user will be prompted to choose a floating IP -# pool for use in their cluster. False by default. You would want -# to set this to True if you were running Nova Networking with -# auto_assign_floating_ip = True. -# SAHARA_AUTO_IP_ALLOCATION_ENABLED = False - -<% django_backends = {'mysql' => 'django.db.backends.mysql', - 'sqlite' => 'django.db.backends.sqlite3', - 'postgresql' => 'django.db.backends.postgresql_psycopg2'} - engine = django_backends[@db_info['service_type']] %> - -# A dictionary containing the settings for all databases to be used with -# Django. It is a nested dictionary whose contents maps database aliases -# to a dictionary containing the options for an individual database. -DATABASES = { - 'default': { - 'ENGINE': '<%= engine %>', - 'NAME': '<%= @db_info["db_name"] %>', -<% unless @db_info['service_type'] == 'sqlite' %> - 'USER': '<%= node["openstack"]["db"]["dashboard"]["username"] %>', - 'PASSWORD': '<%= @db_pass %>', - 'HOST': '<%= @db_info["host"] %>', - 'PORT': '<%= @db_info["port"] %>', -<% end %> - 'default-character-set': 'utf8' - }, -} - -# Boolean that decides if compression should also be done outside of the -# request/response loop - independent from user requests. This allows to -# pre-compress CSS and JavaScript files and works just like the automatic -# compression with the {% compress %} tag. -COMPRESS_OFFLINE = False - -# Add additional plugins. -<% if node["openstack"]["dashboard"]["plugins"] %> -import sys -mod = sys.modules['openstack_dashboard.settings'] -<% node["openstack"]["dashboard"]["plugins"].each do |p| %> -mod.INSTALLED_APPS += ('<%= p %>', ) -<% end %> -<% end %> - -# Allow for misc sections to be added -<% if node["openstack"]["dashboard"]["misc_local_settings"] %> -<% node["openstack"]["dashboard"]["misc_local_settings"].each do |sec, opts| %> -<%= sec %> = { -<% opts.each do |key, value| %> - '<%= key %>': <%= !!value == value ? ( value ? "True" : "False" ) : "'#{value}'" %>, -<% end %> -} -<% end %> -<% end %> - -# define a custom tmp upload directory (override /tmp) -<% if node["openstack"]["dashboard"]["file_upload_temp_dir"] %> -FILE_UPLOAD_TEMP_DIR = "<%= node["openstack"]["dashboard"]["file_upload_temp_dir"] %>" -<% end %> - -# Controls whether the keystone v2 openrc file is accessible from the user menu and the api access panel. -SHOW_KEYSTONE_V2_RC = <%= node['openstack']['dashboard']['show_keystone_v2_rc'] %> diff --git a/templates/default/rs_stylesheets.html.erb b/templates/default/rs_stylesheets.html.erb deleted file mode 100644 index 5995f0b..0000000 --- a/templates/default/rs_stylesheets.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -{% load compress %} - -{% compress css %} - -{% endcompress %} - -