From 004cd12927e70dffc890007466c9749d4213c648 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 4 Feb 2014 15:42:16 -0800 Subject: [PATCH 01/54] Rename from rs-machine_tag to rightscale_tag. --- .kitchen.yml | 4 ++-- README.md | 10 +++++----- Vagrantfile | 2 +- metadata.rb | 8 ++++---- recipes/default.rb | 2 +- recipes/monitoring.rb | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.kitchen.yml b/.kitchen.yml index b034f33..735cba7 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -17,8 +17,8 @@ platforms: suites: - name: default run_list: - - recipe[rs-machine_tag] - - recipe[rs-machine_tag::monitoring] + - recipe[rightscale_tag] + - recipe[rightscale_tag::monitoring] attributes: rightscale: instance_uuid: 01-ABCDEFG123456 diff --git a/README.md b/README.md index 0c51c02..ed15420 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# rs-machine_tag cookbook +# rightscale_tag cookbook -[![Build Status](https://travis-ci.org/rightscale-cookbooks/rs-machine_tag.png?branch=master)](https://travis-ci.org/rightscale-cookbooks/rs-machine_tag) +[![Build Status](https://travis-ci.org/rightscale-cookbooks/rightscale_tag.png?branch=master)](https://travis-ci.org/rightscale-cookbooks/rightscale_tag) This cookbook provides recipes and library methods for dealing with machine tags in RightScale. It builds on the resources and library methods in the @@ -13,7 +13,7 @@ of Instance RightScale Tags]. [List of Instance RightScale Tags]: http://support.rightscale.com/15-References/Machine_Tags/List_of_RightScale_Tags#Tags_for_Instances -Github Repository: [https://github.com/rightscale-cookbooks/rs-machine_tag](https://github.com/rightscale-cookbooks/rs-machine_tag) +Github Repository: [https://github.com/rightscale-cookbooks/rightscale_tag](https://github.com/rightscale-cookbooks/rightscale_tag) # Requirements @@ -29,14 +29,14 @@ Github Repository: [https://github.com/rightscale-cookbooks/rs-machine_tag](http # Usage -On a RightScale server, add `rs-machine_tag::default` to the run list. This will +On a RightScale server, add `rightscale_tag::default` to the run list. This will use the `node['rightscale']['instance_uuid']` attribute to create the `server:uuid` tag and the `node['cloud']['public_ips']` and `node['cloud']['private_ips']`values that come from the Ohai cloud plugin to pupulate the `server:public_ip_X` and `server:private_ip_X` tags (where `X` is 0, 1, etc.). -The `rs-machine_tag::monitoring` recipe should be placed in the run list after a +The `rightscale_tag::monitoring` recipe should be placed in the run list after a recipe setting up `collectd` or equivalent to send monitoring data to RightScale or, alternatively, used with `include_recipe` at the end of a recipe doing that. diff --git a/Vagrantfile b/Vagrantfile index 627ac61..d58706a 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -94,7 +94,7 @@ Vagrant.configure("2") do |config| } chef.run_list = [ - "recipe[rs-machine_tag::default]" + "recipe[rightscale_tag::default]" ] end end diff --git a/metadata.rb b/metadata.rb index 3434d0e..f8c854b 100644 --- a/metadata.rb +++ b/metadata.rb @@ -1,13 +1,13 @@ -name 'rs-machine_tag' +name 'rightscale_tag' maintainer 'RightScale, Inc.' maintainer_email 'cookbooks@rightscale.com' license 'Apache 2.0' -description 'Installs/Configures rs-machine_tag' +description 'Installs/Configures rightscale_tag' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '1.0.0' depends 'machine_tag', '~> 1.0.1' depends 'marker', '~> 1.0.0' -recipe 'rs-machine_tag::default', 'Tags a server with the standard RightScale server tags' -recipe 'rs-machine_tag::monitoring', 'Tags a server with the RightScale monitoring server tag' +recipe 'rightscale_tag::default', 'Tags a server with the standard RightScale server tags' +recipe 'rightscale_tag::monitoring', 'Tags a server with the RightScale monitoring server tag' diff --git a/recipes/default.rb b/recipes/default.rb index 0f1bf93..ae3bbc6 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: rs-machine_tag +# Cookbook Name:: rightscale_tag # Recipe:: default # # Copyright (C) 2013 RightScale, Inc. diff --git a/recipes/monitoring.rb b/recipes/monitoring.rb index 03896ca..f24cb35 100644 --- a/recipes/monitoring.rb +++ b/recipes/monitoring.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: rs-machine_tag +# Cookbook Name:: rightscale_tag # Recipe:: monitoring # # Copyright (C) 2013 RightScale, Inc. From 109979b5d3385b49fa627ac939a140dc07b48876 Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Tue, 4 Feb 2014 17:37:08 -0800 Subject: [PATCH 02/54] Added LWRP for three tier tags. --- .kitchen.yml | 19 +++++++++++++ providers/application.rb | 44 +++++++++++++++++++++++++++++ providers/database.rb | 42 +++++++++++++++++++++++++++ providers/load_balancer.rb | 30 ++++++++++++++++++++ recipes/test.rb | 58 ++++++++++++++++++++++++++++++++++++++ resources/application.rb | 39 +++++++++++++++++++++++++ resources/database.rb | 39 +++++++++++++++++++++++++ resources/load_balancer.rb | 30 ++++++++++++++++++++ 8 files changed, 301 insertions(+) create mode 100644 providers/application.rb create mode 100644 providers/database.rb create mode 100644 providers/load_balancer.rb create mode 100644 recipes/test.rb create mode 100644 resources/application.rb create mode 100644 resources/database.rb create mode 100644 resources/load_balancer.rb diff --git a/.kitchen.yml b/.kitchen.yml index 735cba7..fa50527 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -32,3 +32,22 @@ suites: - null - "" - 10.0.2.15 +# TODO: This suite should be refactored to load_balancer, application, and database as well as the rightscale_tag::test +# recipe should be moved to a fake cookbook as separate recipes. +- name: test + run_list: + - recipe[rightscale_tag] + - recipe[rightscale_tag::test] + attributes: + rightscale: + instance_uuid: 01-ABCDEFG123456 + cloud: + provider: vagrant + public_ips: + - null + - "" + - 33.33.33.10 + private_ips: + - null + - "" + - 10.0.2.15 diff --git a/providers/application.rb b/providers/application.rb new file mode 100644 index 0000000..213b8e2 --- /dev/null +++ b/providers/application.rb @@ -0,0 +1,44 @@ +# +# Cookbook Name:: rightscale_tag +# Provider:: application +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +# The create action that creates required tags for an application server +action :create do + [ + "application:active_#{new_resource.application_name}=true", + "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}", + "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}", + "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" + ].each do |tag| + machine_tag tag + end +end + +# The delete action that removes the application specific tags from the server +action :delete do + [ + "application:active_#{new_resource.application_name}=true", + "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}", + "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}", + "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" + ].each do |tag| + machine_tag tag do + action :delete + end + end +end diff --git a/providers/database.rb b/providers/database.rb new file mode 100644 index 0000000..9231a4b --- /dev/null +++ b/providers/database.rb @@ -0,0 +1,42 @@ +# +# Cookbook Name:: rightscale_tag +# Provider:: database +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +# The create action that creates required tags for a database server +action :create do + [ + "database:active=true", + "database:lineage=#{new_resource.lineage}", + "database:#{new_resource.role}_active=#{new_resource.timestamp}" + ].each do |tag| + machine_tag tag + end +end + +# The delete action that removes the database specific tags from the server +action :delete do + [ + "database:active=true", + "database:lineage=#{new_resource.lineage}", + "database:#{new_resource.role}_active=#{new_resource.timestamp}" + ].each do |tag| + machine_tag tag do + action :delete + end + end +end diff --git a/providers/load_balancer.rb b/providers/load_balancer.rb new file mode 100644 index 0000000..542361e --- /dev/null +++ b/providers/load_balancer.rb @@ -0,0 +1,30 @@ +# +# Cookbook Name:: rightscale_tag +# Provider:: load_balancer +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +# The create action that creates required tags for a load balancer server +action :create do + machine_tag "load_balancer:active_#{new_resource.application_name}=true" +end + +# The delete action that removes the load balancer specific tags from the server +action :delete do + machine_tag "load_balancer:active_#{new_resource.application_name}=true" do + action :delete + end +end diff --git a/recipes/test.rb b/recipes/test.rb new file mode 100644 index 0000000..88271e7 --- /dev/null +++ b/recipes/test.rb @@ -0,0 +1,58 @@ +# +# Cookbook Name:: rightscale_tag +# Recipe:: test +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +delete = false + +marker "recipe_start_rightscale" do + template "rightscale_audit_entry.erb" +end + +## Database +rightscale_tag_database 'master' do + lineage 'production' + timestamp 1391473172 + action delete == true ? :delete : :create +end + +## Application + +rightscale_tag_application 'www' do + bind_ip_address '10.0.0.1' + bind_port 8080 + vhost_path 'www.example.com' + action delete == true ? :delete : :create +end + +rightscale_tag_application 'api server' do + application_name 'api' + bind_ip_address '10.0.0.2' + bind_port 80 + vhost_path '/api' + action delete == true ? :delete : :create +end + +## Load Balancer +rightscale_tag_load_balancer 'www' do + action delete == true ? :delete : :create +end + +rightscale_tag_load_balancer 'api server' do + application_name 'api' + action delete == true ? :delete : :create +end diff --git a/resources/application.rb b/resources/application.rb new file mode 100644 index 0000000..4706107 --- /dev/null +++ b/resources/application.rb @@ -0,0 +1,39 @@ +# +# Cookbook Name:: rightscale_tag +# Resource:: application +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +# The name of the application +attribute :application_name, :kind_of => String, :name_attribute => true + +# The bind IP address of the application +attribute :bind_ip_address, :kind_of => String, :required => true + +# The bind port of the application +attribute :bind_port, :kind_of => Fixnum, :required => true + +# The vhost path of the application. Examples: `'api.example.com'`, `'/api'` +attribute :vhost_path, :kind_of => String, :required => true + +# Creates the required tags for the application server +actions :create + +# Removes the tags from the application server +actions :delete + +# The default action is :create +default_action :create diff --git a/resources/database.rb b/resources/database.rb new file mode 100644 index 0000000..e8732fe --- /dev/null +++ b/resources/database.rb @@ -0,0 +1,39 @@ +# +# Cookbook Name:: rightscale_tag +# Resource:: database +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +# The role of the database server. This attribute should only contain alphanumeric characters and underscores and +# should start with a letter. +# +attribute :role, :kind_of => String, :regex => /^[a-z][a-z0-9_]*$/i, :name_attribute => true + +# The lineage of the database server +attribute :lineage, :kind_of => String + +# The timestamp used to create the _active tag. This tag represents that the server is in the specified role +# since this timestamp +attribute :timestamp, :kind_of => Fixnum + +# Creates the required tags for the database server +actions :create + +# Removes the tags from the database server +actions :delete + +# The default action is :create +default_action :create diff --git a/resources/load_balancer.rb b/resources/load_balancer.rb new file mode 100644 index 0000000..90cc645 --- /dev/null +++ b/resources/load_balancer.rb @@ -0,0 +1,30 @@ +# +# Cookbook Name:: rightscale_tag +# Resource:: load_balancer +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +# The name of the application the load balancer will serve +attribute :application_name, :kind_of => String, :name_attribute => true + +# Creates the required tags for the load balancer server +actions :create + +# Removes the tags from the load balancer server +actions :delete + +# The default action is :create +default_action :create From 4b3087b3e7de3f8dd3005a4bf5bc0e54baeaad3e Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Tue, 4 Feb 2014 17:52:43 -0800 Subject: [PATCH 03/54] Fixed foodcritic failures regarding resource notifications. --- providers/application.rb | 2 ++ providers/database.rb | 2 ++ providers/load_balancer.rb | 2 ++ 3 files changed, 6 insertions(+) diff --git a/providers/application.rb b/providers/application.rb index 213b8e2..d4b42b8 100644 --- a/providers/application.rb +++ b/providers/application.rb @@ -27,6 +27,7 @@ ].each do |tag| machine_tag tag end + new_resource.updated_by_last_action(true) end # The delete action that removes the application specific tags from the server @@ -41,4 +42,5 @@ action :delete end end + new_resource.updated_by_last_action(true) end diff --git a/providers/database.rb b/providers/database.rb index 9231a4b..10fcde8 100644 --- a/providers/database.rb +++ b/providers/database.rb @@ -26,6 +26,7 @@ ].each do |tag| machine_tag tag end + new_resource.updated_by_last_action(true) end # The delete action that removes the database specific tags from the server @@ -39,4 +40,5 @@ action :delete end end + new_resource.updated_by_last_action(true) end diff --git a/providers/load_balancer.rb b/providers/load_balancer.rb index 542361e..3b60e1e 100644 --- a/providers/load_balancer.rb +++ b/providers/load_balancer.rb @@ -20,6 +20,7 @@ # The create action that creates required tags for a load balancer server action :create do machine_tag "load_balancer:active_#{new_resource.application_name}=true" + new_resource.updated_by_last_action(true) end # The delete action that removes the load balancer specific tags from the server @@ -27,4 +28,5 @@ machine_tag "load_balancer:active_#{new_resource.application_name}=true" do action :delete end + new_resource.updated_by_last_action(true) end From 9643c7dab3c8536c3aaaa6b2b1dbab45d315d898 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 4 Feb 2014 18:49:48 -0800 Subject: [PATCH 04/54] Progress on helpers. --- libraries/rightscale_tag_helper.rb | 190 +++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 libraries/rightscale_tag_helper.rb diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb new file mode 100644 index 0000000..6964937 --- /dev/null +++ b/libraries/rightscale_tag_helper.rb @@ -0,0 +1,190 @@ +# +# Cookbook Name:: rightscale_tag +# Helper:: rightscale_tag_helper +# +# Copyright (C) 2014 RightScale, Inc. +# +# 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 + module RightscaleTag + # Finds all load balancers if no name is given and finds + # load balancers matching the application_name if the application_name + # is given. The options hash is passed to the underlying machine_tag + # resource + # + # @param node + # @param application_name + # + # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation + # + # @return [Hash] Information about all matching load balancer servers + # + # @see http://rubydoc.info/gems/machine_tag/#MachineTag__Set MachineTag::Set + # + # @example Example Hash output + # + # { + # 'UUID-1': { + # 'tags': MachineTag::Set, + # 'application_names': [], + # 'private_ips': [], + # 'public_ips': [] + # } + # } + # + def find_load_balancer_servers(node, application_name = nil, options = {}) + required_tags(options) + + if application_name + query_tag = ::MachineTag::Tag.machine_tag('load_balancer', "active_#{application_name}", true) + else + query_tag = 'load_balancer:' + end + + servers = tag_search(node, query_tag, options) + + unless application_name + servers.reject! do |tags| + tags[/^load_balancer:active_.+$/].empty? + end + end + + build_server_hash(servers) do |tags| + # + end + end + + # Finds all application servers if no application name is given and finds + # application servers matching the application_name if the application_name + # is given. + # + # @param node + # @param application_name + # + # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation + # + # @return [Hash] Information about all matching application servers + # + # @see http://rubydoc.info/gems/machine_tag/#MachineTag__Set MachineTag::Set + # + # @example Example Hash output + # + # { + # 'UUID-1': { + # 'tags': MachineTag::Set, + # 'applications': { + # 'APP-1': { + # 'bind_address': 'IP:PORT', + # 'ip': 'IP', + # 'port': 'PORT', + # 'vhost_path': 'VHOST_PATH', + # } + # }, + # 'private_ips': [], + # 'public_ips': [] + # } + # } + # + # + def find_application_servers(node, application_name = nil, options = {}) + required_tags(options) + + if application_name + query_tag = ::MachineTag::Tag.machine_tag('application', "active_#{application_name}", true) + required_tags(options, + ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{application_name}", '*'), + ::MachineTag::Tag.machine_tag('application', "bind_port_#{application_name}", '*'), + ::MachineTag::Tag.machine_tag('application', "vhost_path_#{application_name}", '*') + ) + else + query_tag = 'application:' + end + + servers = tag_search(node, query_tag, options) + + unless application_name + servers.reject! do |tags| + tags[/^application:active_.+$/].empty? + end + end + + build_server_hash(servers) do |tags| + # + end + end + + # + # @param node + # @param lineage [String] the lineage used to filter database servers + # @param role [Symbol] the role to filter. Valid values are `:master` and `:slave` + # + # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation + # + # @return [Hash] Information about all matching database servers + # + # @see http://rubydoc.info/gems/machine_tag/#MachineTag__Set MachineTag::Set + # + # @example Example Hash Output + # + # { + # 'UUID-1': { + # 'tags': MachineTag::Set, + # 'lineage': 'LINEAGE', + # 'role': 'ROLE', + # 'master_since': Time, # Only for master servers + # 'slave_since': Time, # Only for slave servers + # 'private_ips': [], + # 'public_ips': [] + # } + # } + # + def find_database_servers(node, lineage = nil, role = nil, options = {}) + required_tags(options) + + if role + query_tag = ::MachineTag::Tag.machine_tag('database', "#{role}_active", '*') + required_tags(options, ::MachineTag::Tag.machine_tag('database', 'active', true)) + else + query_tag = ::MachineTag::Tag.machine_tag('database', 'active', true) + end + required_tags(options, ::MachineTag::Tag.machine_tag('database', 'lineage', '*')) + + servers = tag_search(node, query_tag, options) + + if lineage + servers.reject! do |tags| + !tags.include?(::MachineTag::Tag.machine_tag('database', 'lineage', lineage)) + end + end + + build_server_hash(servers) do |tags| + # + end + end + + private + + def required_tags(options, *tags) + require 'set' + + options[:required_tags] ||= Set['server:uuid'] + options[:required_tags] += tags + end + + def build_server_hash(servers, &block) + # + end + end +end From 01cf97397715746258a4233e0e9019007e9bc15f Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Wed, 5 Feb 2014 14:35:46 -0800 Subject: [PATCH 05/54] The database resource will take a Time object. --- resources/database.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/database.rb b/resources/database.rb index e8732fe..17f5592 100644 --- a/resources/database.rb +++ b/resources/database.rb @@ -27,7 +27,7 @@ # The timestamp used to create the _active tag. This tag represents that the server is in the specified role # since this timestamp -attribute :timestamp, :kind_of => Fixnum +attribute :timestamp, :kind_of => [Time, Fixnum] # Creates the required tags for the database server actions :create From 0cf9e5cfc07fb225bb57f8a2773b354cdf9f775c Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Wed, 5 Feb 2014 15:28:16 -0800 Subject: [PATCH 06/54] Implemented build_server_hash callbacks. --- libraries/rightscale_tag_helper.rb | 70 +++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 6964937..a43a16c 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -62,7 +62,12 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) end build_server_hash(servers) do |tags| - # + application_names = tags[/^load_balancer:active_.+$/].map do |tag| + next if tag.value != 'true' + tag.predicate.gsub(/^active_/, '') + end + + {'application_names' => application_names.compact} end end @@ -86,9 +91,8 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) # 'tags': MachineTag::Set, # 'applications': { # 'APP-1': { - # 'bind_address': 'IP:PORT', - # 'ip': 'IP', - # 'port': 'PORT', + # 'bind_ip_address': 'IP', + # 'bind_port': PORT, # 'vhost_path': 'VHOST_PATH', # } # }, @@ -121,7 +125,23 @@ def find_application_servers(node, application_name = nil, options = {}) end build_server_hash(servers) do |tags| - # + application_hashes = tags[/^application:active_.+$/].map do |tag| + next if tag.value != 'true' + application_name = tag.predicate.gsub(/^active_/, '') + application_hash = {} + + bind_ip_address = tags['application', "bind_ip_address_#{application_name}"].first + bind_port = tags['application', "bind_port_#{application_name}"].first + vhost_path = tags['application', "vhost_path_#{application_name}"].first + + application_hash['bind_ip_address'] = bind_ip_address.value if bind_ip_address + application_hash['bind_port'] = bind_port.value.to_i if bind_port + application_hash['vhost_path'] = vhost_path.value if vhost_path + + [application_name, application_hash] + end + + {'applications' => Hash[application_hashes.compact]} end end @@ -170,7 +190,30 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) end build_server_hash(servers) do |tags| - # + server_hash = {'lineage' => tags['database:lineage'].first.value} + master_active = tags['database:master_active'].first + slave_active = tags['database:slave_active'].first + + if master_active && slave_active + master_since = Time.at(master_active.value.to_i) + slave_since = Time.at(slave_active.value.to_i) + + if master_since >= slave_since + server_hash['role'] = 'master' + server_hash['master_since'] = master_since + else + server_hash['role'] = 'slave' + server_hash['slave_since]'] = slave_since + end + elsif master_active + server_hash['role'] = 'master' + server_hash['master_since'] = Time.at(master_active.value.to_i) + elsif slave_active + server_hash['role'] = 'slave' + server_hash['slave_since'] = Time.at(slave_active.value.to_i) + end + + server_hash end end @@ -184,7 +227,20 @@ def required_tags(options, *tags) end def build_server_hash(servers, &block) - # + server_hashes = servers.map do |tags| + uuid = tags['server:uuid'].first.value + server_hash = { + 'tags' => tags, + 'public_ips' => tags[/^server:public_ip_\d+$/].map { |tag| tag.value }, + 'private_ips' => tags[/^server:private_ip_\d+$/].map { |tag| tag.value }, + } + + server_hash.merge!(block.call(tags)) if block + + [uuid, server_hash] + end + + Hash[server_hashes] end end end From 41641e6a3dc29147b332c0e3de1e0187ea90fe85 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Wed, 5 Feb 2014 16:24:06 -0800 Subject: [PATCH 07/54] Call tag_search correctly. --- libraries/rightscale_tag_helper.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index a43a16c..ec96ba8 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -53,7 +53,7 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) query_tag = 'load_balancer:' end - servers = tag_search(node, query_tag, options) + servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) unless application_name servers.reject! do |tags| @@ -116,7 +116,7 @@ def find_application_servers(node, application_name = nil, options = {}) query_tag = 'application:' end - servers = tag_search(node, query_tag, options) + servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) unless application_name servers.reject! do |tags| @@ -181,7 +181,7 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) end required_tags(options, ::MachineTag::Tag.machine_tag('database', 'lineage', '*')) - servers = tag_search(node, query_tag, options) + servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) if lineage servers.reject! do |tags| @@ -219,6 +219,13 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) private + # Adds required tags to the options for Chef::MachineTagHelper#tag_search that are needed for the various + # `find_*_servers` methods. By default it will add `server:uuid`, any other requirements need to be passed + # as additional arguments. This method can be called multiple times to add further tag requirements. + # + # @param options [Hash] the options hash to populate + # @param tags [Array] the required tags + # def required_tags(options, *tags) require 'set' From 5288c5c3823b8f9659fd853a35a405b3dab07d68 Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Wed, 5 Feb 2014 18:02:13 -0800 Subject: [PATCH 08/54] Initial progress on writing some unit tests. --- Gemfile | 1 + spec/spec_helper.rb | 25 ++++++ spec/unit_test/rightscale_tag_helper_spec.rb | 88 ++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 spec/spec_helper.rb create mode 100644 spec/unit_test/rightscale_tag_helper_spec.rb diff --git a/Gemfile b/Gemfile index 7501090..bc354a5 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ gem 'berkshelf' gem 'thor-foodcritic' group :integration do + gem 'machine_tag' gem 'test-kitchen', '~> 1.1.0' gem 'kitchen-vagrant' gem 'strainer', '~> 3.3.0' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..b322748 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,25 @@ +# +# Cookbook Name:: rightscale_tag +# Spec:: spec_helper +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +lib = File.expand_path('../../libraries', __FILE__) +$:.unshift(lib) unless $:.include?(lib) + +require 'chefspec' +require 'rightscale_tag_helper' +require 'machine_tag' diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb new file mode 100644 index 0000000..5bb83ff --- /dev/null +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -0,0 +1,88 @@ +# +# Cookbook Name:: rightscale_tag +# Spec:: rightscale_tag_helper_spec +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +require 'spec_helper' + +describe Chef::RightscaleTag do + let(:node) do + node = Chef::Node.new + node.set['cloud']['provider'] = 'some_cloud' + node + end + + class Chef::MachineTagHelper; end + + class Fake; end + + let(:fake) do + fake_obj = Fake.new + fake_obj.extend(Chef::RightscaleTag) + fake_obj + end + + + describe '.find_load_balancer_servers' do + let(:load_balancer_1) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8911IT', + 'load_balancer:active_www=true', + 'load_balancer:active_api=true', + 'server:public_ip_0=157.56.165.202', + 'server:public_ip_1=157.56.165.203', + 'server:private_ip_0=10.0.0.1', + ] + end + + let(:load_balancer_2) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8922IT', + 'load_balancer:active_api=true', + 'server:public_ip_0=157.56.166.202', + 'server:public_ip_1=157.56.166.203', + ] + end + + context 'when no application name is specified' do + let(:tags) do + [load_balancer_1, load_balancer_2] + end + + it 'should return tags from all load balancer servers' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'load_balancer:', {:required_tags => Set['server:uuid']} + ).and_return(tags) + response = fake.find_load_balancer_servers(node) + + # TODO: Remove me + print response.pretty_inspect + response.should include('01-83PJQDO8911IT') + response['01-83PJQDO8911IT']['tags'].should eq(load_balancer_1) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['application_names'].should eq(['www', 'api']) + + response.should include('01-83PJQDO8922IT') + response['01-83PJQDO8922IT']['tags'].should eq(load_balancer_2) + response['01-83PJQDO8922IT']['private_ips'].should be_empty + response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) + response['01-83PJQDO8922IT']['application_names'].should eq(['api']) + end + end + end +end From d8115121b2c9c07d51b2aad07be2ba84820ff609 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Thu, 6 Feb 2014 11:05:55 -0800 Subject: [PATCH 09/54] Add rspec to Strainerfile. --- Strainerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Strainerfile b/Strainerfile index f4bc7f9..54b8e34 100644 --- a/Strainerfile +++ b/Strainerfile @@ -1,3 +1,4 @@ knife: bundle exec knife cookbook test $COOKBOOK foodcritic: bundle exec foodcritic --epic-fail any $SANDBOX/$COOKBOOK +rspec: bundle exec rspec --color --format documentation kitchen: bundle exec kitchen test From 33474440bda9cef08fe32a35116706a1f13d3e89 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Thu, 6 Feb 2014 14:23:33 -0800 Subject: [PATCH 10/54] Checkpoint of documentation work. --- .gitignore | 3 +++ .yardopts | 1 + libraries/rightscale_tag_helper.rb | 7 +++++++ 3 files changed, 11 insertions(+) create mode 100644 .yardopts diff --git a/.gitignore b/.gitignore index 13c7d4b..642b280 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,7 @@ VERSION .kitchen/ .kitchen.local.yml +.yardoc +doc + cache_dir/ diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..29c933b --- /dev/null +++ b/.yardopts @@ -0,0 +1 @@ +--markup markdown diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index ec96ba8..52d9d31 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -233,6 +233,13 @@ def required_tags(options, *tags) options[:required_tags] += tags end + # Builds an array of server information hashes to be returned by the `find_*_servers` methods. A callback + # block can be passed to further populate each server information hash from each tag set. + # + # @param servers [Array] the array of tag sets returned by Chef::MachineTagHelper#tag_search + # @param block [Proc(MachineTag::Set)] a block that does further processing on each tag set; it should + # return a hash that will be merged into the server information hash + # def build_server_hash(servers, &block) server_hashes = servers.map do |tags| uuid = tags['server:uuid'].first.value From b3a11fa30684d5778d036fa175842d00f6089adb Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 7 Feb 2014 10:37:28 -0800 Subject: [PATCH 11/54] Support calling as class methods and don't polute Chef namespace. --- libraries/rightscale_tag_helper.rb | 26 ++++++++++++++------ spec/unit_test/rightscale_tag_helper_spec.rb | 5 ++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 52d9d31..dff20c3 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -17,7 +17,7 @@ # limitations under the License. # -class Chef +module Rightscale module RightscaleTag # Finds all load balancers if no name is given and finds # load balancers matching the application_name if the application_name @@ -44,7 +44,7 @@ module RightscaleTag # } # } # - def find_load_balancer_servers(node, application_name = nil, options = {}) + def self.find_load_balancer_servers(node, application_name = nil, options = {}) required_tags(options) if application_name @@ -71,6 +71,10 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) end end + def find_load_balancer_servers(node, application_name = nil, options = {}) + Rightscale::RightscaleTag.find_load_balancer_servers(node, application_name, options) + end + # Finds all application servers if no application name is given and finds # application servers matching the application_name if the application_name # is given. @@ -102,7 +106,7 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) # } # # - def find_application_servers(node, application_name = nil, options = {}) + def self.find_application_servers(node, application_name = nil, options = {}) required_tags(options) if application_name @@ -145,6 +149,10 @@ def find_application_servers(node, application_name = nil, options = {}) end end + def find_application_servers(node, application_name = nil, options = {}) + Rightscale::RightscaleTag.find_application_servers(node, application_name, options) + end + # # @param node # @param lineage [String] the lineage used to filter database servers @@ -170,7 +178,7 @@ def find_application_servers(node, application_name = nil, options = {}) # } # } # - def find_database_servers(node, lineage = nil, role = nil, options = {}) + def self.find_database_servers(node, lineage = nil, role = nil, options = {}) required_tags(options) if role @@ -217,6 +225,10 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) end end + def find_database_servers(node, lineage = nil, role = nil, options = {}) + Rightscale::RightscaleTag.find_database_servers(node, lineage, role, options) + end + private # Adds required tags to the options for Chef::MachineTagHelper#tag_search that are needed for the various @@ -226,7 +238,7 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) # @param options [Hash] the options hash to populate # @param tags [Array] the required tags # - def required_tags(options, *tags) + def self.required_tags(options, *tags) require 'set' options[:required_tags] ||= Set['server:uuid'] @@ -240,7 +252,7 @@ def required_tags(options, *tags) # @param block [Proc(MachineTag::Set)] a block that does further processing on each tag set; it should # return a hash that will be merged into the server information hash # - def build_server_hash(servers, &block) + def self.build_server_hash(servers, &block) server_hashes = servers.map do |tags| uuid = tags['server:uuid'].first.value server_hash = { @@ -254,7 +266,7 @@ def build_server_hash(servers, &block) [uuid, server_hash] end - Hash[server_hashes] + Mash.from_hash(Hash[server_hashes]) end end end diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 5bb83ff..f93aca3 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -19,7 +19,7 @@ require 'spec_helper' -describe Chef::RightscaleTag do +describe Rightscale::RightscaleTag do let(:node) do node = Chef::Node.new node.set['cloud']['provider'] = 'some_cloud' @@ -32,11 +32,10 @@ class Fake; end let(:fake) do fake_obj = Fake.new - fake_obj.extend(Chef::RightscaleTag) + fake_obj.extend(Rightscale::RightscaleTag) fake_obj end - describe '.find_load_balancer_servers' do let(:load_balancer_1) do MachineTag::Set[ From a885a2f1e0ac92f994aab70cd8d68a8470419009 Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Fri, 7 Feb 2014 12:14:54 -0800 Subject: [PATCH 12/54] Finished unit tests for load balancers and application servers. --- spec/unit_test/rightscale_tag_helper_spec.rb | 173 ++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-) diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index f93aca3..d5d41f0 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -62,14 +62,12 @@ class Fake; end [load_balancer_1, load_balancer_2] end - it 'should return tags from all load balancer servers' do + it 'returns tags from all load balancer servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'load_balancer:', {:required_tags => Set['server:uuid']} ).and_return(tags) response = fake.find_load_balancer_servers(node) - # TODO: Remove me - print response.pretty_inspect response.should include('01-83PJQDO8911IT') response['01-83PJQDO8911IT']['tags'].should eq(load_balancer_1) response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) @@ -83,5 +81,174 @@ class Fake; end response['01-83PJQDO8922IT']['application_names'].should eq(['api']) end end + + context 'when an application name is specified and the application is available' do + let(:tags) do + [load_balancer_1, load_balancer_2] + end + + it 'returns tags from the matching load balancer server' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'load_balancer:active_www=true', {:required_tags => Set['server:uuid']} + ).and_return(tags) + response = fake.find_load_balancer_servers(node, 'www') + + response.should include('01-83PJQDO8911IT') + response['01-83PJQDO8911IT']['tags'].should eq(load_balancer_1) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['application_names'].should eq(['www', 'api']) + end + end + + context 'when an application name is specified and the application is not available' do + let(:tags) { [] } + + it 'returns an empty Mash' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'load_balancer:active_www=true', {:required_tags => Set['server:uuid']} + ).and_return(tags) + response = fake.find_load_balancer_servers(node, 'www') + + response.should be_an_instance_of(Mash) + response.should be_empty + end + end + end + + describe '.find_application_servers' do + let(:application_server_1) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8911IT', + 'application:active_www=true', + 'application:active_api=true', + 'application:bind_ip_address_www=157.56.165.202', + 'application:bind_ip_address_api=157.56.165.203', + 'application:bind_port_www=80', + 'application:bind_port_api=80', + 'application:vhost_path_www=/', + 'application:vhost_path_api=api.example.com', + 'server:public_ip_0=157.56.165.202', + 'server:public_ip_1=157.56.165.203', + 'server:private_ip_0=10.0.0.1', + ] + end + + let(:application_server_2) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8922IT', + 'application:active_api=true', + 'application:bind_ip_address_api=157.56.166.202', + 'application:bind_port_api=443', + 'application:vhost_path_api=api.example.com', + 'server:public_ip_0=157.56.166.202', + 'server:public_ip_1=157.56.166.203', + ] + end + + let(:www_attributes_1) do + Mash.from_hash( + 'bind_ip_address' => '157.56.165.202', + 'bind_port' => 80, + 'vhost_path' => '/' + ) + end + + let(:api_attributes_1) do + Mash.from_hash( + 'bind_ip_address' => '157.56.165.203', + 'bind_port' => 80, + 'vhost_path' => 'api.example.com' + ) + end + + let(:api_attributes_2) do + Mash.from_hash( + 'bind_ip_address' => '157.56.166.202', + 'bind_port' => 443, + 'vhost_path' => 'api.example.com' + ) + end + + context 'when no application name is specified' do + let(:tags) do + [application_server_1, application_server_2] + end + + it 'returns tags of all application servers' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'application:', + {:required_tags => Set['server:uuid']} + ).and_return(tags) + response = fake.find_application_servers(node) + + response.should include('01-83PJQDO8911IT') + response['01-83PJQDO8911IT']['tags'].should eq(application_server_1) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['applications'].should be_an_instance_of(Mash) + response['01-83PJQDO8911IT']['applications']['www'].should eq(www_attributes_1) + + response.should include('01-83PJQDO8922IT') + response['01-83PJQDO8922IT']['tags'].should eq(application_server_2) + response['01-83PJQDO8922IT']['private_ips'].should eq([]) + response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) + response['01-83PJQDO8922IT']['applications'].should be_an_instance_of(Mash) + response['01-83PJQDO8922IT']['applications']['api'].should eq(api_attributes_2) + end + end + + context 'when an application name is specified and the application is available' do + let(:tags) do + [application_server_1, application_server_2] + end + + it 'returns tags of matching application servers' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'application:active_www=true', + {:required_tags => Set[ + 'server:uuid', + 'application:bind_ip_address_www=*', + 'application:bind_port_www=*', + 'application:vhost_path_www=*' + ]} + ).and_return(tags) + response = fake.find_application_servers(node, 'www') + + response.should include('01-83PJQDO8911IT') + response['01-83PJQDO8911IT']['tags'].should eq(application_server_1) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['applications'].should be_an_instance_of(Mash) + response['01-83PJQDO8911IT']['applications']['www'].should eq(www_attributes_1) + + response.should include('01-83PJQDO8922IT') + response['01-83PJQDO8922IT']['tags'].should eq(application_server_2) + response['01-83PJQDO8922IT']['private_ips'].should eq([]) + response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) + response['01-83PJQDO8922IT']['applications'].should be_an_instance_of(Mash) + response['01-83PJQDO8922IT']['applications']['api'].should eq(api_attributes_2) + end + end + + context 'when an application name is specified and the application is not available' do + let(:tags) { [] } + + it 'returns an empty Mash' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'application:active_www=true', + {:required_tags => Set[ + 'server:uuid', + 'application:bind_ip_address_www=*', + 'application:bind_port_www=*', + 'application:vhost_path_www=*' + ]} + ).and_return(tags) + response = fake.find_application_servers(node, 'www') + + response.should be_an_instance_of(Mash) + response.should be_empty + end + end end end From 75c7f1fe2f78d78ef278376b642d81c9fc7123dd Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 7 Feb 2014 13:48:54 -0800 Subject: [PATCH 13/54] Finish up YARD docs. --- libraries/rightscale_tag_helper.rb | 171 +++++++++++++++++++++-------- 1 file changed, 128 insertions(+), 43 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index dff20c3..ce0fbc8 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -19,28 +19,32 @@ module Rightscale module RightscaleTag - # Finds all load balancers if no name is given and finds - # load balancers matching the application_name if the application_name - # is given. The options hash is passed to the underlying machine_tag - # resource + # Find load balancer servers using tags. This will find all active load balancer servers, or, if + # `application_name` is given, it will find all load balancer servers serving for that application. # - # @param node - # @param application_name + # @param node [Chef::Node] the Chef node + # @param application_name [String, nil] the name of the application served by load balancer servers + # to search for # # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation # - # @return [Hash] Information about all matching load balancer servers + # @return [Mash] a hash with server UUIDs as keys and server information hashes as values # # @see http://rubydoc.info/gems/machine_tag/#MachineTag__Set MachineTag::Set # - # @example Example Hash output + # @example Example server hash # # { - # 'UUID-1': { - # 'tags': MachineTag::Set, - # 'application_names': [], - # 'private_ips': [], - # 'public_ips': [] + # '01-ABCDEF123456' => { + # 'tags' => MachineTag::Set[ + # 'load_balancer:active_www=true', + # 'server:public_ip_0=203.0.113.2', + # 'server:private_ip_0=10.0.0.2', + # 'server:uuid=01-ABCDEF123456' + # ], + # 'application_names' => ['www'], + # 'public_ips' => ['203.0.113.2'], + # 'private_ips' => ['10.0.0.2'] # } # } # @@ -71,37 +75,58 @@ def self.find_load_balancer_servers(node, application_name = nil, options = {}) end end + # Find load balancer servers using tags. This will find all active load balancer servers, or, if + # `application_name` is given, it will find all load balancer servers serving for that application. + # + # @param node [Chef::Node] the Chef node + # @param application_name [String, nil] the name of the application served by load balancer servers + # to search for + # + # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation + # + # @return [Mash] a hash with server UUIDs as keys and server information hashes as values + # + # @see .find_load_balancer_servers + # def find_load_balancer_servers(node, application_name = nil, options = {}) Rightscale::RightscaleTag.find_load_balancer_servers(node, application_name, options) end - # Finds all application servers if no application name is given and finds - # application servers matching the application_name if the application_name - # is given. + # Find application servers using tags. This will find all active application servers, or, if + # `application_name` is given, it will find all application servers serving that application. # - # @param node - # @param application_name + # @param node [Chef::Node] the Chef node + # @param application_name [String, nil] the name of the application server by the application servers + # to search for # # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation # - # @return [Hash] Information about all matching application servers + # @return [Mash] a hash with server UUIDs as keys and server information hashes as values # # @see http://rubydoc.info/gems/machine_tag/#MachineTag__Set MachineTag::Set # - # @example Example Hash output + # @example Example server hash # # { - # 'UUID-1': { - # 'tags': MachineTag::Set, - # 'applications': { - # 'APP-1': { - # 'bind_ip_address': 'IP', - # 'bind_port': PORT, - # 'vhost_path': 'VHOST_PATH', + # '01-ABCDEF7890123' => { + # 'tags' => MachineTag::Set[ + # 'application:active_www=true', + # 'application:bind_ip_address_www=10.0.0.3', + # 'application:bind_port_www=8080', + # 'application:vhost_path_www=/', + # 'server:public_ip_0=203.0.113.3', + # 'server:private_ip_0=10.0.0.3', + # 'server:uuid=01-ABCDEF7890123' + # ], + # 'applications' => { + # 'www' => { + # 'bind_ip_address' => '10.0.0.3', + # 'bind_port' => 8080, + # 'vhost_path' => '/', # } # }, - # 'private_ips': [], - # 'public_ips': [] + # 'public_ips' => ['203.0.113.3'], + # 'private_ips' => ['10.0.0.3'] # } # } # @@ -149,32 +174,75 @@ def self.find_application_servers(node, application_name = nil, options = {}) end end + # Find application servers using tags. This will find all active application servers, or, if + # `application_name` is given, it will find all application servers serving that application. + # + # @param node [Chef::Node] the Chef node + # @param application_name [String, nil] the name of the application server by the application servers + # to search for + # + # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation + # + # @return [Mash] a hash with server UUIDs as keys and server information hashes as values + # + # @see .find_application_servers + # def find_application_servers(node, application_name = nil, options = {}) Rightscale::RightscaleTag.find_application_servers(node, application_name, options) end + # Find database servers using tags. This will find all active database servers, or, if `lineage` is + # given, it will find all database servers for that linage, or, if `role` is specified it will find + # the database server(s) with that role. # - # @param node - # @param lineage [String] the lineage used to filter database servers - # @param role [Symbol] the role to filter. Valid values are `:master` and `:slave` + # @param node [Chef::Node] the Chef node + # @param lineage [String] the lineage of the database servers to search for + # @param role [Symbol, String] the role of the database servers to search for; this should be `:master` + # or `:slave` # # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation # - # @return [Hash] Information about all matching database servers + # @return [Mash] a hash with server UUIDs as keys and server information hashes as values # # @see http://rubydoc.info/gems/machine_tag/#MachineTag__Set MachineTag::Set # - # @example Example Hash Output + # @example Example master server hash # # { - # 'UUID-1': { - # 'tags': MachineTag::Set, - # 'lineage': 'LINEAGE', - # 'role': 'ROLE', - # 'master_since': Time, # Only for master servers - # 'slave_since': Time, # Only for slave servers - # 'private_ips': [], - # 'public_ips': [] + # '01-ABCDEF4567890' => { + # 'tags' => MachineTag::Set[ + # 'database:active=true', + # 'database:master_active=1391803034', + # 'database:lineage=example', + # 'server:public_ip_0=203.0.113.4', + # 'server:private_ip_0=10.0.0.4', + # 'server:uuid=01-ABCDEF4567890' + # ], + # 'lineage' => 'example', + # 'role' => 'master', + # 'master_since' => Time.at(1391803034), + # 'public_ips' => ['203.0.113.4'], + # 'private_ips' => ['10.0.0.4'] + # } + # } + # + # @example Example slave server hash + # + # { + # '01-GHIJKL1234567' => { + # 'tags' => MachineTag::Set[ + # 'database:active=true', + # 'database:slave_active=1391803892', + # 'database:lineage=example', + # 'server:public_ip_0=203.0.113.5', + # 'server:private_ip_0=10.0.0.5', + # 'server:uuid=01-GHIJKL1234567' + # ], + # 'lineage' => 'example', + # 'role' => 'slave', + # 'slave_since' => Time.at(1391803892), + # 'public_ips' => ['203.0.113.5'], + # 'private_ips' => ['10.0.0.5'] # } # } # @@ -225,6 +293,21 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) end end + # Find database servers using tags. This will find all active database servers, or, if `lineage` is + # given, it will find all database servers for that linage, or, if `role` is specified it will find + # the database server(s) with that role. + # + # @param node [Chef::Node] the Chef node + # @param lineage [String] the lineage of the database servers to search for + # @param role [Symbol, String] the role of the database servers to search for; this should be `:master` + # or `:slave` + # + # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation + # + # @return [Mash] a hash with server UUIDs as keys and server information hashes as values + # + # @see .find_database_servers + # def find_database_servers(node, lineage = nil, role = nil, options = {}) Rightscale::RightscaleTag.find_database_servers(node, lineage, role, options) end @@ -245,13 +328,15 @@ def self.required_tags(options, *tags) options[:required_tags] += tags end - # Builds an array of server information hashes to be returned by the `find_*_servers` methods. A callback + # Builds a hash of server information hashes to be returned by the `find_*_servers` methods. A callback # block can be passed to further populate each server information hash from each tag set. # # @param servers [Array] the array of tag sets returned by Chef::MachineTagHelper#tag_search # @param block [Proc(MachineTag::Set)] a block that does further processing on each tag set; it should # return a hash that will be merged into the server information hash # + # @return [Mash] the hash with server UUIDs as keys and server information hashes as values + # def self.build_server_hash(servers, &block) server_hashes = servers.map do |tags| uuid = tags['server:uuid'].first.value From 202f1d3715580cdd5f5bf7bf2d9ee7d36b923b7e Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 7 Feb 2014 14:34:24 -0800 Subject: [PATCH 14/54] Update versions in Gemfile. --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index bc354a5..559f263 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ group :integration do gem 'machine_tag' gem 'test-kitchen', '~> 1.1.0' gem 'kitchen-vagrant' - gem 'strainer', '~> 3.3.0' - gem 'chefspec', '~> 1.3.0' + gem 'strainer', '~> 3.3' + gem 'chefspec', '~> 3.2' gem 'travis-lint' end From f303c77339c975749a7ea385703593211329a779 Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Fri, 7 Feb 2014 15:54:44 -0800 Subject: [PATCH 15/54] Added unit test for find_database_servers. --- spec/unit_test/rightscale_tag_helper_spec.rb | 200 +++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index d5d41f0..7c11dad 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -251,4 +251,204 @@ class Fake; end end end end + + describe '.find_database_servers' do + let(:database_master) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8911IT', + 'database:active=true', + 'database:master_active=1391803034', + 'database:lineage=example', + 'server:private_ip_0=10.0.0.1', + 'server:public_ip_0=157.56.165.202', + 'server:public_ip_1=157.56.165.203', + ] + end + + let(:database_slave) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8922IT', + 'database:active=true', + 'database:slave_active=1391803892', + 'database:lineage=example', + 'server:public_ip_0=157.56.166.202', + 'server:public_ip_1=157.56.166.203', + ] + end + + context 'when no database role or lineage is specified' do + let(:tags) do + [database_master, database_slave] + end + + it 'returns tags of all database servers' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:active=true', + {:required_tags => Set['server:uuid', 'database:lineage=*']} + ).and_return(tags) + response = fake.find_database_servers(node) + + response['01-83PJQDO8911IT']['tags'].should eq(database_master) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['lineage'].should eq('example') + response['01-83PJQDO8911IT']['role'].should eq('master') + response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + + response['01-83PJQDO8922IT']['tags'].should eq(database_slave) + response['01-83PJQDO8922IT']['private_ips'].should eq([]) + response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) + response['01-83PJQDO8922IT']['lineage'].should eq('example') + response['01-83PJQDO8922IT']['role'].should eq('slave') + response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + end + end + + context 'when the database lineage is given and the role is not given' do + let(:tags) do + [database_master, database_slave] + end + + it 'returns tags of all database servers' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:active=true', + {:required_tags => Set['server:uuid', 'database:lineage=*']} + ).and_return(tags) + response = fake.find_database_servers(node, 'example') + + response['01-83PJQDO8911IT']['tags'].should eq(database_master) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['lineage'].should eq('example') + response['01-83PJQDO8911IT']['role'].should eq('master') + response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + + response['01-83PJQDO8922IT']['tags'].should eq(database_slave) + response['01-83PJQDO8922IT']['private_ips'].should eq([]) + response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) + response['01-83PJQDO8922IT']['lineage'].should eq('example') + response['01-83PJQDO8922IT']['role'].should eq('slave') + response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + end + + it 'returns an empty Mash when the lineage is not available' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:active=true', + {:required_tags => Set['server:uuid', 'database:lineage=*']} + ).and_return([]) + response = fake.find_database_servers(node, 'undefined') + + response.should be_an_instance_of(Mash) + response.should be_empty + end + end + + context 'when the database role is given and the lineage is not given' do + it 'returns tags of the master database server' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:master_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([database_master]) + response = fake.find_database_servers(node, nil, 'master') + + response['01-83PJQDO8911IT']['tags'].should eq(database_master) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['lineage'].should eq('example') + response['01-83PJQDO8911IT']['role'].should eq('master') + response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + end + + it 'returns tags of the slave database server' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:slave_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([database_slave]) + response = fake.find_database_servers(node, nil, 'slave') + + response['01-83PJQDO8922IT']['tags'].should eq(database_slave) + response['01-83PJQDO8922IT']['private_ips'].should eq([]) + response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) + response['01-83PJQDO8922IT']['lineage'].should eq('example') + response['01-83PJQDO8922IT']['role'].should eq('slave') + response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + end + + it 'returns an empty Mash when the role is not available' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:undefined_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([]) + response = fake.find_database_servers(node, nil, 'undefined') + + response.should be_an_instance_of(Mash) + response.should be_empty + end + end + + context 'when the database role and lineage is given' do + it 'returns tags of the master database server matching example as lineage' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:master_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([database_master]) + response = fake.find_database_servers(node, 'example', 'master') + + response['01-83PJQDO8911IT']['tags'].should eq(database_master) + response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) + response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) + response['01-83PJQDO8911IT']['lineage'].should eq('example') + response['01-83PJQDO8911IT']['role'].should eq('master') + response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + end + + it 'returns tags of the slave database server matching example as lineage' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:slave_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([database_slave]) + response = fake.find_database_servers(node, 'example', 'slave') + + response['01-83PJQDO8922IT']['tags'].should eq(database_slave) + response['01-83PJQDO8922IT']['private_ips'].should eq([]) + response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) + response['01-83PJQDO8922IT']['lineage'].should eq('example') + response['01-83PJQDO8922IT']['role'].should eq('slave') + response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + end + + it 'returns an empty Mash when the role is not available' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:undefined_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([]) + response = fake.find_database_servers(node, 'example', 'undefined') + + response.should be_an_instance_of(Mash) + response.should be_empty + end + + it 'returns an empty Mash when the lineage is not available' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:master_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([]) + response = fake.find_database_servers(node, 'undefined', 'master') + + response.should be_an_instance_of(Mash) + response.should be_empty + end + + it 'returns an empty Mash when both role and lineage are not available' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:undefined_active=*', + {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + ).and_return([]) + response = fake.find_database_servers(node, 'undefined', 'undefined') + + response.should be_an_instance_of(Mash) + response.should be_empty + end + end + end end From 64ea26365c2b7934808ff5e7efd7a922782bf0a0 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 7 Feb 2014 16:36:57 -0800 Subject: [PATCH 16/54] Add database:bind_ip_address and database:bind_port tags. --- libraries/rightscale_tag_helper.rb | 16 +++- providers/application.rb | 16 ++-- providers/database.rb | 28 +++--- providers/load_balancer.rb | 4 +- resources/application.rb | 11 ++- resources/database.rb | 21 ++++- spec/unit_test/rightscale_tag_helper_spec.rb | 89 +++++++++++++++++--- 7 files changed, 148 insertions(+), 37 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index ce0fbc8..21e2ca3 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -219,6 +219,8 @@ def find_application_servers(node, application_name = nil, options = {}) # 'server:uuid=01-ABCDEF4567890' # ], # 'lineage' => 'example', + # 'bind_ip_address' => '10.0.0.4', + # 'bind_port' => 3306, # 'role' => 'master', # 'master_since' => Time.at(1391803034), # 'public_ips' => ['203.0.113.4'], @@ -239,6 +241,8 @@ def find_application_servers(node, application_name = nil, options = {}) # 'server:uuid=01-GHIJKL1234567' # ], # 'lineage' => 'example', + # 'bind_ip_address' => '10.0.0.5', + # 'bind_port' => 3306, # 'role' => 'slave', # 'slave_since' => Time.at(1391803892), # 'public_ips' => ['203.0.113.5'], @@ -255,7 +259,11 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) else query_tag = ::MachineTag::Tag.machine_tag('database', 'active', true) end - required_tags(options, ::MachineTag::Tag.machine_tag('database', 'lineage', '*')) + required_tags(options, + ::MachineTag::Tag.machine_tag('database', 'lineage', '*'), + ::MachineTag::Tag.machine_tag('database', 'bind_ip_address', '*'), + ::MachineTag::Tag.machine_tag('database', 'bind_port', '*') + ) servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) @@ -266,7 +274,11 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) end build_server_hash(servers) do |tags| - server_hash = {'lineage' => tags['database:lineage'].first.value} + server_hash = { + 'lineage' => tags['database:lineage'].first.value, + 'bind_ip_address' => tags['database:bind_ip_address'].first.value, + 'bind_port' => tags['database:bind_port'].first.value.to_i, + } master_active = tags['database:master_active'].first slave_active = tags['database:slave_active'].first diff --git a/providers/application.rb b/providers/application.rb index d4b42b8..bfa83de 100644 --- a/providers/application.rb +++ b/providers/application.rb @@ -20,10 +20,10 @@ # The create action that creates required tags for an application server action :create do [ - "application:active_#{new_resource.application_name}=true", - "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}", - "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}", - "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" + ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), + ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), + ::MachineTag::Tag.machine_tag('application', "bind_port_#{new_resource.application_name}", new_resource.bind_port), + ::MachineTag::Tag.machine_tag('application', "vhost_path_#{new_resource.application_name}", new_resource.vhost_path) ].each do |tag| machine_tag tag end @@ -33,10 +33,10 @@ # The delete action that removes the application specific tags from the server action :delete do [ - "application:active_#{new_resource.application_name}=true", - "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}", - "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}", - "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" + ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), + ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), + ::MachineTag::Tag.machine_tag('application', "bind_port_#{new_resource.application_name}", new_resource.bind_port), + ::MachineTag::Tag.machine_tag('application', "vhost_path_#{new_resource.application_name}", new_resource.vhost_path) ].each do |tag| machine_tag tag do action :delete diff --git a/providers/database.rb b/providers/database.rb index 10fcde8..51490a7 100644 --- a/providers/database.rb +++ b/providers/database.rb @@ -19,11 +19,15 @@ # The create action that creates required tags for a database server action :create do - [ - "database:active=true", - "database:lineage=#{new_resource.lineage}", - "database:#{new_resource.role}_active=#{new_resource.timestamp}" - ].each do |tag| + database_tags = [ + ::MachineTag::Tag.machine_tag('database', 'active', true), + ::MachineTag::Tag.machine_tag('database', 'lineage', new_resource.lineage), + ::MachineTag::Tag.machine_tag('database', 'bind_ip_address', new_resource.bind_ip_address), + ::MachineTag::Tag.machine_tag('database', 'bind_port', new_resource.bind_port), + ] + database_tags << "database:#{new_resource.role}_active=#{new_resource.timestamp}" if new_resource.role + + database_tags.each do |tag| machine_tag tag end new_resource.updated_by_last_action(true) @@ -31,11 +35,15 @@ # The delete action that removes the database specific tags from the server action :delete do - [ - "database:active=true", - "database:lineage=#{new_resource.lineage}", - "database:#{new_resource.role}_active=#{new_resource.timestamp}" - ].each do |tag| + database_tags = [ + ::MachineTag::Tag.machine_tag('database', 'active', true), + ::MachineTag::Tag.machine_tag('database', 'lineage', new_resource.lineage), + ::MachineTag::Tag.machine_tag('database', 'bind_ip_address', new_resource.bind_ip_address), + ::MachineTag::Tag.machine_tag('database', 'bind_port', new_resource.bind_port), + ] + database_tags << "database:#{new_resource.role}_active=#{new_resource.timestamp}" if new_resource.role + + database_tags.each do |tag| machine_tag tag do action :delete end diff --git a/providers/load_balancer.rb b/providers/load_balancer.rb index 3b60e1e..6df3d65 100644 --- a/providers/load_balancer.rb +++ b/providers/load_balancer.rb @@ -19,13 +19,13 @@ # The create action that creates required tags for a load balancer server action :create do - machine_tag "load_balancer:active_#{new_resource.application_name}=true" + machine_tag ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) new_resource.updated_by_last_action(true) end # The delete action that removes the load balancer specific tags from the server action :delete do - machine_tag "load_balancer:active_#{new_resource.application_name}=true" do + machine_tag ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) do action :delete end new_resource.updated_by_last_action(true) diff --git a/resources/application.rb b/resources/application.rb index 4706107..228eba6 100644 --- a/resources/application.rb +++ b/resources/application.rb @@ -21,7 +21,16 @@ attribute :application_name, :kind_of => String, :name_attribute => true # The bind IP address of the application -attribute :bind_ip_address, :kind_of => String, :required => true +attribute :bind_ip_address, :kind_of => String, :required => true, :callbacks => { + 'should be a valid IP address' => lambda do |ip_address| + require 'ipaddress' + begin + IPAddress.parse(ip_address) + rescue ArgumentError + false + end + end +} # The bind port of the application attribute :bind_port, :kind_of => Fixnum, :required => true diff --git a/resources/database.rb b/resources/database.rb index 17f5592..2bc0fda 100644 --- a/resources/database.rb +++ b/resources/database.rb @@ -17,14 +17,29 @@ # limitations under the License. # +# The lineage of the database server +attribute :lineage, :kind_of => String, :required => true + +# The bind IP address of the database +attribute :bind_ip_address, :kind_of => String, :required => true, :callbacks => { + 'should be a valid IP address' => lambda do |ip_address| + require 'ipaddress' + begin + IPAddress.parse(ip_address) + rescue ArgumentError + false + end + end +} + +# The bind port of the database +attribute :bind_port, :kind_of => Fixnum, :required => true + # The role of the database server. This attribute should only contain alphanumeric characters and underscores and # should start with a letter. # attribute :role, :kind_of => String, :regex => /^[a-z][a-z0-9_]*$/i, :name_attribute => true -# The lineage of the database server -attribute :lineage, :kind_of => String - # The timestamp used to create the _active tag. This tag represents that the server is in the specified role # since this timestamp attribute :timestamp, :kind_of => [Time, Fixnum] diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 7c11dad..f42683c 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -259,6 +259,8 @@ class Fake; end 'database:active=true', 'database:master_active=1391803034', 'database:lineage=example', + 'database:bind_ip_address=10.0.0.1', + 'database:bind_port=3306', 'server:private_ip_0=10.0.0.1', 'server:public_ip_0=157.56.165.202', 'server:public_ip_1=157.56.165.203', @@ -271,6 +273,8 @@ class Fake; end 'database:active=true', 'database:slave_active=1391803892', 'database:lineage=example', + 'database:bind_ip_address=157.56.166.202', + 'database:bind_port=3306', 'server:public_ip_0=157.56.166.202', 'server:public_ip_1=157.56.166.203', ] @@ -284,7 +288,12 @@ class Fake; end it 'returns tags of all database servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:active=true', - {:required_tags => Set['server:uuid', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return(tags) response = fake.find_database_servers(node) @@ -312,7 +321,12 @@ class Fake; end it 'returns tags of all database servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:active=true', - {:required_tags => Set['server:uuid', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return(tags) response = fake.find_database_servers(node, 'example') @@ -334,7 +348,12 @@ class Fake; end it 'returns an empty Mash when the lineage is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:active=true', - {:required_tags => Set['server:uuid', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([]) response = fake.find_database_servers(node, 'undefined') @@ -347,7 +366,13 @@ class Fake; end it 'returns tags of the master database server' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:master_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([database_master]) response = fake.find_database_servers(node, nil, 'master') @@ -362,7 +387,13 @@ class Fake; end it 'returns tags of the slave database server' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:slave_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([database_slave]) response = fake.find_database_servers(node, nil, 'slave') @@ -377,7 +408,13 @@ class Fake; end it 'returns an empty Mash when the role is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:undefined_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([]) response = fake.find_database_servers(node, nil, 'undefined') @@ -390,7 +427,13 @@ class Fake; end it 'returns tags of the master database server matching example as lineage' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:master_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([database_master]) response = fake.find_database_servers(node, 'example', 'master') @@ -405,7 +448,13 @@ class Fake; end it 'returns tags of the slave database server matching example as lineage' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:slave_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([database_slave]) response = fake.find_database_servers(node, 'example', 'slave') @@ -420,7 +469,13 @@ class Fake; end it 'returns an empty Mash when the role is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:undefined_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([]) response = fake.find_database_servers(node, 'example', 'undefined') @@ -431,7 +486,13 @@ class Fake; end it 'returns an empty Mash when the lineage is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:master_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([]) response = fake.find_database_servers(node, 'undefined', 'master') @@ -442,7 +503,13 @@ class Fake; end it 'returns an empty Mash when both role and lineage are not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( node, 'database:undefined_active=*', - {:required_tags => Set['server:uuid', 'database:active=true', 'database:lineage=*']} + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} ).and_return([]) response = fake.find_database_servers(node, 'undefined', 'undefined') From c1c0586eda6e1c5bd610af4eb60eabe07760fb2f Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Fri, 7 Feb 2014 16:43:40 -0800 Subject: [PATCH 17/54] Test database:bind_ip_address and database:bind_port tags in unit tests. --- spec/unit_test/rightscale_tag_helper_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index f42683c..3a993ad 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -303,6 +303,8 @@ class Fake; end response['01-83PJQDO8911IT']['lineage'].should eq('example') response['01-83PJQDO8911IT']['role'].should eq('master') response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + response['01-83PJQDO8911IT']['bind_ip_address'].should eq('10.0.0.1') + response['01-83PJQDO8911IT']['bind_port'].should eq(3306) response['01-83PJQDO8922IT']['tags'].should eq(database_slave) response['01-83PJQDO8922IT']['private_ips'].should eq([]) @@ -310,6 +312,8 @@ class Fake; end response['01-83PJQDO8922IT']['lineage'].should eq('example') response['01-83PJQDO8922IT']['role'].should eq('slave') response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + response['01-83PJQDO8922IT']['bind_ip_address'].should eq('157.56.166.202') + response['01-83PJQDO8922IT']['bind_port'].should eq(3306) end end @@ -336,6 +340,8 @@ class Fake; end response['01-83PJQDO8911IT']['lineage'].should eq('example') response['01-83PJQDO8911IT']['role'].should eq('master') response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + response['01-83PJQDO8911IT']['bind_ip_address'].should eq('10.0.0.1') + response['01-83PJQDO8911IT']['bind_port'].should eq(3306) response['01-83PJQDO8922IT']['tags'].should eq(database_slave) response['01-83PJQDO8922IT']['private_ips'].should eq([]) @@ -343,6 +349,8 @@ class Fake; end response['01-83PJQDO8922IT']['lineage'].should eq('example') response['01-83PJQDO8922IT']['role'].should eq('slave') response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + response['01-83PJQDO8922IT']['bind_ip_address'].should eq('157.56.166.202') + response['01-83PJQDO8922IT']['bind_port'].should eq(3306) end it 'returns an empty Mash when the lineage is not available' do @@ -382,6 +390,8 @@ class Fake; end response['01-83PJQDO8911IT']['lineage'].should eq('example') response['01-83PJQDO8911IT']['role'].should eq('master') response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + response['01-83PJQDO8911IT']['bind_ip_address'].should eq('10.0.0.1') + response['01-83PJQDO8911IT']['bind_port'].should eq(3306) end it 'returns tags of the slave database server' do @@ -403,6 +413,8 @@ class Fake; end response['01-83PJQDO8922IT']['lineage'].should eq('example') response['01-83PJQDO8922IT']['role'].should eq('slave') response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + response['01-83PJQDO8922IT']['bind_ip_address'].should eq('157.56.166.202') + response['01-83PJQDO8922IT']['bind_port'].should eq(3306) end it 'returns an empty Mash when the role is not available' do @@ -443,6 +455,8 @@ class Fake; end response['01-83PJQDO8911IT']['lineage'].should eq('example') response['01-83PJQDO8911IT']['role'].should eq('master') response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + response['01-83PJQDO8911IT']['bind_ip_address'].should eq('10.0.0.1') + response['01-83PJQDO8911IT']['bind_port'].should eq(3306) end it 'returns tags of the slave database server matching example as lineage' do @@ -464,6 +478,8 @@ class Fake; end response['01-83PJQDO8922IT']['lineage'].should eq('example') response['01-83PJQDO8922IT']['role'].should eq('slave') response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + response['01-83PJQDO8922IT']['bind_ip_address'].should eq('157.56.166.202') + response['01-83PJQDO8922IT']['bind_port'].should eq(3306) end it 'returns an empty Mash when the role is not available' do From e1aeddfe12b04938adab9a4f94f1fb74f8dbf53f Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 7 Feb 2014 16:55:15 -0800 Subject: [PATCH 18/54] Actually return true from IP address callbacks. --- resources/application.rb | 1 + resources/database.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/resources/application.rb b/resources/application.rb index 228eba6..e25cfc8 100644 --- a/resources/application.rb +++ b/resources/application.rb @@ -26,6 +26,7 @@ require 'ipaddress' begin IPAddress.parse(ip_address) + true rescue ArgumentError false end diff --git a/resources/database.rb b/resources/database.rb index 2bc0fda..0872641 100644 --- a/resources/database.rb +++ b/resources/database.rb @@ -26,6 +26,7 @@ require 'ipaddress' begin IPAddress.parse(ip_address) + true rescue ArgumentError false end From eabd07ed27e97dd533392d61065b2a54cd5ad516 Mon Sep 17 00:00:00 2001 From: david-vo Date: Fri, 7 Feb 2014 16:43:26 -0800 Subject: [PATCH 19/54] Create kitchen tests for three tier server setup --- .kitchen.yml | 51 ++++++++++++++-- Berksfile | 4 ++ Gemfile | 1 + Vagrantfile | 4 +- metadata.rb | 2 +- test/cookbooks/fake/metadata.rb | 12 ++++ test/cookbooks/fake/recipes/app_server.rb | 42 +++++++++++++ test/cookbooks/fake/recipes/db_server.rb | 41 +++++++++++++ test/cookbooks/fake/recipes/default.rb | 42 +++++++++++++ test/cookbooks/fake/recipes/lb_server.rb | 40 +++++++++++++ .../application/serverspec/server_spec.rb | 60 +++++++++++++++++++ .../application/serverspec/spec_helper.rb | 13 ++++ .../database/serverspec/server_spec.rb | 56 +++++++++++++++++ .../database/serverspec/spec_helper.rb | 13 ++++ .../default/serverspec/server_spec.rb | 31 ++++++++++ .../default/serverspec/spec_helper.rb | 13 ++++ .../load_balancer/serverspec/server_spec.rb | 44 ++++++++++++++ .../load_balancer/serverspec/spec_helper.rb | 13 ++++ 18 files changed, 475 insertions(+), 7 deletions(-) create mode 100644 test/cookbooks/fake/metadata.rb create mode 100644 test/cookbooks/fake/recipes/app_server.rb create mode 100644 test/cookbooks/fake/recipes/db_server.rb create mode 100644 test/cookbooks/fake/recipes/default.rb create mode 100644 test/cookbooks/fake/recipes/lb_server.rb create mode 100644 test/integration/application/serverspec/server_spec.rb create mode 100644 test/integration/application/serverspec/spec_helper.rb create mode 100644 test/integration/database/serverspec/server_spec.rb create mode 100644 test/integration/database/serverspec/spec_helper.rb create mode 100644 test/integration/default/serverspec/server_spec.rb create mode 100644 test/integration/default/serverspec/spec_helper.rb create mode 100644 test/integration/load_balancer/serverspec/server_spec.rb create mode 100644 test/integration/load_balancer/serverspec/spec_helper.rb diff --git a/.kitchen.yml b/.kitchen.yml index fa50527..4940637 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -32,15 +32,16 @@ suites: - null - "" - 10.0.2.15 -# TODO: This suite should be refactored to load_balancer, application, and database as well as the rightscale_tag::test -# recipe should be moved to a fake cookbook as separate recipes. -- name: test + +# Application server tests +- name: application run_list: - recipe[rightscale_tag] - - recipe[rightscale_tag::test] + - recipe[rightscale_tag::monitoring] + - recipe[fake::app_server] attributes: rightscale: - instance_uuid: 01-ABCDEFG123456 + instance_uuid: 02-BBCDEFG123457 cloud: provider: vagrant public_ips: @@ -51,3 +52,43 @@ suites: - null - "" - 10.0.2.15 + +# Database server tests +- name: database + run_list: + - recipe[rightscale_tag] + - recipe[rightscale_tag::monitoring] + - recipe[fake::db_server] + attributes: + rightscale: + instance_uuid: 03-CBCDEFG123458 + cloud: + provider: vagrant + public_ips: + - null + - "" + - 33.33.33.12 + private_ips: + - null + - "" + - 10.0.2.17 + +# Load Balancer server tests +- name: load_balancer + run_list: + - recipe[rightscale_tag] + - recipe[rightscale_tag::monitoring] + - recipe[fake::lb_server] + attributes: + rightscale: + instance_uuid: 04-DBCDEFG123459 + cloud: + provider: vagrant + public_ips: + - null + - "" + - 33.33.33.11 + private_ips: + - null + - "" + - 10.0.2.16 diff --git a/Berksfile b/Berksfile index c4bb297..eebbad1 100644 --- a/Berksfile +++ b/Berksfile @@ -1,3 +1,7 @@ site :opscode metadata + +group :integration do + cookbook 'fake', path: './test/cookbooks/fake' +end diff --git a/Gemfile b/Gemfile index 559f263..137b8e0 100644 --- a/Gemfile +++ b/Gemfile @@ -10,4 +10,5 @@ group :integration do gem 'strainer', '~> 3.3' gem 'chefspec', '~> 3.2' gem 'travis-lint' + gem 'machine_tag' end diff --git a/Vagrantfile b/Vagrantfile index d58706a..1930fa7 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -80,6 +80,7 @@ Vagrant.configure("2") do |config| :instance_uuid => '01-ABCDEFG123456' }, :cloud => { + :provider => 'vagrant', :public_ips => [ nil, '', @@ -94,7 +95,8 @@ Vagrant.configure("2") do |config| } chef.run_list = [ - "recipe[rightscale_tag::default]" + "recipe[rightscale_tag::default]", + "recipe[rightscale_tag::test]" ] end end diff --git a/metadata.rb b/metadata.rb index f8c854b..d3305e4 100644 --- a/metadata.rb +++ b/metadata.rb @@ -6,7 +6,7 @@ long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '1.0.0' -depends 'machine_tag', '~> 1.0.1' +depends 'machine_tag', '~> 1.0.3' depends 'marker', '~> 1.0.0' recipe 'rightscale_tag::default', 'Tags a server with the standard RightScale server tags' diff --git a/test/cookbooks/fake/metadata.rb b/test/cookbooks/fake/metadata.rb new file mode 100644 index 0000000..ee32724 --- /dev/null +++ b/test/cookbooks/fake/metadata.rb @@ -0,0 +1,12 @@ +name 'fake' +maintainer 'RightScale, Inc.' +maintainer_email 'cookbooks@rightscale.com' +license 'Apache 2.0' +description 'Installs and tags fake servers for testing purposes' +version '0.1.0' + +depends 'rightscale_tag' + +recipe 'fake::app_server', 'Prepares the test application server database' +recipe 'fake::db_server', 'Prepares the test database server database' +recipe 'fake::lb_server', 'Prepares the test load balancer server database' diff --git a/test/cookbooks/fake/recipes/app_server.rb b/test/cookbooks/fake/recipes/app_server.rb new file mode 100644 index 0000000..6cdfae3 --- /dev/null +++ b/test/cookbooks/fake/recipes/app_server.rb @@ -0,0 +1,42 @@ +# +# Cookbook Name:: fake +# Recipe:: app_server +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +delete = false + +# Application test setup. We are only using www and not both www and api so the latter doesn't pollute the tag data +rightscale_tag_application 'www' do + bind_ip_address '10.0.0.1' + bind_port 8080 + vhost_path 'www.example.com' + action delete == true ? :delete : :create +end + +# Use find_application_servers helper method and write it to a JSON file so the kitchen test can access it + +class Chef::Resource::RubyBlock + include Rightscale::RightscaleTag +end + +ruby_block "Find application servers" do + block do + File.open("/tmp/found_app_servers.json", "w") do |file| + file.write find_application_servers(node, "www").to_json + end + end +end diff --git a/test/cookbooks/fake/recipes/db_server.rb b/test/cookbooks/fake/recipes/db_server.rb new file mode 100644 index 0000000..0d14361 --- /dev/null +++ b/test/cookbooks/fake/recipes/db_server.rb @@ -0,0 +1,41 @@ +# +# Cookbook Name:: fake +# Recipe:: db_server +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +delete = false + +# Database setup +rightscale_tag_database 'master' do + lineage 'production' + timestamp 1391473172 + action delete == true ? :delete : :create +end + +# Use the find_database_server helper method and write it to a JSON file so the kitchen tests can access it + +class Chef::Resource::RubyBlock + include Rightscale::RightscaleTag +end + +ruby_block "Find database servers" do + block do + File.open("/tmp/found_db_servers.json", "w") do |file| + file.write find_database_servers(node, "production").to_json + end + end +end diff --git a/test/cookbooks/fake/recipes/default.rb b/test/cookbooks/fake/recipes/default.rb new file mode 100644 index 0000000..907a56d --- /dev/null +++ b/test/cookbooks/fake/recipes/default.rb @@ -0,0 +1,42 @@ +# +# Cookbook Name:: fake +# Recipe:: default +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +delete = false + +marker "recipe_start_rightscale" do + template "rightscale_audit_entry.erb" +end + +if node['rightscale'] && node['rightscale']['instance_uuid'] + machine_tag "server:uuid=#{node['rightscale']['instance_uuid']}" +end + +if node['cloud'] + if node['cloud']['public_ips'] + node['cloud']['public_ips'].reject { |ip| ip.nil? || ip.empty? }.each_with_index do |public_ip, index| + machine_tag "server:public_ip_#{index}=#{public_ip}" + end + end + + if node['cloud']['private_ips'] + node['cloud']['private_ips'].reject { |ip| ip.nil? || ip.empty? }.each_with_index do |private_ip, index| + machine_tag "server:private_ip_#{index}=#{private_ip}" + end + end +end diff --git a/test/cookbooks/fake/recipes/lb_server.rb b/test/cookbooks/fake/recipes/lb_server.rb new file mode 100644 index 0000000..3c5e2e8 --- /dev/null +++ b/test/cookbooks/fake/recipes/lb_server.rb @@ -0,0 +1,40 @@ +# +# Cookbook Name:: fake +# Recipe:: lb_server +# +# Copyright (C) 2013 RightScale, Inc. +# +# 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. +# + +delete = false + +# Load balancer setup. We are only using api and not both api and www so the latter doesn't pollute the tag data +rightscale_tag_load_balancer 'api server' do + application_name 'api' + action delete == true ? :delete : :create +end + +# Use find_load_balancer_servers helper method and write it to a JSON file so the kitchen tests can access it + +class Chef::Resource::RubyBlock + include Rightscale::RightscaleTag +end + +ruby_block "Find load balancer servers" do + block do + File.open("/tmp/found_lb_servers.json", "w") do |file| + file.write find_load_balancer_servers(node, "api").to_json + end + end +end diff --git a/test/integration/application/serverspec/server_spec.rb b/test/integration/application/serverspec/server_spec.rb new file mode 100644 index 0000000..d7b68de --- /dev/null +++ b/test/integration/application/serverspec/server_spec.rb @@ -0,0 +1,60 @@ +# Test:: application server +require 'spec_helper' + +#Get the hostname +host_name = `hostname -s`.chomp + +app_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) + +describe "Application (www) server tags" do + it "should have a UUID of 02-BBCDEFG123457" do + app_tags['server:uuid'].first.value.should match ('02-BBCDEFG123457') + end + it "should have a public IP of" do + app_tags['server:public_ip_0'].first.value.should match ('33.33.33.10') + end + it "should have a private IP of" do + app_tags['server:private_ip_0'].first.value.should match ('10.0.2.15') + end + it "should have 4 application specific entries" do + app_tags['application'].length.should == 4 + end + it "should be active" do + app_tags['application:active_www'].first.value.should be_true + end + it "should have an IP of 10.0.0.1" do + app_tags['application:bind_ip_address_www'].first.value.should match ('10.0.0.1') + end + it "should have an port of 8080" do + app_tags['application:bind_port_www'].first.value.should match ('8080') + end + it "should have vhost path of www.example.com" do + app_tags['application:vhost_path_www'].first.value.should match ('www.example.com') + end +end + + +# We use find_application_servers helper to find all the application servers with name www, and we write results to +# file. Here we are loading the file so it can be parsed +app_server_tags = JSON.parse(IO.read("/tmp/found_app_servers.json")) + +describe "Found www application servers" do + it "should have a UUID of 02-BBCDEFG123457" do + app_server_tags.has_key?('02-BBCDEFG123457').should be_true + end + it "should include a www server" do + app_server_tags['02-BBCDEFG123457']['applications'].has_key?('www').should be_true + end + it "should include a bind IP address of 10.0.0.1" do + app_server_tags['02-BBCDEFG123457']['applications']['www']['bind_ip_address'].should match ('10.0.0.1') + end + it "should include a bind port of 8080" do + app_server_tags['02-BBCDEFG123457']['applications']['www']['bind_port'].should == 8080 + end + it "should NOT include an API server" do + app_server_tags['02-BBCDEFG123457']['applications'].has_key?('api').should be_false + end + it "should NOT include database server" do + app_server_tags['02-BBCDEFG123457']['applications'].has_key?('master').should be_false + end +end diff --git a/test/integration/application/serverspec/spec_helper.rb b/test/integration/application/serverspec/spec_helper.rb new file mode 100644 index 0000000..d89b194 --- /dev/null +++ b/test/integration/application/serverspec/spec_helper.rb @@ -0,0 +1,13 @@ +require 'serverspec' +require 'pathname' +require 'json' +require 'rubygems/dependency_installer' + +include Serverspec::Helper::Exec +include Serverspec::Helper::DetectOS + +installer = Gem::DependencyInstaller.new +installer.install('machine_tag') +Gem.clear_paths + +require 'machine_tag' diff --git a/test/integration/database/serverspec/server_spec.rb b/test/integration/database/serverspec/server_spec.rb new file mode 100644 index 0000000..99a0f92 --- /dev/null +++ b/test/integration/database/serverspec/server_spec.rb @@ -0,0 +1,56 @@ +# Test:: database server +require 'spec_helper' + +# Get the hostname +host_name = `hostname -s`.chomp + +db_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) + +describe "Database server tags" do + it "should have a UUID of 03-CBCDEFG123458" do + db_tags['server:uuid'].first.value.should match ('03-CBCDEFG123458') + end + it "should have a public of 33.33.33.12" do + db_tags['server:public_ip_0'].first.value.should match ('33.33.33.12') + end + it "should have a private IP of 10.0.2.17" do + db_tags['server:private_ip_0'].first.value.should match ('10.0.2.17') + end + it "should have 3 application specific entries" do + db_tags['database'].length.should == 3 + end + it "should be active" do + db_tags['database:active'].first.value.should be_true + end + it "should have a lineage of production" do + db_tags['database:lineage'].first.value.should match ('production') + end + it "should have a master_active value of 1391473172" do + db_tags['database:master_active'].first.value.should match ('1391473172') + end +end + +# We use find_database_servers helper to find all the database severs, and we write results to a file. +# Here we are loading the file so it can be parsed +db_server_tags = JSON.parse(IO.read("/tmp/found_db_servers.json")) + +describe "Found database application servers" do + it "should have a UUID of 03-CBCDEFG123458" do + db_server_tags.has_key?('03-CBCDEFG123458').should be_true + end + it "should include a public IP address of 33.33.33.12" do + db_server_tags['03-CBCDEFG123458']['public_ips'].first.should match ('33.33.33.12') + end + it "should include a private IP address of 10.0.2.17" do + db_server_tags['03-CBCDEFG123458']['private_ips'].first.should match ('10.0.2.17') + end + it "should include a lineage of production" do + db_server_tags['03-CBCDEFG123458']['lineage'].should match ('production') + end + it "should have a role of master" do + db_server_tags['03-CBCDEFG123458']['role'].should match ('master') + end + it "should have been a master since 2014-02-04 00:19:32 +0000" do + db_server_tags['03-CBCDEFG123458']['master_since'].should == '2014-02-04 00:19:32 +0000' + end +end diff --git a/test/integration/database/serverspec/spec_helper.rb b/test/integration/database/serverspec/spec_helper.rb new file mode 100644 index 0000000..d89b194 --- /dev/null +++ b/test/integration/database/serverspec/spec_helper.rb @@ -0,0 +1,13 @@ +require 'serverspec' +require 'pathname' +require 'json' +require 'rubygems/dependency_installer' + +include Serverspec::Helper::Exec +include Serverspec::Helper::DetectOS + +installer = Gem::DependencyInstaller.new +installer.install('machine_tag') +Gem.clear_paths + +require 'machine_tag' diff --git a/test/integration/default/serverspec/server_spec.rb b/test/integration/default/serverspec/server_spec.rb new file mode 100644 index 0000000..557817b --- /dev/null +++ b/test/integration/default/serverspec/server_spec.rb @@ -0,0 +1,31 @@ +# Test:: default server +require 'spec_helper' + +#Get the hostname +host_name = `hostname -s`.chomp + +default_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) + +describe "Default server tags" do + it "should have a UUID of 01-ABCDEFG123456" do + default_tags['server:uuid'].first.value.should match ('01-ABCDEFG123456') + end + it "should have a public IP of" do + default_tags['server:public_ip_0'].first.value.should match ('33.33.33.10') + end + it "should have a private IP of" do + default_tags['server:private_ip_0'].first.value.should match ('10.0.2.15') + end + it "should have an Active monitoring state" do + default_tags['rs_monitoring:state'].first.value.should match ('active') + end + it "should have NOT have any Application tags" do + default_tags['application'].should be_empty + end + it "should have NOT have any Database tags" do + default_tags['database'].should be_empty + end + it "should have NOT have any Load Balancer tags" do + default_tags['load_balancer'].should be_empty + end +end diff --git a/test/integration/default/serverspec/spec_helper.rb b/test/integration/default/serverspec/spec_helper.rb new file mode 100644 index 0000000..d89b194 --- /dev/null +++ b/test/integration/default/serverspec/spec_helper.rb @@ -0,0 +1,13 @@ +require 'serverspec' +require 'pathname' +require 'json' +require 'rubygems/dependency_installer' + +include Serverspec::Helper::Exec +include Serverspec::Helper::DetectOS + +installer = Gem::DependencyInstaller.new +installer.install('machine_tag') +Gem.clear_paths + +require 'machine_tag' diff --git a/test/integration/load_balancer/serverspec/server_spec.rb b/test/integration/load_balancer/serverspec/server_spec.rb new file mode 100644 index 0000000..aecdb7d --- /dev/null +++ b/test/integration/load_balancer/serverspec/server_spec.rb @@ -0,0 +1,44 @@ +# Test:: load_balancer server +require 'spec_helper' + +# Get the hostname +host_name = `hostname -s`.chomp + +lb_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) + +describe "Load balancer server tags" do + it "should have a UUID of 04-DBCDEFG123459" do + lb_tags['server:uuid'].first.value.should match ('04-DBCDEFG123459') + end + it "should have a public IP of 33.33.33.11" do + lb_tags['server:public_ip_0'].first.value.should match ('33.33.33.11') + end + it "should have a private IP of 10.0.2.16" do + lb_tags['server:private_ip_0'].first.value.should match ('10.0.2.16') + end + it "should have 1 application specific entry" do + lb_tags['load_balancer'].length.should == 1 + end + it "should have an active API" do + lb_tags['load_balancer:active_api'].should be_true + end +end + +# We use find_load_balancer_servers helper to find all the load balancers with name api, and we write results to a file. +# Here we are loading the file so it can be parsed +lb_server_tags = JSON.parse(IO.read("/tmp/found_lb_servers.json")) + +describe "Found load balancer server" do + it "should have a UUID of 04-DBCDEFG123459" do + lb_server_tags.has_key?('04-DBCDEFG123459').should be_true + end + it "should have a public IP address of 33.33.33.11" do + lb_server_tags['04-DBCDEFG123459']['public_ips'].first.should match ('33.33.33.11') + end + it "should have a private IP address of 10.0.2.16" do + lb_server_tags['04-DBCDEFG123459']['private_ips'].first.should match ('10.0.2.16') + end + it "should have an application name of api" do + lb_server_tags['04-DBCDEFG123459']['application_names'].first.should match ('api') + end +end diff --git a/test/integration/load_balancer/serverspec/spec_helper.rb b/test/integration/load_balancer/serverspec/spec_helper.rb new file mode 100644 index 0000000..d89b194 --- /dev/null +++ b/test/integration/load_balancer/serverspec/spec_helper.rb @@ -0,0 +1,13 @@ +require 'serverspec' +require 'pathname' +require 'json' +require 'rubygems/dependency_installer' + +include Serverspec::Helper::Exec +include Serverspec::Helper::DetectOS + +installer = Gem::DependencyInstaller.new +installer.install('machine_tag') +Gem.clear_paths + +require 'machine_tag' From a16b3aff674ce04f5fe416eb1fafb4c0a1ff7fd8 Mon Sep 17 00:00:00 2001 From: david-vo Date: Fri, 7 Feb 2014 17:45:19 -0800 Subject: [PATCH 20/54] Update tests --- test/cookbooks/fake/recipes/db_server.rb | 2 ++ test/integration/database/serverspec/server_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/cookbooks/fake/recipes/db_server.rb b/test/cookbooks/fake/recipes/db_server.rb index 0d14361..a3dc9d6 100644 --- a/test/cookbooks/fake/recipes/db_server.rb +++ b/test/cookbooks/fake/recipes/db_server.rb @@ -21,6 +21,8 @@ # Database setup rightscale_tag_database 'master' do + bind_ip_address '10.0.0.2' + bind_port 3306 lineage 'production' timestamp 1391473172 action delete == true ? :delete : :create diff --git a/test/integration/database/serverspec/server_spec.rb b/test/integration/database/serverspec/server_spec.rb index 99a0f92..07a87d4 100644 --- a/test/integration/database/serverspec/server_spec.rb +++ b/test/integration/database/serverspec/server_spec.rb @@ -16,8 +16,8 @@ it "should have a private IP of 10.0.2.17" do db_tags['server:private_ip_0'].first.value.should match ('10.0.2.17') end - it "should have 3 application specific entries" do - db_tags['database'].length.should == 3 + it "should have 5 application specific entries" do + db_tags['database'].length.should == 5 end it "should be active" do db_tags['database:active'].first.value.should be_true From 3fbc2695a39b328f5e4815d67e16a6dd2dc782a8 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Mon, 10 Feb 2014 10:06:47 -0800 Subject: [PATCH 21/54] Remove duplicate machine_tag dependency from Gemfile. --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index 137b8e0..559f263 100644 --- a/Gemfile +++ b/Gemfile @@ -10,5 +10,4 @@ group :integration do gem 'strainer', '~> 3.3' gem 'chefspec', '~> 3.2' gem 'travis-lint' - gem 'machine_tag' end From 9a60aea337ff54498f73de51f9df23a757c01610 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Mon, 10 Feb 2014 11:06:00 -0800 Subject: [PATCH 22/54] Remove test recipe. --- Vagrantfile | 1 - recipes/test.rb | 58 ------------------------------------------------- 2 files changed, 59 deletions(-) delete mode 100644 recipes/test.rb diff --git a/Vagrantfile b/Vagrantfile index 1930fa7..88d2016 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -96,7 +96,6 @@ Vagrant.configure("2") do |config| chef.run_list = [ "recipe[rightscale_tag::default]", - "recipe[rightscale_tag::test]" ] end end diff --git a/recipes/test.rb b/recipes/test.rb deleted file mode 100644 index 88271e7..0000000 --- a/recipes/test.rb +++ /dev/null @@ -1,58 +0,0 @@ -# -# Cookbook Name:: rightscale_tag -# Recipe:: test -# -# Copyright (C) 2013 RightScale, Inc. -# -# 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. -# - -delete = false - -marker "recipe_start_rightscale" do - template "rightscale_audit_entry.erb" -end - -## Database -rightscale_tag_database 'master' do - lineage 'production' - timestamp 1391473172 - action delete == true ? :delete : :create -end - -## Application - -rightscale_tag_application 'www' do - bind_ip_address '10.0.0.1' - bind_port 8080 - vhost_path 'www.example.com' - action delete == true ? :delete : :create -end - -rightscale_tag_application 'api server' do - application_name 'api' - bind_ip_address '10.0.0.2' - bind_port 80 - vhost_path '/api' - action delete == true ? :delete : :create -end - -## Load Balancer -rightscale_tag_load_balancer 'www' do - action delete == true ? :delete : :create -end - -rightscale_tag_load_balancer 'api server' do - application_name 'api' - action delete == true ? :delete : :create -end From 4234a717e78f52271cfc43c0c319709a9404673d Mon Sep 17 00:00:00 2001 From: Nitin Mohan Date: Mon, 10 Feb 2014 12:32:08 -0800 Subject: [PATCH 23/54] Make lineage as the name attribute --- resources/database.rb | 4 ++-- test/cookbooks/fake/recipes/db_server.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/database.rb b/resources/database.rb index 0872641..6605fd3 100644 --- a/resources/database.rb +++ b/resources/database.rb @@ -18,7 +18,7 @@ # # The lineage of the database server -attribute :lineage, :kind_of => String, :required => true +attribute :lineage, :kind_of => String, :name_attribute => true # The bind IP address of the database attribute :bind_ip_address, :kind_of => String, :required => true, :callbacks => { @@ -39,7 +39,7 @@ # The role of the database server. This attribute should only contain alphanumeric characters and underscores and # should start with a letter. # -attribute :role, :kind_of => String, :regex => /^[a-z][a-z0-9_]*$/i, :name_attribute => true +attribute :role, :kind_of => String, :regex => /^[a-z][a-z0-9_]*$/i # The timestamp used to create the _active tag. This tag represents that the server is in the specified role # since this timestamp diff --git a/test/cookbooks/fake/recipes/db_server.rb b/test/cookbooks/fake/recipes/db_server.rb index a3dc9d6..2cabf88 100644 --- a/test/cookbooks/fake/recipes/db_server.rb +++ b/test/cookbooks/fake/recipes/db_server.rb @@ -20,10 +20,10 @@ delete = false # Database setup -rightscale_tag_database 'master' do +rightscale_tag_database 'production' do bind_ip_address '10.0.0.2' bind_port 3306 - lineage 'production' + role 'master' timestamp 1391473172 action delete == true ? :delete : :create end From b4e9e7e5a0ae51abf5a86523cebac6f5337c41db Mon Sep 17 00:00:00 2001 From: Nitin Mohan Date: Tue, 11 Feb 2014 13:32:34 -0800 Subject: [PATCH 24/54] Require machine_tag gem for helper methods --- libraries/rightscale_tag_helper.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 21e2ca3..bfa9bf6 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -49,6 +49,8 @@ module RightscaleTag # } # def self.find_load_balancer_servers(node, application_name = nil, options = {}) + require 'machine_tag' + required_tags(options) if application_name @@ -132,6 +134,8 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) # # def self.find_application_servers(node, application_name = nil, options = {}) + require 'machine_tag' + required_tags(options) if application_name @@ -251,6 +255,8 @@ def find_application_servers(node, application_name = nil, options = {}) # } # def self.find_database_servers(node, lineage = nil, role = nil, options = {}) + require 'machine_tag' + required_tags(options) if role From 014a70de7b42394bd66cfac0448d80438de4b56c Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 11 Feb 2014 14:05:25 -0800 Subject: [PATCH 25/54] Manage timestamps for database tagging internally. --- providers/database.rb | 35 +++++++++++++++++-- resources/database.rb | 4 --- test/cookbooks/fake/recipes/db_server.rb | 1 - .../database/serverspec/server_spec.rb | 12 +++---- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/providers/database.rb b/providers/database.rb index 51490a7..a4c4850 100644 --- a/providers/database.rb +++ b/providers/database.rb @@ -25,7 +25,25 @@ ::MachineTag::Tag.machine_tag('database', 'bind_ip_address', new_resource.bind_ip_address), ::MachineTag::Tag.machine_tag('database', 'bind_port', new_resource.bind_port), ] - database_tags << "database:#{new_resource.role}_active=#{new_resource.timestamp}" if new_resource.role + if new_resource.role + timestamp_file = "/var/lib/rightscale/rightscale_tag_database_#{new_resource.role}_active.timestamp" + if ::File.exists?(timestamp_file) + timestamp = ::Time.at(::File.read(timestamp_file).to_i) + else + timestamp = ::Time.now + end + + directory '/var/lib/rightscale' do + mode 0755 + end + + file timestamp_file do + action :create_if_missing + content "#{timestamp.to_i}" + end + + database_tags << "database:#{new_resource.role}_active=#{timestamp.to_i}" + end database_tags.each do |tag| machine_tag tag @@ -41,7 +59,20 @@ ::MachineTag::Tag.machine_tag('database', 'bind_ip_address', new_resource.bind_ip_address), ::MachineTag::Tag.machine_tag('database', 'bind_port', new_resource.bind_port), ] - database_tags << "database:#{new_resource.role}_active=#{new_resource.timestamp}" if new_resource.role + if new_resource.role + timestamp_file = "/var/lib/rightscale/rightscale_tag_database_#{new_resource.role}_active.timestamp" + if ::File.exists?(timestamp_file) + timestamp = ::Time.at(::File.read(timestamp_file).to_i) + else + timestamp = 0 + end + + file timestamp_file do + action :delete + end + + database_tags << "database:#{new_resource.role}_active=#{timestamp.to_i}" + end database_tags.each do |tag| machine_tag tag do diff --git a/resources/database.rb b/resources/database.rb index 6605fd3..352585a 100644 --- a/resources/database.rb +++ b/resources/database.rb @@ -41,10 +41,6 @@ # attribute :role, :kind_of => String, :regex => /^[a-z][a-z0-9_]*$/i -# The timestamp used to create the _active tag. This tag represents that the server is in the specified role -# since this timestamp -attribute :timestamp, :kind_of => [Time, Fixnum] - # Creates the required tags for the database server actions :create diff --git a/test/cookbooks/fake/recipes/db_server.rb b/test/cookbooks/fake/recipes/db_server.rb index 2cabf88..496781f 100644 --- a/test/cookbooks/fake/recipes/db_server.rb +++ b/test/cookbooks/fake/recipes/db_server.rb @@ -24,7 +24,6 @@ bind_ip_address '10.0.0.2' bind_port 3306 role 'master' - timestamp 1391473172 action delete == true ? :delete : :create end diff --git a/test/integration/database/serverspec/server_spec.rb b/test/integration/database/serverspec/server_spec.rb index 07a87d4..8589a86 100644 --- a/test/integration/database/serverspec/server_spec.rb +++ b/test/integration/database/serverspec/server_spec.rb @@ -25,9 +25,9 @@ it "should have a lineage of production" do db_tags['database:lineage'].first.value.should match ('production') end - it "should have a master_active value of 1391473172" do - db_tags['database:master_active'].first.value.should match ('1391473172') - end + #it "should have a master_active value of 1391473172" do + # db_tags['database:master_active'].first.value.should match ('1391473172') + #end end # We use find_database_servers helper to find all the database severs, and we write results to a file. @@ -50,7 +50,7 @@ it "should have a role of master" do db_server_tags['03-CBCDEFG123458']['role'].should match ('master') end - it "should have been a master since 2014-02-04 00:19:32 +0000" do - db_server_tags['03-CBCDEFG123458']['master_since'].should == '2014-02-04 00:19:32 +0000' - end + #it "should have been a master since 2014-02-04 00:19:32 +0000" do + # db_server_tags['03-CBCDEFG123458']['master_since'].should == '2014-02-04 00:19:32 +0000' + #end end From 5d672efd8b39c5852e993b52b0204b90fc8f9474 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 11 Feb 2014 15:13:01 -0800 Subject: [PATCH 26/54] Appease the foodcritic. --- providers/database.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/database.rb b/providers/database.rb index a4c4850..32a5ce3 100644 --- a/providers/database.rb +++ b/providers/database.rb @@ -39,7 +39,7 @@ file timestamp_file do action :create_if_missing - content "#{timestamp.to_i}" + content timestamp.to_i.to_s end database_tags << "database:#{new_resource.role}_active=#{timestamp.to_i}" From bf4403ca71f327a4c784cb3ed6cab8d03f2a1152 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 11 Feb 2014 15:13:37 -0800 Subject: [PATCH 27/54] Require machine_tag in the providers. --- providers/application.rb | 4 ++++ providers/database.rb | 4 ++++ providers/load_balancer.rb | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/providers/application.rb b/providers/application.rb index bfa83de..ec3813e 100644 --- a/providers/application.rb +++ b/providers/application.rb @@ -19,6 +19,8 @@ # The create action that creates required tags for an application server action :create do + require 'machine_tag' + [ ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), @@ -32,6 +34,8 @@ # The delete action that removes the application specific tags from the server action :delete do + require 'machine_tag' + [ ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), diff --git a/providers/database.rb b/providers/database.rb index 32a5ce3..9b206cb 100644 --- a/providers/database.rb +++ b/providers/database.rb @@ -19,6 +19,8 @@ # The create action that creates required tags for a database server action :create do + require 'machine_tag' + database_tags = [ ::MachineTag::Tag.machine_tag('database', 'active', true), ::MachineTag::Tag.machine_tag('database', 'lineage', new_resource.lineage), @@ -53,6 +55,8 @@ # The delete action that removes the database specific tags from the server action :delete do + require 'machine_tag' + database_tags = [ ::MachineTag::Tag.machine_tag('database', 'active', true), ::MachineTag::Tag.machine_tag('database', 'lineage', new_resource.lineage), diff --git a/providers/load_balancer.rb b/providers/load_balancer.rb index 6df3d65..f23b298 100644 --- a/providers/load_balancer.rb +++ b/providers/load_balancer.rb @@ -19,12 +19,16 @@ # The create action that creates required tags for a load balancer server action :create do + require 'machine_tag' + machine_tag ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) new_resource.updated_by_last_action(true) end # The delete action that removes the load balancer specific tags from the server action :delete do + require 'machine_tag' + machine_tag ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) do action :delete end From 1d3c23a9a0895b6ab8574db67c6f1f11a702bdc9 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 11 Feb 2014 16:03:46 -0800 Subject: [PATCH 28/54] Add resources/providers to README.md. --- README.md | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 177 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ed15420..9030a6d 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,13 @@ Github Repository: [https://github.com/rightscale-cookbooks/rightscale_tag](http # Requirements -* Chef 11 or above -* [machine_tag] cookbook -* [marker] cookbook +* Requires Chef 11 or higher * Platform * Ubuntu 12.04 * CentOS 6.4 +* Cookbooks + * [machine_tag] + * [marker] [machine_tag]: https://github.com/rightscale-cookbooks/machine_tag [marker]: https://github.com/rightscale-cookbooks/marker @@ -49,16 +50,187 @@ There are no attributes in this cookbook. # Recipes -## default +## `rightscale_tag::default` Sets the standard machine tags for a RightScale server which are `server:uuid`, `server:public_ip_X`, `server:private_ip_X` (where `X` is 0, 1, etc.). -## monitoring +## `rightscale_tag::monitoring` Sets the standard machine tag to enable RightScale monitoring which is `rs_monitoring:state=active`. This should only be set when `collectd` or equivalent is sending data to RightScale (for more information see [rs-base]). [rs-base]: https://github.com/rightscale-cookbooks/rs-base +# Resources/Providers + +## `rightscale_tag_load_balancer` + +A resource to create and remove tags to identify a load balancer server. + +### Actions + + + + + + + + + + + + + + + + + +
ActionsDescriptionDefault
:createCreates the tags required for the load balancer serverYes
:deleteRemoves the tags from the load balancer server
+ +### Attributes + + + + + + + + + + + + + + +
AttributeDescriptionDefault ValueRequired
application_nameThe name of the application the load balancer will servenameYes
+ +## `rightscale_tag_application` + +A resource to create and remove tags to identify an application server. + +### Actions + + + + + + + + + + + + + + + + + +
ActionsDescriptionDefault
:createCreates the tags required for the application serverYes
:deleteRemoves the tags from the application server
+ +### Attributes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault ValueRequired
application_nameThe name of the applicationnameYes
bind_ip_addressThe IP address the application is bound toYes
bind_portThe port the application is bound toYes
vhost_pathThe vhost or path of the applicationYes
+ +## `rightscale_tag_database` + +A resource to create and remove tags to identify a database server including its role of master or slave. + +### Actions + + + + + + + + + + + + + + + + + +
ActionsDescriptionDefault
:createCreates the tags required for the database serverYes
:deleteRemoves the tags from the database server
+ +### Attributes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionDefault ValueRequired
lineageThe lineage of the databasenameYes
bind_ip_addressThe IP address the database is bound toYes
bind_portThe port the database is bound toYes
roleThe role of the database; this can be "master" or "slave"No
+ +# Helpers + +## `find_load_balancer_servers` + +## `find_application_servers` + +## `find_database_servers` + +# Usage + # Author Author:: RightScale, Inc. () From f59dcaf8828044bed37623338e8e877c7ecb78e1 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 11 Feb 2014 16:56:12 -0800 Subject: [PATCH 29/54] Typo fix. --- libraries/rightscale_tag_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index bfa9bf6..5e5bef3 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -98,7 +98,7 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) # `application_name` is given, it will find all application servers serving that application. # # @param node [Chef::Node] the Chef node - # @param application_name [String, nil] the name of the application server by the application servers + # @param application_name [String, nil] the name of the application served by the application servers # to search for # # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation @@ -182,7 +182,7 @@ def self.find_application_servers(node, application_name = nil, options = {}) # `application_name` is given, it will find all application servers serving that application. # # @param node [Chef::Node] the Chef node - # @param application_name [String, nil] the name of the application server by the application servers + # @param application_name [String, nil] the name of the application served by the application servers # to search for # # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation From e7cadf5f9b9cbfc7ebcd50654b58b61e2f6c256a Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 11 Feb 2014 17:01:15 -0800 Subject: [PATCH 30/54] Use strings instead of symbols for example. --- libraries/rightscale_tag_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 5e5bef3..3006551 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -201,8 +201,8 @@ def find_application_servers(node, application_name = nil, options = {}) # # @param node [Chef::Node] the Chef node # @param lineage [String] the lineage of the database servers to search for - # @param role [Symbol, String] the role of the database servers to search for; this should be `:master` - # or `:slave` + # @param role [String] the role of the database servers to search for; this should be `'master'` or + # `'slave'` # # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation # From 079f37ab83ea0095ee4498d2250296f5bb5f9251 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 11 Feb 2014 17:02:56 -0800 Subject: [PATCH 31/54] Add helpers to README.md. --- README.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9030a6d..fe17537 100644 --- a/README.md +++ b/README.md @@ -51,12 +51,14 @@ There are no attributes in this cookbook. # Recipes ## `rightscale_tag::default` - -Sets the standard machine tags for a RightScale server which are `server:uuid`, `server:public_ip_X`, `server:private_ip_X` (where `X` is 0, 1, etc.). +Sets the standard machine tags for a RightScale server which are `server:uuid`, +`server:public_ip_X`, `server:private_ip_X` (where `X` is 0, 1, etc.). ## `rightscale_tag::monitoring` -Sets the standard machine tag to enable RightScale monitoring which is `rs_monitoring:state=active`. This should only be set when `collectd` or equivalent is sending data to RightScale (for more information see [rs-base]). +Sets the standard machine tag to enable RightScale monitoring which is +`rs_monitoring:state=active`. This should only be set when `collectd` or +equivalent is sending data to RightScale (for more information see [rs-base]). [rs-base]: https://github.com/rightscale-cookbooks/rs-base @@ -164,7 +166,8 @@ A resource to create and remove tags to identify an application server. ## `rightscale_tag_database` -A resource to create and remove tags to identify a database server including its role of master or slave. +A resource to create and remove tags to identify a database server including its +role of master or slave. ### Actions @@ -215,7 +218,7 @@ A resource to create and remove tags to identify a database server including its role - The role of the database; this can be "master" or "slave" + The role of the database; this can be 'master' or 'slave' No @@ -223,12 +226,140 @@ A resource to create and remove tags to identify a database server including its # Helpers +This cookbook also provides three helper methods for finding servers of each +type. To use them in a recipe add the following: + +```ruby +class Chef::Recipe + include RightScale::RightScaleTag +end +``` + ## `find_load_balancer_servers` +Find load balancer servers using tags. This will find all active load balancer +servers, or, if `application_name` is given, it will find all load balancer +servers serving for that application. + +```ruby +def find_load_balancer_servers(node, application_name = nil, options = {}) +``` + +### Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionType
nodethe Chef nodeChef::Node
application_namethe name of the application served by load balancer servers to search for; this is an optional parameterString
optionsoptional parametersHash
options[:query_timeout]the seconds to timeout for the query operation; the default is `120`Integer
+ ## `find_application_servers` +Find application servers using tags. This will find all active application +servers, or, if `application_name` is given, it will find all application +servers serving that application. + +```ruby +def find_application_servers(node, application_name = nil, options = {}) +``` + +### Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionType
nodethe Chef nodeChef::Node
application_namethe name of the application served by the application servers to search for; this is an optional parameterString
optionsoptional parametersHash
options[:query_timeout]the seconds to timeout for the query operation; the default is `120`Integer
+ ## `find_database_servers` +Find database servers using tags. This will find all active database servers, +or, if `lineage` is given, it will find all database servers for that linage, +or, if `role` is specified it will find the database server(s) with that role. + +```ruby +def find_database_servers(node, lineage = nil, role = nil, options = {}) +``` + +### Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionType
nodethe Chef nodeChef::Node
lineagethe lineage of the database servers to search for; this is an optional parameterString
rolethe role of the database servers to search for; this should be 'master' or 'slave'; this is an optional parameterString
optionsoptional parametersHash
options[:query_timeout]the seconds to timeout for the query operation; the default is `120`Integer
+ # Usage # Author From b78512f8a20faee29e8ac69bb6629b89dcd9be48 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Wed, 12 Feb 2014 15:57:03 -0800 Subject: [PATCH 32/54] Remove extra bracket. --- libraries/rightscale_tag_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 3006551..c68b0b5 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -297,7 +297,7 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) server_hash['master_since'] = master_since else server_hash['role'] = 'slave' - server_hash['slave_since]'] = slave_since + server_hash['slave_since'] = slave_since end elsif master_active server_hash['role'] = 'master' From 0c22a393d8a0d3f6bb9f94f30df33d418d6081f9 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Wed, 12 Feb 2014 17:23:38 -0800 Subject: [PATCH 33/54] Add a spec test that would have caught that extra bracket. --- spec/unit_test/rightscale_tag_helper_spec.rb | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 3a993ad..09d2372 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -317,6 +317,43 @@ class Fake; end end end + context 'when a server has both master and slave tags' do + let(:database_master_with_slave_tag) do + MachineTag::Set[*database_master, 'database:slave_active=1391802974'] + end + + let(:database_slave_with_master_tag) do + MachineTag::Set[*database_slave, 'database:master_active=1391803832'] + end + + let(:tags) do + [database_master_with_slave_tag, database_slave_with_master_tag] + end + + it 'returns role of the latest tag' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:active=true', + {:required_tags => Set[ + 'server:uuid', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} + ).and_return(tags) + response = fake.find_database_servers(node) + + response['01-83PJQDO8911IT']['tags'].should eq(database_master_with_slave_tag) + response['01-83PJQDO8911IT']['role'].should eq('master') + response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + response['01-83PJQDO8911IT']['slave_since'].should be_nil + + response['01-83PJQDO8922IT']['tags'].should eq(database_slave_with_master_tag) + response['01-83PJQDO8922IT']['role'].should eq('slave') + response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) + response['01-83PJQDO8922IT']['master_since'].should be_nil + end + end + context 'when the database lineage is given and the role is not given' do let(:tags) do [database_master, database_slave] From f384a5fce0a5a1ee5b12e0cc534d452b886f13ea Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Wed, 12 Feb 2014 17:28:05 -0800 Subject: [PATCH 34/54] Progress on the Usage section of README.md. --- README.md | 108 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index fe17537..e68aee8 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,14 @@ [![Build Status](https://travis-ci.org/rightscale-cookbooks/rightscale_tag.png?branch=master)](https://travis-ci.org/rightscale-cookbooks/rightscale_tag) -This cookbook provides recipes and library methods for dealing with machine tags -in RightScale. It builds on the resources and library methods in the -[machine_tag] cookbook and provides a higher level set of functionality dealing -specifically with RightScale. In the future it will include support for defining -a 3-tier web application architecture on RightScale with machine tags. +This cookbook provides recipes, resources, providers, and library methods for +dealing with machine tags in RightScale. It builds on the resources and library +methods in the [machine_tag] cookbook and provides a higher level set of +functionality dealing specifically with RightScale. There are resources, +providers, and library methods for definign a 3-tier web application consisting +of load balancer, application, and database servers. The resources and providers +allow for setting up tags on the respective servers while the helper methods can +be used by other servers needing to find them. For information about some of the machine tags used by this cookbook, see [List of Instance RightScale Tags]. @@ -44,6 +47,43 @@ or, alternatively, used with `include_recipe` at the end of a recipe doing that. Please see the [rs-base] cookbook for how these recipes are used in RightScale ServerTemplates. +[rs-base]: https://github.com/rightscale-cookbooks/rs-base + +## 3-Tier Web Applications + +This cookbook supports building a 3-tier web application deployment architecture +by providing an interface with tags on servers that can be set up with resources +and providers and searched for using helper methods. For a complete +implementation of a 3-tier LAMP stack using this cookbook, please see the +[rs-haproxy], [rs-application_php], and [rs-mysql] cookbooks. + +[rs-haproxy]: https://github.com/rightscale-cookbooks/rs-haproxy +[rs-application_php]: https://github.com/rightscale-cookbooks/rs-application_php +[rs-mysql]: https://github.com/rightscale-cookbooks/rs-mysql + +### Load Balancer Servers + +================================================================================ + +* **`load_balancer:active_=true`** - specifies an application that the load balancer server serves; examples: `load_balancer:active_api=true`, `load_balancer:active_www=true` + +### Application Servers + +================================================================================ + +* **`application:active_=true`** - specifies an application that the application server serves; examples: `application:active_api=true`, `application:active_www=true` +* **`application:bind_ip_address_=`** - specifies the bind IP address of the application server; examples: `application:bind_ip_address_api=192.0.2.1`, `application:bind_ip_address_www=192.0.2.2` +* **`application:bind_port_=`** - specifies the bind port of the application server; examples: `application:bind_port_api=8080`, `application:bind_port_www=8080` +* **`application:vhost_path_`** - specifies the vhost or path name the application serves; examples: `application:vhost_path_api=api.example.com`, `application:vhost_path_www=/` + +### Database Servers + +================================================================================ + +* **`database:active=true`** - specifies that a server is an active database server +* **`database:lineage=`** - specifies the lineage of the database server; example: `database:lineage=production` +* **`database:master_active=`** - specifies that the database server is an active master since timestamp + # Attributes There are no attributes in this cookbook. @@ -60,8 +100,6 @@ Sets the standard machine tag to enable RightScale monitoring which is `rs_monitoring:state=active`. This should only be set when `collectd` or equivalent is sending data to RightScale (for more information see [rs-base]). -[rs-base]: https://github.com/rightscale-cookbooks/rs-base - # Resources/Providers ## `rightscale_tag_load_balancer` @@ -78,12 +116,12 @@ A resource to create and remove tags to identify a load balancer server. :create - Creates the tags required for the load balancer server - Yes + creates the tags required for the load balancer server + yes :delete - Removes the tags from the load balancer server + removes the tags from the load balancer server @@ -99,9 +137,9 @@ A resource to create and remove tags to identify a load balancer server. application_name - The name of the application the load balancer will serve + the name of the application the load balancer will serve name - Yes + yes @@ -119,12 +157,12 @@ A resource to create and remove tags to identify an application server. :create - Creates the tags required for the application server - Yes + creates the tags required for the application server + yes :delete - Removes the tags from the application server + removes the tags from the application server @@ -140,27 +178,27 @@ A resource to create and remove tags to identify an application server. application_name - The name of the application + the name of the application name - Yes + yes bind_ip_address - The IP address the application is bound to + the IP address the application is bound to - Yes + yes bind_port - The port the application is bound to + the port the application is bound to - Yes + yes vhost_path - The vhost or path of the application + the vhost or path of the application - Yes + yes @@ -179,12 +217,12 @@ role of master or slave. :create - Creates the tags required for the database server - Yes + creates the tags required for the database server + yes :delete - Removes the tags from the database server + removes the tags from the database server @@ -200,27 +238,27 @@ role of master or slave. lineage - The lineage of the database + the lineage of the database name - Yes + yes bind_ip_address - The IP address the database is bound to + the IP address the database is bound to - Yes + yes bind_port - The port the database is bound to + the port the database is bound to - Yes + yes role - The role of the database; this can be 'master' or 'slave' + the role of the database; this can be 'master' or 'slave' - No + no @@ -360,8 +398,6 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) -# Usage - # Author Author:: RightScale, Inc. () From 72e56a29caefda2875cc0a9f9fbeaafb230e5fd1 Mon Sep 17 00:00:00 2001 From: Nitin Mohan Date: Thu, 13 Feb 2014 11:26:12 -0800 Subject: [PATCH 35/54] Fix query tags for load balancer and application server helpers --- libraries/rightscale_tag_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index c68b0b5..e50a90c 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -56,7 +56,7 @@ def self.find_load_balancer_servers(node, application_name = nil, options = {}) if application_name query_tag = ::MachineTag::Tag.machine_tag('load_balancer', "active_#{application_name}", true) else - query_tag = 'load_balancer:' + query_tag = 'load_balancer' end servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) @@ -146,7 +146,7 @@ def self.find_application_servers(node, application_name = nil, options = {}) ::MachineTag::Tag.machine_tag('application', "vhost_path_#{application_name}", '*') ) else - query_tag = 'application:' + query_tag = 'application' end servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) From 5300e3c327d33ab7abcb9d418c5b3132e98cdb6e Mon Sep 17 00:00:00 2001 From: Nitin Mohan Date: Thu, 13 Feb 2014 12:08:55 -0800 Subject: [PATCH 36/54] Have ':active=true' tag for load balancer and application servers just like databases --- libraries/rightscale_tag_helper.rb | 4 ++-- providers/application.rb | 2 ++ providers/load_balancer.rb | 13 +++++++++++-- spec/unit_test/rightscale_tag_helper_spec.rb | 8 ++++++-- .../application/serverspec/server_spec.rb | 5 +++-- .../load_balancer/serverspec/server_spec.rb | 7 ++++--- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index e50a90c..ec08504 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -56,7 +56,7 @@ def self.find_load_balancer_servers(node, application_name = nil, options = {}) if application_name query_tag = ::MachineTag::Tag.machine_tag('load_balancer', "active_#{application_name}", true) else - query_tag = 'load_balancer' + query_tag = ::MachineTag::Tag.machine_tag('load_balancer', 'active', true) end servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) @@ -146,7 +146,7 @@ def self.find_application_servers(node, application_name = nil, options = {}) ::MachineTag::Tag.machine_tag('application', "vhost_path_#{application_name}", '*') ) else - query_tag = 'application' + query_tag = ::MachineTag::Tag.machine_tag('application', 'active', true) end servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) diff --git a/providers/application.rb b/providers/application.rb index ec3813e..2e4d681 100644 --- a/providers/application.rb +++ b/providers/application.rb @@ -22,6 +22,7 @@ require 'machine_tag' [ + ::MachineTag::Tag.machine_tag('application', "active", true), ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), ::MachineTag::Tag.machine_tag('application', "bind_port_#{new_resource.application_name}", new_resource.bind_port), @@ -37,6 +38,7 @@ require 'machine_tag' [ + ::MachineTag::Tag.machine_tag('application', "active", true), ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), ::MachineTag::Tag.machine_tag('application', "bind_port_#{new_resource.application_name}", new_resource.bind_port), diff --git a/providers/load_balancer.rb b/providers/load_balancer.rb index f23b298..ea183e3 100644 --- a/providers/load_balancer.rb +++ b/providers/load_balancer.rb @@ -21,7 +21,12 @@ action :create do require 'machine_tag' - machine_tag ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) + [ + ::MachineTag::Tag.machine_tag('load_balancer', "active", true), + ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) + ].each do |tag| + machine_tag tag + end new_resource.updated_by_last_action(true) end @@ -29,7 +34,11 @@ action :delete do require 'machine_tag' - machine_tag ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) do + [ + ::MachineTag::Tag.machine_tag('load_balancer', "active", true), + ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) + ].each do |tag| + machine_tag tag action :delete end new_resource.updated_by_last_action(true) diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 09d2372..16fcaa9 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -40,6 +40,7 @@ class Fake; end let(:load_balancer_1) do MachineTag::Set[ 'server:uuid=01-83PJQDO8911IT', + 'load_balancer:active=true', 'load_balancer:active_www=true', 'load_balancer:active_api=true', 'server:public_ip_0=157.56.165.202', @@ -51,6 +52,7 @@ class Fake; end let(:load_balancer_2) do MachineTag::Set[ 'server:uuid=01-83PJQDO8922IT', + 'load_balancer:active=true', 'load_balancer:active_api=true', 'server:public_ip_0=157.56.166.202', 'server:public_ip_1=157.56.166.203', @@ -64,7 +66,7 @@ class Fake; end it 'returns tags from all load balancer servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'load_balancer:', {:required_tags => Set['server:uuid']} + node, 'load_balancer:active=true', {:required_tags => Set['server:uuid']} ).and_return(tags) response = fake.find_load_balancer_servers(node) @@ -120,6 +122,7 @@ class Fake; end let(:application_server_1) do MachineTag::Set[ 'server:uuid=01-83PJQDO8911IT', + 'application:active=true', 'application:active_www=true', 'application:active_api=true', 'application:bind_ip_address_www=157.56.165.202', @@ -137,6 +140,7 @@ class Fake; end let(:application_server_2) do MachineTag::Set[ 'server:uuid=01-83PJQDO8922IT', + 'application:active=true', 'application:active_api=true', 'application:bind_ip_address_api=157.56.166.202', 'application:bind_port_api=443', @@ -177,7 +181,7 @@ class Fake; end it 'returns tags of all application servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'application:', + node, 'application:active=true', {:required_tags => Set['server:uuid']} ).and_return(tags) response = fake.find_application_servers(node) diff --git a/test/integration/application/serverspec/server_spec.rb b/test/integration/application/serverspec/server_spec.rb index d7b68de..c2842d4 100644 --- a/test/integration/application/serverspec/server_spec.rb +++ b/test/integration/application/serverspec/server_spec.rb @@ -16,10 +16,11 @@ it "should have a private IP of" do app_tags['server:private_ip_0'].first.value.should match ('10.0.2.15') end - it "should have 4 application specific entries" do - app_tags['application'].length.should == 4 + it "should have 5 application specific entries" do + app_tags['application'].length.should == 5 end it "should be active" do + app_tags['application:active'].first.value.should be_true app_tags['application:active_www'].first.value.should be_true end it "should have an IP of 10.0.0.1" do diff --git a/test/integration/load_balancer/serverspec/server_spec.rb b/test/integration/load_balancer/serverspec/server_spec.rb index aecdb7d..6c36c33 100644 --- a/test/integration/load_balancer/serverspec/server_spec.rb +++ b/test/integration/load_balancer/serverspec/server_spec.rb @@ -16,10 +16,11 @@ it "should have a private IP of 10.0.2.16" do lb_tags['server:private_ip_0'].first.value.should match ('10.0.2.16') end - it "should have 1 application specific entry" do - lb_tags['load_balancer'].length.should == 1 + it "should have 2 application specific entry" do + lb_tags['load_balancer'].length.should == 2 end - it "should have an active API" do + it "should be active" do + lb_tags['load_balancer:active'].should be_true lb_tags['load_balancer:active_api'].should be_true end end From f70d41f3c31707daf0a1e8598e090848fa5acca7 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Thu, 13 Feb 2014 15:07:05 -0800 Subject: [PATCH 37/54] Update examples to include new tags. [ci skip] --- libraries/rightscale_tag_helper.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index ec08504..df8f659 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -37,6 +37,7 @@ module RightscaleTag # { # '01-ABCDEF123456' => { # 'tags' => MachineTag::Set[ + # 'load_balancer:active=true', # 'load_balancer:active_www=true', # 'server:public_ip_0=203.0.113.2', # 'server:private_ip_0=10.0.0.2', @@ -112,6 +113,7 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) # { # '01-ABCDEF7890123' => { # 'tags' => MachineTag::Set[ + # 'application:active=true', # 'application:active_www=true', # 'application:bind_ip_address_www=10.0.0.3', # 'application:bind_port_www=8080', From 7db02d3747a7e983edcf88d676c60bfb2f655cbc Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Thu, 13 Feb 2014 15:34:46 -0800 Subject: [PATCH 38/54] Finish up 3-tier usage sections. [ci skip] --- README.md | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 224 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e68aee8..368fb77 100644 --- a/README.md +++ b/README.md @@ -63,26 +63,239 @@ implementation of a 3-tier LAMP stack using this cookbook, please see the ### Load Balancer Servers -================================================================================ +The tags used for load balancer servers are as follows: -* **`load_balancer:active_=true`** - specifies an application that the load balancer server serves; examples: `load_balancer:active_api=true`, `load_balancer:active_www=true` +* **`load_balancer:active=true`** - specifies that that the load balancer server + is active +* **`load_balancer:active_=true`** - specifies an application + that the load balancer server serves; examples: + `load_balancer:active_api=true`, `load_balancer:active_www=true` + +These tags can be set up on a server using the [`rightscale_tag_load_balancer`] +resource and provider. For example, to tag a load balancer server for `api` and +`www` applications respectively in a recipe: + +```ruby +rightscale_tag_load_balancer 'api' + +rightscale_tag_load_balancer 'www' + +# the server where this recipe is run will now have the following tags: +# load_balancer:active=true +# load_balancer:active_api=true +# load_balancer:active_www=true +``` + +The [`find_load_balancer_servers`] method can be used to find tagged load +balancer servers. For example, to find load balancer servers for the `www` +application in a Chef recipe: + +```ruby +class Chef::Recipe + include Rightscale::RightscaleTag +end + +lb_servers = find_load_balancer_servers(node, 'www') + +# lb_servers will be a hash with contents like: +# { +# '01-ABCDEF123456' => { +# 'tags' => MachineTag::Set[ +# 'load_balancer:active=true', +# 'load_balancer:active_www=true', +# 'server:public_ip_0=203.0.113.2', +# 'server:private_ip_0=10.0.0.2', +# 'server:uuid=01-ABCDEF123456' +# ], +# 'application_names' => ['www'], +# 'public_ips' => ['203.0.113.2'], +# 'private_ips' => ['10.0.0.2'] +# } +# } + +lb_servers.each do |uuid, server_info| + # here an application server could add each load balancer to its inbound + # firewall rules using server_info['private_ips'] +end +``` + +[`rightscale_tag_load_balancer`]: #rightscale_tag_load_balancer +[`find_load_balancer_servers`]: #find_load_balancer_servers ### Application Servers -================================================================================ +The tags used for application servers are as follows: + +* **`application:active=true`** - specifies that the application server is + active +* **`application:active_=true`** - specifies an application + that the application server serves; examples: `application:active_api=true`, + `application:active_www=true` +* **`application:bind_ip_address_=`** - specifies + the bind IP address of the application server; examples: + `application:bind_ip_address_api=10.0.0.1`, + `application:bind_ip_address_www=10.0.0.2` +* **`application:bind_port_=`** - specifies the bind + port of the application server; examples: `application:bind_port_api=8080`, + `application:bind_port_www=8080` +* **`application:vhost_path_`** - specifies the + vhost or path name the application serves; examples: + `application:vhost_path_api=api.example.com`, `application:vhost_path_www=/` + +These tags can be set up on a server using the [`rightscale_tag_application`] +resource and provider. For example, to tag an application server for `api` and +`www` applications respectively in a recipe: + +```ruby +rightscale_tag_application 'api' do + bind_ip_address node['cloud']['private_ips'][0] + bind_port 8080 + vhost_path 'api.example.com' +end + +rightscale_tag_application 'www' do + bind_ip_address node['cloud']['private_ips'][0] + bind_port 8080 + vhost_path '/' +end + +# the server where this recipe is run will now have the following tags: +# application:active=true +# application:active_api=true +# application:active_www=true +# application:bind_ip_address_api=10.0.0.1 +# application:bind_ip_address_www=10.0.0.1 +# application:bind_port_api=8080 +# application:bind_port_www=8080 +# application:vhost_path_api=api.example.com +# application:vhost_path_www=/ +``` -* **`application:active_=true`** - specifies an application that the application server serves; examples: `application:active_api=true`, `application:active_www=true` -* **`application:bind_ip_address_=`** - specifies the bind IP address of the application server; examples: `application:bind_ip_address_api=192.0.2.1`, `application:bind_ip_address_www=192.0.2.2` -* **`application:bind_port_=`** - specifies the bind port of the application server; examples: `application:bind_port_api=8080`, `application:bind_port_www=8080` -* **`application:vhost_path_`** - specifies the vhost or path name the application serves; examples: `application:vhost_path_api=api.example.com`, `application:vhost_path_www=/` +The [`find_application_servers`] method can be used to find tagged application +servers. For example, to find application servers for the `www`application in a +Chef recipe: + +```ruby +class Chef::Recipe + include Rightscale::RightscaleTag +end + +app_servers = find_application_servers(node, 'www') + +# app_servers will be a hash with content like: +# { +# '01-ABCDEF7890123' => { +# 'tags' => MachineTag::Set[ +# 'application:active=true', +# 'application:active_www=true', +# 'application:bind_ip_address_www=10.0.0.3', +# 'application:bind_port_www=8080', +# 'application:vhost_path_www=/', +# 'server:public_ip_0=203.0.113.3', +# 'server:private_ip_0=10.0.0.3', +# 'server:uuid=01-ABCDEF7890123' +# ], +# 'applications' => { +# 'www' => { +# 'bind_ip_address' => '10.0.0.3', +# 'bind_port' => 8080, +# 'vhost_path' => '/', +# } +# }, +# 'public_ips' => ['203.0.113.3'], +# 'private_ips' => ['10.0.0.3'] +# } +# } + +app_servers.each do |uuid, server_info| + # here a load balancer server could add application servers to its + # configuration using the values in server_info['applications']['www'] +end +``` + +[`rightscale_tag_application`]: #rightscale_tag_application +[`find_application_servers`]: #find_application_servers ### Database Servers -================================================================================ +The tags used for database servers are as follows: + +* **`database:active=true`** - specifies that a server is an active database + server +* **`database:lineage=`** - specifies the lineage of the database + server; examples: `database:lineage=production`, `database:lineage=staging` +* **`database:master_active=`** - specifies that the database server + is an active master since `timestamp`; a timestamp is the number of seconds + since the UNIX epoch; examples: `database:master_active=1391473172` (in this + case the timestamp represents 2014-02-04 00:19:32 UTC) +* **`database:slave_active=`** - specifies that the database server + is an active slave since `timestamp`; a timestamp is the number of seconds + since the UNIX epoch; examples: `database:slave_active=1391473672` (in this + case the timestamp represents 2014-02-04 00:27:52 UTC) +* **`database:bind_ip_address=`** - specifies the bind IP address + of the database server; examples: `database:bind_ip_address=10.0.0.4` +* **`database:bind_port=`** - specifies the bind port of the database + server; examples: `database:bind_port=3306` + +These tags can be set up on a server using the [`rightscale_tag_database`] +resource and provider. For example, to tag a database server for the `staging` +lineage as a master in a recipe: + +```ruby +rightscale_tag_database 'staging' do + role 'master' + bind_ip_address node['cloud']['private_ips'][0] + bind_port 3306 +end + +# the server where this recipe is run will now have the following tags: +# database:active=true +# database:lineage=staging +# database:master_active=1391473172 +# database:bind_ip_address=10.0.0.1 +# database:bind_port=3306 +``` + +The [`find_database_servers`] method can be used to find tagged database +servers. For example, to find the master database server for the `staging` +lineage in a Chef recipe: + +```ruby +class Chef::Recipe + include Rightscale::RightscaleTag +end + +db_servers = find_database_servers(node, 'staging', 'master') + +# db_servers will be a hash with content like: +# { +# '01-ABCDEF4567890' => { +# 'tags' => MachineTag::Set[ +# 'database:active=true', +# 'database:master_active=1391803034', +# 'database:lineage=example', +# 'server:public_ip_0=203.0.113.4', +# 'server:private_ip_0=10.0.0.4', +# 'server:uuid=01-ABCDEF4567890' +# ], +# 'lineage' => 'example', +# 'bind_ip_address' => '10.0.0.4', +# 'bind_port' => 3306, +# 'role' => 'master', +# 'master_since' => Time.at(1391803034), +# 'public_ips' => ['203.0.113.4'], +# 'private_ips' => ['10.0.0.4'] +# } +# } + +db_servers.each do |uuid, server_info| + # here a slave database server could set up replication from the master using + # server_info['bind_ip_address'] and server_info['bind_port'] +end +``` -* **`database:active=true`** - specifies that a server is an active database server -* **`database:lineage=`** - specifies the lineage of the database server; example: `database:lineage=production` -* **`database:master_active=`** - specifies that the database server is an active master since timestamp +[`rightscale_tag_database`]: #rightscale_tag_database +[`find_database_servers`]: #find_database_servers # Attributes From cd83846f862d500f356a7a1d35fd038a9f1de3ad Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 14 Feb 2014 16:27:17 -0800 Subject: [PATCH 39/54] Add only_latest_for_role option to find_database_servers. --- README.md | 7 +- libraries/rightscale_tag_helper.rb | 24 ++++++- spec/unit_test/rightscale_tag_helper_spec.rb | 74 +++++++++++++++++++- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 368fb77..5b728d1 100644 --- a/README.md +++ b/README.md @@ -265,7 +265,7 @@ class Chef::Recipe include Rightscale::RightscaleTag end -db_servers = find_database_servers(node, 'staging', 'master') +db_servers = find_database_servers(node, 'staging', 'master', only_latest_for_role: true) # db_servers will be a hash with content like: # { @@ -604,6 +604,11 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) optional parameters Hash + + options[:only_latest_for_role] + only return the latest server tagged for a role; the default is `false` + Boolean + options[:query_timeout] the seconds to timeout for the query operation; the default is `120` diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index df8f659..efffd4d 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -206,6 +206,7 @@ def find_application_servers(node, application_name = nil, options = {}) # @param role [String] the role of the database servers to search for; this should be `'master'` or # `'slave'` # + # @option options [Boolean] :only_latest_for_role (false) only return the latest server tagged for a role # @option options [Integer] :query_timeout (120) the seconds to timeout for the query operation # # @return [Mash] a hash with server UUIDs as keys and server information hashes as values @@ -259,6 +260,7 @@ def find_application_servers(node, application_name = nil, options = {}) def self.find_database_servers(node, lineage = nil, role = nil, options = {}) require 'machine_tag' + only_latest_for_role = options.delete(:only_latest_for_role) required_tags(options) if role @@ -281,7 +283,7 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) end end - build_server_hash(servers) do |tags| + server_hashes = build_server_hash(servers) do |tags| server_hash = { 'lineage' => tags['database:lineage'].first.value, 'bind_ip_address' => tags['database:bind_ip_address'].first.value, @@ -311,6 +313,26 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) server_hash end + + if only_latest_for_role + server_hashes = server_hashes.sort_by {|_, server_hash| server_hash['lineage']}.chunk do |_, server_hash| + server_hash['lineage'] + end.map do |lineage, server_hashes| + server_hashes.sort_by {|_, server_hash| server_hash['role'] || ''}.chunk do |_, server_hash| + server_hash['role'] || '' + end.map do |role, server_hashes| + if role.empty? + server_hashes + else + [server_hashes.max_by {|uuid, server_hash| server_hash["#{role}_since"]}] + end + end + end + + server_hashes = Mash.from_hash(Hash[server_hashes.flatten(2)]) + end + + server_hashes end # Find database servers using tags. This will find all active database servers, or, if `lineage` is diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 16fcaa9..04a449f 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -284,9 +284,45 @@ class Fake; end ] end + let(:database_master_2) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8933IT', + 'database:active=true', + 'database:master_active=1391802023', + 'database:lineage=example', + 'database:bind_ip_address=10.0.0.2', + 'database:bind_port=3306', + 'server:private_ip_0=10.0.0.2', + 'server:public_ip_0=157.56.165.204', + ] + end + + let(:database_slave_2) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8944IT', + 'database:active=true', + 'database:slave_active=1391803781', + 'database:lineage=example', + 'database:bind_ip_address=157.56.166.204', + 'database:bind_port=3306', + 'server:public_ip_0=157.56.166.204', + ] + end + + let(:database_standalone) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8955IT', + 'database:active=true', + 'database:lineage=example', + 'database:bind_ip_address=10.0.0.3', + 'database:bind_port=3306', + 'server:private_ip_0=10.0.0.3', + ] + end + context 'when no database role or lineage is specified' do let(:tags) do - [database_master, database_slave] + [database_master, database_slave, database_standalone] end it 'returns tags of all database servers' do @@ -301,12 +337,15 @@ class Fake; end ).and_return(tags) response = fake.find_database_servers(node) + response.keys.should match_array(['01-83PJQDO8911IT', '01-83PJQDO8922IT', '01-83PJQDO8955IT']) + response['01-83PJQDO8911IT']['tags'].should eq(database_master) response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) response['01-83PJQDO8911IT']['lineage'].should eq('example') response['01-83PJQDO8911IT']['role'].should eq('master') response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) + response['01-83PJQDO8911IT'].should_not include('slave_since') response['01-83PJQDO8911IT']['bind_ip_address'].should eq('10.0.0.1') response['01-83PJQDO8911IT']['bind_port'].should eq(3306) @@ -315,9 +354,42 @@ class Fake; end response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) response['01-83PJQDO8922IT']['lineage'].should eq('example') response['01-83PJQDO8922IT']['role'].should eq('slave') + response['01-83PJQDO8922IT'].should_not include('master_since') response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) response['01-83PJQDO8922IT']['bind_ip_address'].should eq('157.56.166.202') response['01-83PJQDO8922IT']['bind_port'].should eq(3306) + + response['01-83PJQDO8955IT']['tags'].should eq(database_standalone) + response['01-83PJQDO8955IT']['private_ips'].should eq(['10.0.0.3']) + response['01-83PJQDO8955IT']['public_ips'].should eq([]) + response['01-83PJQDO8955IT']['lineage'].should eq('example') + response['01-83PJQDO8955IT'].should_not include('role', 'master_since', 'slave_since') + response['01-83PJQDO8955IT']['bind_ip_address'].should eq('10.0.0.3') + response['01-83PJQDO8955IT']['bind_port'].should eq(3306) + end + + context 'when only_latest_for_role is true' do + let(:tags) do + [database_master, database_slave, database_master_2, database_slave_2, database_standalone] + end + + it 'returns only the latest masters and slaves and any standalones' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:active=true', + {:required_tags => Set[ + 'server:uuid', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} + ).and_return(tags) + response = fake.find_database_servers(node, nil, nil, only_latest_for_role: true) + + response.keys.should match_array(['01-83PJQDO8911IT', '01-83PJQDO8922IT', '01-83PJQDO8955IT']) + response['01-83PJQDO8911IT']['tags'].should eq(database_master) + response['01-83PJQDO8922IT']['tags'].should eq(database_slave) + response['01-83PJQDO8955IT']['tags'].should eq(database_standalone) + end end end From ca3eb11aaaf89d0c5f416e6b1e83ab754eb87687 Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Tue, 18 Feb 2014 14:27:50 +0530 Subject: [PATCH 40/54] Expanded tests for only_latest_for_role option. --- spec/unit_test/rightscale_tag_helper_spec.rb | 84 +++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 04a449f..4fa9470 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -432,7 +432,7 @@ class Fake; end context 'when the database lineage is given and the role is not given' do let(:tags) do - [database_master, database_slave] + [database_master, database_slave, database_standalone] end it 'returns tags of all database servers' do @@ -447,11 +447,14 @@ class Fake; end ).and_return(tags) response = fake.find_database_servers(node, 'example') + response.keys.should match_array(['01-83PJQDO8911IT', '01-83PJQDO8922IT', '01-83PJQDO8955IT']) + response['01-83PJQDO8911IT']['tags'].should eq(database_master) response['01-83PJQDO8911IT']['private_ips'].should eq(['10.0.0.1']) response['01-83PJQDO8911IT']['public_ips'].should eq(['157.56.165.202', '157.56.165.203']) response['01-83PJQDO8911IT']['lineage'].should eq('example') response['01-83PJQDO8911IT']['role'].should eq('master') + response['01-83PJQDO8911IT'].should_not include('slave_since') response['01-83PJQDO8911IT']['master_since'].should eq(Time.at(1391803034)) response['01-83PJQDO8911IT']['bind_ip_address'].should eq('10.0.0.1') response['01-83PJQDO8911IT']['bind_port'].should eq(3306) @@ -461,9 +464,18 @@ class Fake; end response['01-83PJQDO8922IT']['public_ips'].should eq(['157.56.166.202', '157.56.166.203']) response['01-83PJQDO8922IT']['lineage'].should eq('example') response['01-83PJQDO8922IT']['role'].should eq('slave') + response['01-83PJQDO8922IT'].should_not include('master_since') response['01-83PJQDO8922IT']['slave_since'].should eq(Time.at(1391803892)) response['01-83PJQDO8922IT']['bind_ip_address'].should eq('157.56.166.202') response['01-83PJQDO8922IT']['bind_port'].should eq(3306) + + response['01-83PJQDO8955IT']['tags'].should eq(database_standalone) + response['01-83PJQDO8955IT']['private_ips'].should eq(['10.0.0.3']) + response['01-83PJQDO8955IT']['public_ips'].should eq([]) + response['01-83PJQDO8955IT']['lineage'].should eq('example') + response['01-83PJQDO8955IT'].should_not include('role', 'master_since', 'slave_since') + response['01-83PJQDO8955IT']['bind_ip_address'].should eq('10.0.0.3') + response['01-83PJQDO8955IT']['bind_port'].should eq(3306) end it 'returns an empty Mash when the lineage is not available' do @@ -481,6 +493,30 @@ class Fake; end response.should be_an_instance_of(Mash) response.should be_empty end + + context 'when only_latest_for_role is true' do + let(:tags) do + [database_master, database_slave, database_master_2, database_slave_2, database_standalone] + end + + it 'returns only the latest masters and slaves and any standalones' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:active=true', + {:required_tags => Set[ + 'server:uuid', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} + ).and_return(tags) + response = fake.find_database_servers(node, 'example', nil, only_latest_for_role: true) + + response.keys.should match_array(['01-83PJQDO8911IT', '01-83PJQDO8922IT', '01-83PJQDO8955IT']) + response['01-83PJQDO8911IT']['tags'].should eq(database_master) + response['01-83PJQDO8922IT']['tags'].should eq(database_slave) + response['01-83PJQDO8955IT']['tags'].should eq(database_standalone) + end + end end context 'when the database role is given and the lineage is not given' do @@ -546,6 +582,29 @@ class Fake; end response.should be_an_instance_of(Mash) response.should be_empty end + + context 'when only_latest_for_role is true for master role' do + let(:tags) do + [database_master, database_master_2] + end + + it 'returns only the latest master' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:master_active=*', + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} + ).and_return(tags) + response = fake.find_database_servers(node, nil, 'master', only_latest_for_role: true) + + response.keys.should match_array(['01-83PJQDO8911IT']) + response['01-83PJQDO8911IT']['tags'].should eq(database_master) + end + end end context 'when the database role and lineage is given' do @@ -645,6 +704,29 @@ class Fake; end response.should be_an_instance_of(Mash) response.should be_empty end + + context 'when only_latest_for_role is true for slave role' do + let(:tags) do + [database_slave, database_slave_2] + end + + it 'returns only the latest slave' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'database:slave_active=*', + {:required_tags => Set[ + 'server:uuid', + 'database:active=true', + 'database:lineage=*', + 'database:bind_ip_address=*', + 'database:bind_port=*', + ]} + ).and_return(tags) + response = fake.find_database_servers(node, 'example', 'slave', only_latest_for_role: true) + + response.keys.should match_array(['01-83PJQDO8922IT']) + response['01-83PJQDO8922IT']['tags'].should eq(database_slave) + end + end end end end From ce55f8da5d051718a7ab84523e0b9295fb0cf8bf Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Tue, 18 Feb 2014 16:32:34 -0800 Subject: [PATCH 41/54] Fix typo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b728d1..9a099d2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This cookbook provides recipes, resources, providers, and library methods for dealing with machine tags in RightScale. It builds on the resources and library methods in the [machine_tag] cookbook and provides a higher level set of functionality dealing specifically with RightScale. There are resources, -providers, and library methods for definign a 3-tier web application consisting +providers, and library methods for defining a 3-tier web application consisting of load balancer, application, and database servers. The resources and providers allow for setting up tags on the respective servers while the helper methods can be used by other servers needing to find them. From 2fb940e02d530290e649ff5689d5d7fb8965335f Mon Sep 17 00:00:00 2001 From: david-vo Date: Wed, 19 Feb 2014 15:24:12 -0800 Subject: [PATCH 42/54] Address code review comments --- .kitchen.yml | 27 ---------- test/cookbooks/fake/recipes/app_server.rb | 5 +- test/cookbooks/fake/recipes/db_server.rb | 4 +- test/cookbooks/fake/recipes/lb_server.rb | 2 +- .../application/serverspec/server_spec.rb | 54 ++++++++----------- .../application/serverspec/spec_helper.rb | 2 + .../database/serverspec/server_spec.rb | 40 +++++++------- .../database/serverspec/spec_helper.rb | 2 + .../default/serverspec/server_spec.rb | 27 ++++++---- .../default/serverspec/spec_helper.rb | 2 + .../load_balancer/serverspec/server_spec.rb | 32 +++++------ .../load_balancer/serverspec/spec_helper.rb | 2 + 12 files changed, 84 insertions(+), 115 deletions(-) diff --git a/.kitchen.yml b/.kitchen.yml index 4940637..11378f9 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -37,58 +37,31 @@ suites: - name: application run_list: - recipe[rightscale_tag] - - recipe[rightscale_tag::monitoring] - recipe[fake::app_server] attributes: rightscale: instance_uuid: 02-BBCDEFG123457 cloud: provider: vagrant - public_ips: - - null - - "" - - 33.33.33.10 - private_ips: - - null - - "" - - 10.0.2.15 # Database server tests - name: database run_list: - recipe[rightscale_tag] - - recipe[rightscale_tag::monitoring] - recipe[fake::db_server] attributes: rightscale: instance_uuid: 03-CBCDEFG123458 cloud: provider: vagrant - public_ips: - - null - - "" - - 33.33.33.12 - private_ips: - - null - - "" - - 10.0.2.17 # Load Balancer server tests - name: load_balancer run_list: - recipe[rightscale_tag] - - recipe[rightscale_tag::monitoring] - recipe[fake::lb_server] attributes: rightscale: instance_uuid: 04-DBCDEFG123459 cloud: provider: vagrant - public_ips: - - null - - "" - - 33.33.33.11 - private_ips: - - null - - "" - - 10.0.2.16 diff --git a/test/cookbooks/fake/recipes/app_server.rb b/test/cookbooks/fake/recipes/app_server.rb index 6cdfae3..71d03dd 100644 --- a/test/cookbooks/fake/recipes/app_server.rb +++ b/test/cookbooks/fake/recipes/app_server.rb @@ -19,12 +19,11 @@ delete = false -# Application test setup. We are only using www and not both www and api so the latter doesn't pollute the tag data rightscale_tag_application 'www' do bind_ip_address '10.0.0.1' bind_port 8080 vhost_path 'www.example.com' - action delete == true ? :delete : :create + action :create end # Use find_application_servers helper method and write it to a JSON file so the kitchen test can access it @@ -35,7 +34,7 @@ class Chef::Resource::RubyBlock ruby_block "Find application servers" do block do - File.open("/tmp/found_app_servers.json", "w") do |file| + ::File.open("/tmp/found_app_servers.json", "w") do |file| file.write find_application_servers(node, "www").to_json end end diff --git a/test/cookbooks/fake/recipes/db_server.rb b/test/cookbooks/fake/recipes/db_server.rb index 496781f..15e48bc 100644 --- a/test/cookbooks/fake/recipes/db_server.rb +++ b/test/cookbooks/fake/recipes/db_server.rb @@ -24,10 +24,10 @@ bind_ip_address '10.0.0.2' bind_port 3306 role 'master' - action delete == true ? :delete : :create + action :create end -# Use the find_database_server helper method and write it to a JSON file so the kitchen tests can access it +# Use the find_database_servers helper method and write it to a JSON file so the kitchen tests can access it class Chef::Resource::RubyBlock include Rightscale::RightscaleTag diff --git a/test/cookbooks/fake/recipes/lb_server.rb b/test/cookbooks/fake/recipes/lb_server.rb index 3c5e2e8..ca6469b 100644 --- a/test/cookbooks/fake/recipes/lb_server.rb +++ b/test/cookbooks/fake/recipes/lb_server.rb @@ -22,7 +22,7 @@ # Load balancer setup. We are only using api and not both api and www so the latter doesn't pollute the tag data rightscale_tag_load_balancer 'api server' do application_name 'api' - action delete == true ? :delete : :create + action :create end # Use find_load_balancer_servers helper method and write it to a JSON file so the kitchen tests can access it diff --git a/test/integration/application/serverspec/server_spec.rb b/test/integration/application/serverspec/server_spec.rb index c2842d4..622c920 100644 --- a/test/integration/application/serverspec/server_spec.rb +++ b/test/integration/application/serverspec/server_spec.rb @@ -1,61 +1,53 @@ # Test:: application server require 'spec_helper' +require 'socket' -#Get the hostname -host_name = `hostname -s`.chomp +describe "Application LWRP" do + let(:host_name) { Socket.gethostname } + let(:app_tags) { MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) } -app_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) - -describe "Application (www) server tags" do - it "should have a UUID of 02-BBCDEFG123457" do - app_tags['server:uuid'].first.value.should match ('02-BBCDEFG123457') - end - it "should have a public IP of" do - app_tags['server:public_ip_0'].first.value.should match ('33.33.33.10') - end - it "should have a private IP of" do - app_tags['server:private_ip_0'].first.value.should match ('10.0.2.15') - end it "should have 5 application specific entries" do app_tags['application'].length.should == 5 end + it "should be active" do app_tags['application:active'].first.value.should be_true app_tags['application:active_www'].first.value.should be_true end + it "should have an IP of 10.0.0.1" do - app_tags['application:bind_ip_address_www'].first.value.should match ('10.0.0.1') + app_tags['application:bind_ip_address_www'].first.value.should eq ('10.0.0.1') end + it "should have an port of 8080" do - app_tags['application:bind_port_www'].first.value.should match ('8080') + app_tags['application:bind_port_www'].first.value.should eq ('8080') end + it "should have vhost path of www.example.com" do - app_tags['application:vhost_path_www'].first.value.should match ('www.example.com') + app_tags['application:vhost_path_www'].first.value.should eq ('www.example.com') end end # We use find_application_servers helper to find all the application servers with name www, and we write results to # file. Here we are loading the file so it can be parsed -app_server_tags = JSON.parse(IO.read("/tmp/found_app_servers.json")) +describe "Using find_application_servers helper method, the found www server should" do + + let(:app_server_tags) { JSON.parse(IO.read("/tmp/found_app_servers.json")) } -describe "Found www application servers" do - it "should have a UUID of 02-BBCDEFG123457" do + it "return a UUID of 02-BBCDEFG123457" do app_server_tags.has_key?('02-BBCDEFG123457').should be_true end - it "should include a www server" do - app_server_tags['02-BBCDEFG123457']['applications'].has_key?('www').should be_true + + it "return a www server" do + app_server_tags['02-BBCDEFG123457']['applications'].should have_key('www') end - it "should include a bind IP address of 10.0.0.1" do - app_server_tags['02-BBCDEFG123457']['applications']['www']['bind_ip_address'].should match ('10.0.0.1') + + it "return a bind IP address of 10.0.0.1" do + app_server_tags['02-BBCDEFG123457']['applications']['www']['bind_ip_address'].should eq ('10.0.0.1') end - it "should include a bind port of 8080" do + + it "return a bind port of 8080" do app_server_tags['02-BBCDEFG123457']['applications']['www']['bind_port'].should == 8080 end - it "should NOT include an API server" do - app_server_tags['02-BBCDEFG123457']['applications'].has_key?('api').should be_false - end - it "should NOT include database server" do - app_server_tags['02-BBCDEFG123457']['applications'].has_key?('master').should be_false - end end diff --git a/test/integration/application/serverspec/spec_helper.rb b/test/integration/application/serverspec/spec_helper.rb index d89b194..c3f4476 100644 --- a/test/integration/application/serverspec/spec_helper.rb +++ b/test/integration/application/serverspec/spec_helper.rb @@ -6,6 +6,8 @@ include Serverspec::Helper::Exec include Serverspec::Helper::DetectOS +# server_spec requires Gems to be installed in a specific path so the following is needed to make machine_tag +# available for testing installer = Gem::DependencyInstaller.new installer.install('machine_tag') Gem.clear_paths diff --git a/test/integration/database/serverspec/server_spec.rb b/test/integration/database/serverspec/server_spec.rb index 8589a86..6522ee0 100644 --- a/test/integration/database/serverspec/server_spec.rb +++ b/test/integration/database/serverspec/server_spec.rb @@ -1,30 +1,23 @@ # Test:: database server require 'spec_helper' - -# Get the hostname -host_name = `hostname -s`.chomp - -db_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) +require 'socket' describe "Database server tags" do - it "should have a UUID of 03-CBCDEFG123458" do - db_tags['server:uuid'].first.value.should match ('03-CBCDEFG123458') - end - it "should have a public of 33.33.33.12" do - db_tags['server:public_ip_0'].first.value.should match ('33.33.33.12') - end - it "should have a private IP of 10.0.2.17" do - db_tags['server:private_ip_0'].first.value.should match ('10.0.2.17') - end + let(:host_name) { Socket.gethostname } + let(:db_tags) { MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) } + it "should have 5 application specific entries" do db_tags['database'].length.should == 5 end + it "should be active" do db_tags['database:active'].first.value.should be_true end + it "should have a lineage of production" do - db_tags['database:lineage'].first.value.should match ('production') + db_tags['database:lineage'].first.value.should eq ('production') end + #it "should have a master_active value of 1391473172" do # db_tags['database:master_active'].first.value.should match ('1391473172') #end @@ -32,24 +25,29 @@ # We use find_database_servers helper to find all the database severs, and we write results to a file. # Here we are loading the file so it can be parsed -db_server_tags = JSON.parse(IO.read("/tmp/found_db_servers.json")) - describe "Found database application servers" do + let(:db_server_tags) { JSON.parse(IO.read("/tmp/found_db_servers.json")) } + it "should have a UUID of 03-CBCDEFG123458" do db_server_tags.has_key?('03-CBCDEFG123458').should be_true end + it "should include a public IP address of 33.33.33.12" do - db_server_tags['03-CBCDEFG123458']['public_ips'].first.should match ('33.33.33.12') + db_server_tags['03-CBCDEFG123458']['public_ips'].first.should eq ('33.33.33.12') end + it "should include a private IP address of 10.0.2.17" do - db_server_tags['03-CBCDEFG123458']['private_ips'].first.should match ('10.0.2.17') + db_server_tags['03-CBCDEFG123458']['private_ips'].first.should eq ('10.0.2.17') end + it "should include a lineage of production" do - db_server_tags['03-CBCDEFG123458']['lineage'].should match ('production') + db_server_tags['03-CBCDEFG123458']['lineage'].should eq ('production') end + it "should have a role of master" do - db_server_tags['03-CBCDEFG123458']['role'].should match ('master') + db_server_tags['03-CBCDEFG123458']['role'].should eq ('master') end + #it "should have been a master since 2014-02-04 00:19:32 +0000" do # db_server_tags['03-CBCDEFG123458']['master_since'].should == '2014-02-04 00:19:32 +0000' #end diff --git a/test/integration/database/serverspec/spec_helper.rb b/test/integration/database/serverspec/spec_helper.rb index d89b194..c3f4476 100644 --- a/test/integration/database/serverspec/spec_helper.rb +++ b/test/integration/database/serverspec/spec_helper.rb @@ -6,6 +6,8 @@ include Serverspec::Helper::Exec include Serverspec::Helper::DetectOS +# server_spec requires Gems to be installed in a specific path so the following is needed to make machine_tag +# available for testing installer = Gem::DependencyInstaller.new installer.install('machine_tag') Gem.clear_paths diff --git a/test/integration/default/serverspec/server_spec.rb b/test/integration/default/serverspec/server_spec.rb index 557817b..1fb115d 100644 --- a/test/integration/default/serverspec/server_spec.rb +++ b/test/integration/default/serverspec/server_spec.rb @@ -1,30 +1,35 @@ # Test:: default server require 'spec_helper' - -#Get the hostname -host_name = `hostname -s`.chomp - -default_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) +require 'socket' describe "Default server tags" do + let(:host_name) { Socket.gethostname } + let(:default_tags) { MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) } + it "should have a UUID of 01-ABCDEFG123456" do - default_tags['server:uuid'].first.value.should match ('01-ABCDEFG123456') + default_tags['server:uuid'].first.value.should eq ('01-ABCDEFG123456') end - it "should have a public IP of" do - default_tags['server:public_ip_0'].first.value.should match ('33.33.33.10') + + it "should have a public IP of 33.33.33.10" do + default_tags['server:public_ip_0'].first.value.should eq ('33.33.33.10') end - it "should have a private IP of" do - default_tags['server:private_ip_0'].first.value.should match ('10.0.2.15') + + it "should have a private IP of 10.0.2.15" do + default_tags['server:private_ip_0'].first.value.should eq ('10.0.2.15') end + it "should have an Active monitoring state" do - default_tags['rs_monitoring:state'].first.value.should match ('active') + default_tags['rs_monitoring:state'].first.value.should eq ('active') end + it "should have NOT have any Application tags" do default_tags['application'].should be_empty end + it "should have NOT have any Database tags" do default_tags['database'].should be_empty end + it "should have NOT have any Load Balancer tags" do default_tags['load_balancer'].should be_empty end diff --git a/test/integration/default/serverspec/spec_helper.rb b/test/integration/default/serverspec/spec_helper.rb index d89b194..c3f4476 100644 --- a/test/integration/default/serverspec/spec_helper.rb +++ b/test/integration/default/serverspec/spec_helper.rb @@ -6,6 +6,8 @@ include Serverspec::Helper::Exec include Serverspec::Helper::DetectOS +# server_spec requires Gems to be installed in a specific path so the following is needed to make machine_tag +# available for testing installer = Gem::DependencyInstaller.new installer.install('machine_tag') Gem.clear_paths diff --git a/test/integration/load_balancer/serverspec/server_spec.rb b/test/integration/load_balancer/serverspec/server_spec.rb index 6c36c33..d27e1ee 100644 --- a/test/integration/load_balancer/serverspec/server_spec.rb +++ b/test/integration/load_balancer/serverspec/server_spec.rb @@ -1,24 +1,15 @@ # Test:: load_balancer server require 'spec_helper' - -# Get the hostname -host_name = `hostname -s`.chomp - -lb_tags = MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) +require 'socket' describe "Load balancer server tags" do - it "should have a UUID of 04-DBCDEFG123459" do - lb_tags['server:uuid'].first.value.should match ('04-DBCDEFG123459') - end - it "should have a public IP of 33.33.33.11" do - lb_tags['server:public_ip_0'].first.value.should match ('33.33.33.11') - end - it "should have a private IP of 10.0.2.16" do - lb_tags['server:private_ip_0'].first.value.should match ('10.0.2.16') - end + let(:host_name) { Socket.gethostname } + let(:lb_tags) { MachineTag::Set.new(JSON.parse(IO.read("/vagrant/cache_dir/machine_tag_cache/#{host_name}/tags.json"))) } + it "should have 2 application specific entry" do lb_tags['load_balancer'].length.should == 2 end + it "should be active" do lb_tags['load_balancer:active'].should be_true lb_tags['load_balancer:active_api'].should be_true @@ -27,19 +18,22 @@ # We use find_load_balancer_servers helper to find all the load balancers with name api, and we write results to a file. # Here we are loading the file so it can be parsed -lb_server_tags = JSON.parse(IO.read("/tmp/found_lb_servers.json")) - describe "Found load balancer server" do + let(:lb_server_tags) { JSON.parse(IO.read("/tmp/found_lb_servers.json")) } + it "should have a UUID of 04-DBCDEFG123459" do lb_server_tags.has_key?('04-DBCDEFG123459').should be_true end + it "should have a public IP address of 33.33.33.11" do - lb_server_tags['04-DBCDEFG123459']['public_ips'].first.should match ('33.33.33.11') + lb_server_tags['04-DBCDEFG123459']['public_ips'].first.should eq ('33.33.33.11') end + it "should have a private IP address of 10.0.2.16" do - lb_server_tags['04-DBCDEFG123459']['private_ips'].first.should match ('10.0.2.16') + lb_server_tags['04-DBCDEFG123459']['private_ips'].first.should eq ('10.0.2.16') end + it "should have an application name of api" do - lb_server_tags['04-DBCDEFG123459']['application_names'].first.should match ('api') + lb_server_tags['04-DBCDEFG123459']['application_names'].first.should eq ('api') end end diff --git a/test/integration/load_balancer/serverspec/spec_helper.rb b/test/integration/load_balancer/serverspec/spec_helper.rb index d89b194..c3f4476 100644 --- a/test/integration/load_balancer/serverspec/spec_helper.rb +++ b/test/integration/load_balancer/serverspec/spec_helper.rb @@ -6,6 +6,8 @@ include Serverspec::Helper::Exec include Serverspec::Helper::DetectOS +# server_spec requires Gems to be installed in a specific path so the following is needed to make machine_tag +# available for testing installer = Gem::DependencyInstaller.new installer.install('machine_tag') Gem.clear_paths From ecc98a0a8972926315c60e455481d50fb18f14d8 Mon Sep 17 00:00:00 2001 From: david-vo Date: Wed, 19 Feb 2014 17:37:44 -0800 Subject: [PATCH 43/54] Add tests for timestamps for database --- .../database/serverspec/server_spec.rb | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/test/integration/database/serverspec/server_spec.rb b/test/integration/database/serverspec/server_spec.rb index 6522ee0..1e02ee0 100644 --- a/test/integration/database/serverspec/server_spec.rb +++ b/test/integration/database/serverspec/server_spec.rb @@ -1,6 +1,7 @@ # Test:: database server require 'spec_helper' require 'socket' +require 'time' describe "Database server tags" do let(:host_name) { Socket.gethostname } @@ -18,9 +19,12 @@ db_tags['database:lineage'].first.value.should eq ('production') end - #it "should have a master_active value of 1391473172" do - # db_tags['database:master_active'].first.value.should match ('1391473172') - #end + # We want to test that the master_active timestamp is a reasonable value; arbitrarily within the last 24 hours + let(:db_time) { Time.at(db_tags['database:master_active'].first.value.to_i) } + + it "should have a master_active value that is valid (within the last 24 hours)" do + (Time.now - db_time).should < 86400 + end end # We use find_database_servers helper to find all the database severs, and we write results to a file. @@ -48,7 +52,10 @@ db_server_tags['03-CBCDEFG123458']['role'].should eq ('master') end - #it "should have been a master since 2014-02-04 00:19:32 +0000" do - # db_server_tags['03-CBCDEFG123458']['master_since'].should == '2014-02-04 00:19:32 +0000' - #end + # We want to test that the master_active timestamp is a reasonable value; arbitrarily within the last 24 hours + let(:time_from_tags) { Time.parse(db_server_tags['03-CBCDEFG123458']['master_since']).to_i} + + it "should have a master_since timestamp that is valid (within the last 24 hours)" do + (Time.now.utc.to_i - time_from_tags).should < 86400 + end end From 9d95126b92b395c08d92348ddbd07b10baf624b0 Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Thu, 20 Feb 2014 13:25:21 +0530 Subject: [PATCH 44/54] Various code review changes. --- README.md | 21 +++--- Strainerfile | 2 +- libraries/rightscale_tag_helper.rb | 24 +++++-- metadata.rb | 2 +- spec/unit_test/rightscale_tag_helper_spec.rb | 69 +++++++++++++------- 5 files changed, 80 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 9a099d2..c9ba75a 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Github Repository: [https://github.com/rightscale-cookbooks/rightscale_tag](http # Requirements * Requires Chef 11 or higher +* Requires Ruby 1.9 or higher * Platform * Ubuntu 12.04 * CentOS 6.4 @@ -28,16 +29,16 @@ Github Repository: [https://github.com/rightscale-cookbooks/rightscale_tag](http * [machine_tag] * [marker] -[machine_tag]: https://github.com/rightscale-cookbooks/machine_tag -[marker]: https://github.com/rightscale-cookbooks/marker +[machine_tag]: http://community.opscode.com/cookbooks/machine_tag +[marker]: http://community.opscode.com/cookbooks/marker # Usage On a RightScale server, add `rightscale_tag::default` to the run list. This will use the `node['rightscale']['instance_uuid']` attribute to create the `server:uuid` tag and the `node['cloud']['public_ips']` and -`node['cloud']['private_ips']`values that come from the Ohai cloud plugin to -pupulate the `server:public_ip_X` and `server:private_ip_X` tags (where `X` is +`node['cloud']['private_ips']` values that come from the Ohai cloud plugin to +pupulate the `server:public_ip_X` and `server:private_ip_X` tags (where `X` is 0, 1, etc.). The `rightscale_tag::monitoring` recipe should be placed in the run list after a @@ -65,7 +66,7 @@ implementation of a 3-tier LAMP stack using this cookbook, please see the The tags used for load balancer servers are as follows: -* **`load_balancer:active=true`** - specifies that that the load balancer server +* **`load_balancer:active=true`** - specifies that the load balancer server is active * **`load_balancer:active_=true`** - specifies an application that the load balancer server serves; examples: @@ -172,7 +173,7 @@ end ``` The [`find_application_servers`] method can be used to find tagged application -servers. For example, to find application servers for the `www`application in a +servers. For example, to find application servers for the `www` application in a Chef recipe: ```ruby @@ -521,7 +522,7 @@ def find_load_balancer_servers(node, application_name = nil, options = {}) options[:query_timeout] - the seconds to timeout for the query operation; the default is `120` + the seconds to timeout for the query operation; the default is 120 Integer @@ -561,7 +562,7 @@ def find_application_servers(node, application_name = nil, options = {}) options[:query_timeout] - the seconds to timeout for the query operation; the default is `120` + the seconds to timeout for the query operation; the default is 120 Integer @@ -606,12 +607,12 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) options[:only_latest_for_role] - only return the latest server tagged for a role; the default is `false` + only return the latest server tagged for a role; the default is false Boolean options[:query_timeout] - the seconds to timeout for the query operation; the default is `120` + the seconds to timeout for the query operation; the default is 120 Integer diff --git a/Strainerfile b/Strainerfile index 54b8e34..a5b1737 100644 --- a/Strainerfile +++ b/Strainerfile @@ -1,4 +1,4 @@ knife: bundle exec knife cookbook test $COOKBOOK foodcritic: bundle exec foodcritic --epic-fail any $SANDBOX/$COOKBOOK rspec: bundle exec rspec --color --format documentation -kitchen: bundle exec kitchen test +kitchen: bundle exec kitchen test --parallel diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index efffd4d..2b9c429 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -60,6 +60,9 @@ def self.find_load_balancer_servers(node, application_name = nil, options = {}) query_tag = ::MachineTag::Tag.machine_tag('load_balancer', 'active', true) end + # Performs a tag search for load balancer servers with given attributes. + # See https://github.com/rightscale-cookbooks/machine_tag#tag_searchnode-query-options-- for more information + # about this helper method. servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) unless application_name @@ -68,6 +71,7 @@ def self.find_load_balancer_servers(node, application_name = nil, options = {}) end end + # Builds a Hash with server information obtained from each server from their tags. build_server_hash(servers) do |tags| application_names = tags[/^load_balancer:active_.+$/].map do |tag| next if tag.value != 'true' @@ -151,6 +155,9 @@ def self.find_application_servers(node, application_name = nil, options = {}) query_tag = ::MachineTag::Tag.machine_tag('application', 'active', true) end + # Performs a tag search for application servers with given attributes. + # See https://github.com/rightscale-cookbooks/machine_tag#tag_searchnode-query-options-- for more information + # about this helper method. servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) unless application_name @@ -159,6 +166,7 @@ def self.find_application_servers(node, application_name = nil, options = {}) end end + # Builds a Hash with server information obtained from each server from their tags. build_server_hash(servers) do |tags| application_hashes = tags[/^application:active_.+$/].map do |tag| next if tag.value != 'true' @@ -169,7 +177,7 @@ def self.find_application_servers(node, application_name = nil, options = {}) bind_port = tags['application', "bind_port_#{application_name}"].first vhost_path = tags['application', "vhost_path_#{application_name}"].first - application_hash['bind_ip_address'] = bind_ip_address.value if bind_ip_address + application_hash['bind_ip_address'] = bind_ip_address.value if bind_ip_address application_hash['bind_port'] = bind_port.value.to_i if bind_port application_hash['vhost_path'] = vhost_path.value if vhost_path @@ -275,6 +283,9 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) ::MachineTag::Tag.machine_tag('database', 'bind_port', '*') ) + # Performs a tag search for database servers with given attributes. + # See https://github.com/rightscale-cookbooks/machine_tag#tag_searchnode-query-options-- for more information + # about this helper method. servers = Chef::MachineTagHelper.tag_search(node, query_tag, options) if lineage @@ -283,6 +294,7 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) end end + # Builds a Hash with server information obtained from each server from their tags. server_hashes = build_server_hash(servers) do |tags| server_hash = { 'lineage' => tags['database:lineage'].first.value, @@ -292,6 +304,7 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) master_active = tags['database:master_active'].first slave_active = tags['database:slave_active'].first + # If a server is identified as both master and slave, pick the most recent role. if master_active && slave_active master_since = Time.at(master_active.value.to_i) slave_since = Time.at(slave_active.value.to_i) @@ -314,17 +327,20 @@ def self.find_database_servers(node, lineage = nil, role = nil, options = {}) server_hash end + # If `only_latest_for_role` option is set to true, find the latest active server for the given role if more than + # one servers are found. + # if only_latest_for_role - server_hashes = server_hashes.sort_by {|_, server_hash| server_hash['lineage']}.chunk do |_, server_hash| + server_hashes = server_hashes.sort_by { |_, server_hash| server_hash['lineage'] }.chunk do |_, server_hash| server_hash['lineage'] end.map do |lineage, server_hashes| - server_hashes.sort_by {|_, server_hash| server_hash['role'] || ''}.chunk do |_, server_hash| + server_hashes.sort_by { |_, server_hash| server_hash['role'] || '' }.chunk do |_, server_hash| server_hash['role'] || '' end.map do |role, server_hashes| if role.empty? server_hashes else - [server_hashes.max_by {|uuid, server_hash| server_hash["#{role}_since"]}] + [server_hashes.max_by { |uuid, server_hash| server_hash["#{role}_since"] }] end end end diff --git a/metadata.rb b/metadata.rb index d3305e4..19df96a 100644 --- a/metadata.rb +++ b/metadata.rb @@ -2,7 +2,7 @@ maintainer 'RightScale, Inc.' maintainer_email 'cookbooks@rightscale.com' license 'Apache 2.0' -description 'Installs/Configures rightscale_tag' +description 'Provides LWRPs and helper methods for building 3-tier applications using machine tags in RightScale' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '1.0.0' diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 4fa9470..0457343 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -66,7 +66,9 @@ class Fake; end it 'returns tags from all load balancer servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'load_balancer:active=true', {:required_tags => Set['server:uuid']} + node, + 'load_balancer:active=true', + {:required_tags => Set['server:uuid']} ).and_return(tags) response = fake.find_load_balancer_servers(node) @@ -91,7 +93,9 @@ class Fake; end it 'returns tags from the matching load balancer server' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'load_balancer:active_www=true', {:required_tags => Set['server:uuid']} + node, + 'load_balancer:active_www=true', + {:required_tags => Set['server:uuid']} ).and_return(tags) response = fake.find_load_balancer_servers(node, 'www') @@ -108,7 +112,9 @@ class Fake; end it 'returns an empty Mash' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'load_balancer:active_www=true', {:required_tags => Set['server:uuid']} + node, + 'load_balancer:active_www=true', + {:required_tags => Set['server:uuid']} ).and_return(tags) response = fake.find_load_balancer_servers(node, 'www') @@ -181,7 +187,8 @@ class Fake; end it 'returns tags of all application servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'application:active=true', + node, + 'application:active=true', {:required_tags => Set['server:uuid']} ).and_return(tags) response = fake.find_application_servers(node) @@ -209,7 +216,8 @@ class Fake; end it 'returns tags of matching application servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'application:active_www=true', + node, + 'application:active_www=true', {:required_tags => Set[ 'server:uuid', 'application:bind_ip_address_www=*', @@ -240,7 +248,8 @@ class Fake; end it 'returns an empty Mash' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'application:active_www=true', + node, + 'application:active_www=true', {:required_tags => Set[ 'server:uuid', 'application:bind_ip_address_www=*', @@ -327,7 +336,8 @@ class Fake; end it 'returns tags of all database servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:active=true', + node, + 'database:active=true', {:required_tags => Set[ 'server:uuid', 'database:lineage=*', @@ -375,7 +385,8 @@ class Fake; end it 'returns only the latest masters and slaves and any standalones' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:active=true', + node, + 'database:active=true', {:required_tags => Set[ 'server:uuid', 'database:lineage=*', @@ -408,7 +419,8 @@ class Fake; end it 'returns role of the latest tag' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:active=true', + node, + 'database:active=true', {:required_tags => Set[ 'server:uuid', 'database:lineage=*', @@ -437,7 +449,8 @@ class Fake; end it 'returns tags of all database servers' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:active=true', + node, + 'database:active=true', {:required_tags => Set[ 'server:uuid', 'database:lineage=*', @@ -480,7 +493,8 @@ class Fake; end it 'returns an empty Mash when the lineage is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:active=true', + node, + 'database:active=true', {:required_tags => Set[ 'server:uuid', 'database:lineage=*', @@ -501,7 +515,8 @@ class Fake; end it 'returns only the latest masters and slaves and any standalones' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:active=true', + node, + 'database:active=true', {:required_tags => Set[ 'server:uuid', 'database:lineage=*', @@ -522,7 +537,8 @@ class Fake; end context 'when the database role is given and the lineage is not given' do it 'returns tags of the master database server' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:master_active=*', + node, + 'database:master_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -545,7 +561,8 @@ class Fake; end it 'returns tags of the slave database server' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:slave_active=*', + node, + 'database:slave_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -568,7 +585,8 @@ class Fake; end it 'returns an empty Mash when the role is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:undefined_active=*', + node, + 'database:undefined_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -590,7 +608,8 @@ class Fake; end it 'returns only the latest master' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:master_active=*', + node, + 'database:master_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -610,7 +629,8 @@ class Fake; end context 'when the database role and lineage is given' do it 'returns tags of the master database server matching example as lineage' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:master_active=*', + node, + 'database:master_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -633,7 +653,8 @@ class Fake; end it 'returns tags of the slave database server matching example as lineage' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:slave_active=*', + node, + 'database:slave_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -656,7 +677,8 @@ class Fake; end it 'returns an empty Mash when the role is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:undefined_active=*', + node, + 'database:undefined_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -673,7 +695,8 @@ class Fake; end it 'returns an empty Mash when the lineage is not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:master_active=*', + node, + 'database:master_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -690,7 +713,8 @@ class Fake; end it 'returns an empty Mash when both role and lineage are not available' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:undefined_active=*', + node, + 'database:undefined_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', @@ -712,7 +736,8 @@ class Fake; end it 'returns only the latest slave' do Chef::MachineTagHelper.should_receive(:tag_search).with( - node, 'database:slave_active=*', + node, + 'database:slave_active=*', {:required_tags => Set[ 'server:uuid', 'database:active=true', From d15c2c4ef1550962e90667f4dd41259ca4fb82bb Mon Sep 17 00:00:00 2001 From: david-vo Date: Thu, 20 Feb 2014 13:11:42 -0800 Subject: [PATCH 45/54] Iteration on code review --- test/cookbooks/fake/recipes/app_server.rb | 2 -- test/cookbooks/fake/recipes/default.rb | 2 -- test/cookbooks/fake/recipes/lb_server.rb | 2 -- 3 files changed, 6 deletions(-) diff --git a/test/cookbooks/fake/recipes/app_server.rb b/test/cookbooks/fake/recipes/app_server.rb index 71d03dd..c080e1a 100644 --- a/test/cookbooks/fake/recipes/app_server.rb +++ b/test/cookbooks/fake/recipes/app_server.rb @@ -17,8 +17,6 @@ # limitations under the License. # -delete = false - rightscale_tag_application 'www' do bind_ip_address '10.0.0.1' bind_port 8080 diff --git a/test/cookbooks/fake/recipes/default.rb b/test/cookbooks/fake/recipes/default.rb index 907a56d..c601647 100644 --- a/test/cookbooks/fake/recipes/default.rb +++ b/test/cookbooks/fake/recipes/default.rb @@ -17,8 +17,6 @@ # limitations under the License. # -delete = false - marker "recipe_start_rightscale" do template "rightscale_audit_entry.erb" end diff --git a/test/cookbooks/fake/recipes/lb_server.rb b/test/cookbooks/fake/recipes/lb_server.rb index ca6469b..e75e7b9 100644 --- a/test/cookbooks/fake/recipes/lb_server.rb +++ b/test/cookbooks/fake/recipes/lb_server.rb @@ -17,8 +17,6 @@ # limitations under the License. # -delete = false - # Load balancer setup. We are only using api and not both api and www so the latter doesn't pollute the tag data rightscale_tag_load_balancer 'api server' do application_name 'api' From 8cd126b4dc92d791ddd897a3c6df7062f2277905 Mon Sep 17 00:00:00 2001 From: Nitin Mohan Date: Thu, 20 Feb 2014 15:26:29 -0800 Subject: [PATCH 46/54] Add group_servers_by_application_name helper method --- libraries/rightscale_tag_helper.rb | 69 ++++++++++++++ spec/unit_test/rightscale_tag_helper_spec.rb | 94 ++++++++++++++++++++ 2 files changed, 163 insertions(+) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 2b9c429..59496fe 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -370,6 +370,75 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) Rightscale::RightscaleTag.find_database_servers(node, lineage, role, options) end + # Groups the application servers hash returned by find_application_servers + # method based on application names. + # + # @param servers [Hash{String, Hash}] the application servers hash + # + # @return [Hash] the pools hash with pool name as the key and the server hash + # as value + # + # @example + # + # # Given the application servers hash as below + # + # { + # '01-ABCDEF7890123' => { + # 'applications' => { + # 'www' => { + # 'bind_ip_address' => '10.0.0.3', + # 'bind_port' => 8080, + # 'vhost_path' => '/', + # } + # }, + # 'public_ips' => ['203.0.113.3'], + # 'private_ips' => ['10.0.0.3'] + # }, + # '01-EDFHG9876DFG' => { + # 'applications' => { + # 'api' => { + # 'bind_ip_address' => '10.0.0.3', + # 'bind_port' => 8080, + # 'vhost_path' => '/', + # } + # }, + # 'public_ips' => ['8.0.13.3'], + # 'private_ips' => ['10.0.0.3'] + # } + # } + # + # # This method returns + # + # { + # 'www' => { + # '01-ABCDEF7890123' => { + # 'bind_ip_address' => '10.0.0.3', + # 'bind_port' => 8080, + # 'vhost_path' => '/', + # } + # } + # 'api' => { + # { + # '01-EDFHG9876DFG' => { + # 'bind_ip_address' => '10.0.0.3', + # 'bind_port' => 8080, + # 'vhost_path' => '/', + # } + # } + # ] + # } + # + def self.group_servers_by_application_name(servers) + pools_hash = {} + servers.each do |server_uuid, server_hash| + server_hash['applications'].each do |app_name, app_hash| + pools_hash[app_name] ||= {} + pools_hash[app_name][server_uuid] = app_hash + end + end + pools_hash + end + private # Adds required tags to the options for Chef::MachineTagHelper#tag_search that are needed for the various diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 0457343..72f6609 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -754,4 +754,98 @@ class Fake; end end end end + + describe '.group_servers_by_application_name' do + let(:application_server_1) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8911IT', + 'application:active=true', + 'application:active_www=true', + 'application:active_api=true', + 'application:bind_ip_address_www=157.56.165.202', + 'application:bind_ip_address_api=157.56.165.203', + 'application:bind_port_www=80', + 'application:bind_port_api=80', + 'application:vhost_path_www=/', + 'application:vhost_path_api=api.example.com', + 'server:public_ip_0=157.56.165.202', + 'server:public_ip_1=157.56.165.203', + 'server:private_ip_0=10.0.0.1', + ] + end + + let(:application_server_2) do + MachineTag::Set[ + 'server:uuid=01-83PJQDO8922IT', + 'application:active=true', + 'application:active_api=true', + 'application:bind_ip_address_api=157.56.166.202', + 'application:bind_port_api=443', + 'application:vhost_path_api=api.example.com', + 'server:public_ip_0=157.56.166.202', + 'server:public_ip_1=157.56.166.203', + ] + end + + let(:www_attributes_1) do + Mash.from_hash( + 'bind_ip_address' => '157.56.165.202', + 'bind_port' => 80, + 'vhost_path' => '/' + ) + end + + let(:api_attributes_1) do + Mash.from_hash( + 'bind_ip_address' => '157.56.165.203', + 'bind_port' => 80, + 'vhost_path' => 'api.example.com' + ) + end + + let(:api_attributes_2) do + Mash.from_hash( + 'bind_ip_address' => '157.56.166.202', + 'bind_port' => 443, + 'vhost_path' => 'api.example.com' + ) + end + + context 'when application servers exist' do + let(:tags) do + [application_server_1, application_server_2] + end + + it 'groups application servers by application name' do + Chef::MachineTagHelper.should_receive(:tag_search).with( + node, 'application:active=true', + {:required_tags => Set['server:uuid']} + ).and_return(tags) + servers = fake.find_application_servers(node) + response = Rightscale::RightscaleTag::group_servers_by_application_name(servers) + + response.should be_kind_of(Hash) + + response.should include('www') + response['www'].should include('01-83PJQDO8911IT') + response['www']['01-83PJQDO8911IT'].should eq(www_attributes_1) + + response.should include('api') + response['api'].should include('01-83PJQDO8922IT') + response['api']['01-83PJQDO8922IT'].should eq(api_attributes_2) + + response['api'].should include('01-83PJQDO8911IT') + response['api']['01-83PJQDO8911IT'].should eq(api_attributes_1) + end + end + end + + context 'when no application servers exists' do + it 'should return an empty Hash' do + response = Rightscale::RightscaleTag::group_servers_by_application_name(Mash.new) + + response.should be_kind_of(Hash) + response.should be_empty + end + end end From 5d50b5d457d3444572cf9712c0a6fb54afe34609 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Thu, 20 Feb 2014 16:57:46 -0800 Subject: [PATCH 47/54] Simplify providers. --- providers/application.rb | 42 ++++++++++++++++++-------------------- providers/database.rb | 42 +++++++++++++++++--------------------- providers/load_balancer.rb | 21 +++++++------------ 3 files changed, 46 insertions(+), 59 deletions(-) diff --git a/providers/application.rb b/providers/application.rb index 2e4d681..e2a061e 100644 --- a/providers/application.rb +++ b/providers/application.rb @@ -19,34 +19,32 @@ # The create action that creates required tags for an application server action :create do - require 'machine_tag' + machine_tag 'application:active=true' + machine_tag "application:active_#{new_resource.application_name}=true" + machine_tag "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}" + machine_tag "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}" + machine_tag "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" - [ - ::MachineTag::Tag.machine_tag('application', "active", true), - ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), - ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), - ::MachineTag::Tag.machine_tag('application', "bind_port_#{new_resource.application_name}", new_resource.bind_port), - ::MachineTag::Tag.machine_tag('application', "vhost_path_#{new_resource.application_name}", new_resource.vhost_path) - ].each do |tag| - machine_tag tag - end new_resource.updated_by_last_action(true) end # The delete action that removes the application specific tags from the server action :delete do - require 'machine_tag' - - [ - ::MachineTag::Tag.machine_tag('application', "active", true), - ::MachineTag::Tag.machine_tag('application', "active_#{new_resource.application_name}", true), - ::MachineTag::Tag.machine_tag('application', "bind_ip_address_#{new_resource.application_name}", new_resource.bind_ip_address), - ::MachineTag::Tag.machine_tag('application', "bind_port_#{new_resource.application_name}", new_resource.bind_port), - ::MachineTag::Tag.machine_tag('application', "vhost_path_#{new_resource.application_name}", new_resource.vhost_path) - ].each do |tag| - machine_tag tag do - action :delete - end + machine_tag 'application:active=true' do + action :delete + end + machine_tag "application:active_#{new_resource.application_name}=true" do + action :delete + end + machine_tag "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}" do + action :delete end + machine_tag "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}" do + action :delete + end + machine_tag "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" do + action :delete + end + new_resource.updated_by_last_action(true) end diff --git a/providers/database.rb b/providers/database.rb index 9b206cb..56a9e88 100644 --- a/providers/database.rb +++ b/providers/database.rb @@ -19,14 +19,11 @@ # The create action that creates required tags for a database server action :create do - require 'machine_tag' + machine_tag 'database:active=true' + machine_tag "database:lineage=#{new_resource.lineage}" + machine_tag "database:bind_ip_address=#{new_resource.bind_ip_address}" + machine_tag "database:bind_port=#{new_resource.bind_port}" - database_tags = [ - ::MachineTag::Tag.machine_tag('database', 'active', true), - ::MachineTag::Tag.machine_tag('database', 'lineage', new_resource.lineage), - ::MachineTag::Tag.machine_tag('database', 'bind_ip_address', new_resource.bind_ip_address), - ::MachineTag::Tag.machine_tag('database', 'bind_port', new_resource.bind_port), - ] if new_resource.role timestamp_file = "/var/lib/rightscale/rightscale_tag_database_#{new_resource.role}_active.timestamp" if ::File.exists?(timestamp_file) @@ -44,25 +41,27 @@ content timestamp.to_i.to_s end - database_tags << "database:#{new_resource.role}_active=#{timestamp.to_i}" + machine_tag "database:#{new_resource.role}_active=#{timestamp.to_i}" end - database_tags.each do |tag| - machine_tag tag - end new_resource.updated_by_last_action(true) end # The delete action that removes the database specific tags from the server action :delete do - require 'machine_tag' + machine_tag 'database:active=true' do + action :delete + end + machine_tag "database:lineage=#{new_resource.lineage}" do + action :delete + end + machine_tag "database:bind_ip_address=#{new_resource.bind_ip_address}" do + action :delete + end + machine_tag "database:bind_port=#{new_resource.bind_port}" do + action :delete + end - database_tags = [ - ::MachineTag::Tag.machine_tag('database', 'active', true), - ::MachineTag::Tag.machine_tag('database', 'lineage', new_resource.lineage), - ::MachineTag::Tag.machine_tag('database', 'bind_ip_address', new_resource.bind_ip_address), - ::MachineTag::Tag.machine_tag('database', 'bind_port', new_resource.bind_port), - ] if new_resource.role timestamp_file = "/var/lib/rightscale/rightscale_tag_database_#{new_resource.role}_active.timestamp" if ::File.exists?(timestamp_file) @@ -75,13 +74,10 @@ action :delete end - database_tags << "database:#{new_resource.role}_active=#{timestamp.to_i}" - end - - database_tags.each do |tag| - machine_tag tag do + machine_tag "database:#{new_resource.role}_active=#{timestamp.to_i}" do action :delete end end + new_resource.updated_by_last_action(true) end diff --git a/providers/load_balancer.rb b/providers/load_balancer.rb index ea183e3..da194de 100644 --- a/providers/load_balancer.rb +++ b/providers/load_balancer.rb @@ -19,27 +19,20 @@ # The create action that creates required tags for a load balancer server action :create do - require 'machine_tag' + machine_tag 'load_balancer:active=true' + machine_tag "load_balancer:active_#{new_resource.application_name}=true" - [ - ::MachineTag::Tag.machine_tag('load_balancer', "active", true), - ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) - ].each do |tag| - machine_tag tag - end new_resource.updated_by_last_action(true) end # The delete action that removes the load balancer specific tags from the server action :delete do - require 'machine_tag' - - [ - ::MachineTag::Tag.machine_tag('load_balancer', "active", true), - ::MachineTag::Tag.machine_tag('load_balancer', "active_#{new_resource.application_name}", true) - ].each do |tag| - machine_tag tag + machine_tag "load_balancer:active=true" do action :delete end + machine_tag "load_balancer:active_#{new_resource.application_name}=true" do + action :delete + end + new_resource.updated_by_last_action(true) end From 9d4cf600cdd90d2f97f558c85b671868f35501a4 Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Thu, 20 Feb 2014 18:09:14 -0800 Subject: [PATCH 48/54] Appease the food critic. --- providers/application.rb | 38 +++++++++++++++++++------------------- providers/database.rb | 32 +++++++++++++++++--------------- providers/load_balancer.rb | 20 +++++++++++++------- 3 files changed, 49 insertions(+), 41 deletions(-) diff --git a/providers/application.rb b/providers/application.rb index e2a061e..f18b018 100644 --- a/providers/application.rb +++ b/providers/application.rb @@ -19,31 +19,31 @@ # The create action that creates required tags for an application server action :create do - machine_tag 'application:active=true' - machine_tag "application:active_#{new_resource.application_name}=true" - machine_tag "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}" - machine_tag "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}" - machine_tag "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" + [ + 'application:active=true', + "application:active_#{new_resource.application_name}=true", + "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}", + "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}", + "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}", + ].each do |tag| + machine_tag tag + end new_resource.updated_by_last_action(true) end # The delete action that removes the application specific tags from the server action :delete do - machine_tag 'application:active=true' do - action :delete - end - machine_tag "application:active_#{new_resource.application_name}=true" do - action :delete - end - machine_tag "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}" do - action :delete - end - machine_tag "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}" do - action :delete - end - machine_tag "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}" do - action :delete + [ + 'application:active=true', + "application:active_#{new_resource.application_name}=true", + "application:bind_ip_address_#{new_resource.application_name}=#{new_resource.bind_ip_address}", + "application:bind_port_#{new_resource.application_name}=#{new_resource.bind_port}", + "application:vhost_path_#{new_resource.application_name}=#{new_resource.vhost_path}", + ].each do |tag| + machine_tag tag do + action :delete + end end new_resource.updated_by_last_action(true) diff --git a/providers/database.rb b/providers/database.rb index 56a9e88..8315c51 100644 --- a/providers/database.rb +++ b/providers/database.rb @@ -19,10 +19,14 @@ # The create action that creates required tags for a database server action :create do - machine_tag 'database:active=true' - machine_tag "database:lineage=#{new_resource.lineage}" - machine_tag "database:bind_ip_address=#{new_resource.bind_ip_address}" - machine_tag "database:bind_port=#{new_resource.bind_port}" + [ + 'database:active=true', + "database:lineage=#{new_resource.lineage}", + "database:bind_ip_address=#{new_resource.bind_ip_address}", + "database:bind_port=#{new_resource.bind_port}", + ].each do |tag| + machine_tag tag + end if new_resource.role timestamp_file = "/var/lib/rightscale/rightscale_tag_database_#{new_resource.role}_active.timestamp" @@ -49,17 +53,15 @@ # The delete action that removes the database specific tags from the server action :delete do - machine_tag 'database:active=true' do - action :delete - end - machine_tag "database:lineage=#{new_resource.lineage}" do - action :delete - end - machine_tag "database:bind_ip_address=#{new_resource.bind_ip_address}" do - action :delete - end - machine_tag "database:bind_port=#{new_resource.bind_port}" do - action :delete + [ + 'database:active=true', + "database:lineage=#{new_resource.lineage}", + "database:bind_ip_address=#{new_resource.bind_ip_address}", + "database:bind_port=#{new_resource.bind_port}", + ].each do |tag| + machine_tag tag do + action :delete + end end if new_resource.role diff --git a/providers/load_balancer.rb b/providers/load_balancer.rb index da194de..8ab31df 100644 --- a/providers/load_balancer.rb +++ b/providers/load_balancer.rb @@ -19,19 +19,25 @@ # The create action that creates required tags for a load balancer server action :create do - machine_tag 'load_balancer:active=true' - machine_tag "load_balancer:active_#{new_resource.application_name}=true" + [ + 'load_balancer:active=true', + "load_balancer:active_#{new_resource.application_name}=true", + ].each do |tag| + machine_tag tag + end new_resource.updated_by_last_action(true) end # The delete action that removes the load balancer specific tags from the server action :delete do - machine_tag "load_balancer:active=true" do - action :delete - end - machine_tag "load_balancer:active_#{new_resource.application_name}=true" do - action :delete + [ + 'load_balancer:active=true', + "load_balancer:active_#{new_resource.application_name}=true", + ].each do |tag| + machine_tag tag do + action :delete + end end new_resource.updated_by_last_action(true) From 34e3f146b76a623d05f78497b70b3579ff7ed03e Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Fri, 21 Feb 2014 10:55:58 +0530 Subject: [PATCH 49/54] Added instance method version of group_servers_by_application_name helper method. --- libraries/rightscale_tag_helper.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 59496fe..7330454 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -439,6 +439,20 @@ def self.group_servers_by_application_name(servers) pools_hash end + # Groups the application servers hash returned by find_application_servers + # method based on application names. + # + # @param servers [Hash{String, Hash}] the application servers hash + # + # @return [Hash] the pools hash with pool name as the key and the server hash + # as value + # + # @see .group_servers_by_application_name + # + def group_servers_by_application_name(servers) + Rightscale::RightscaleTag.group_servers_by_application_name(servers) + end + private # Adds required tags to the options for Chef::MachineTagHelper#tag_search that are needed for the various From 52579d582741affcc70c9bc8192bffae86c0b7cc Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Fri, 21 Feb 2014 12:17:58 +0530 Subject: [PATCH 50/54] Put back the IP attributes in .kitchen.yml. We didn't want to remove the IP attributes completely. There were some null and empty string attributes to test the robustness of the default recipe which were not required for all suites. --- .kitchen.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.kitchen.yml b/.kitchen.yml index 11378f9..0e633b8 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -43,6 +43,8 @@ suites: instance_uuid: 02-BBCDEFG123457 cloud: provider: vagrant + public_ips: ['33.33.33.10'] + private_ips: ['10.0.2.15'] # Database server tests - name: database @@ -54,6 +56,8 @@ suites: instance_uuid: 03-CBCDEFG123458 cloud: provider: vagrant + public_ips: ['33.33.33.12'] + private_ips: ['10.0.2.17'] # Load Balancer server tests - name: load_balancer @@ -65,3 +69,5 @@ suites: instance_uuid: 04-DBCDEFG123459 cloud: provider: vagrant + public_ips: ['33.33.33.11'] + private_ips: ['10.0.2.16'] From a870abc695189fec6943e5be95a77f035f004937 Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Fri, 21 Feb 2014 19:01:30 +0530 Subject: [PATCH 51/54] Modified `group_servers_by_application_name` to return a Mash. --- libraries/rightscale_tag_helper.rb | 10 +++++----- spec/unit_test/rightscale_tag_helper_spec.rb | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/rightscale_tag_helper.rb b/libraries/rightscale_tag_helper.rb index 7330454..68e50be 100644 --- a/libraries/rightscale_tag_helper.rb +++ b/libraries/rightscale_tag_helper.rb @@ -373,9 +373,9 @@ def find_database_servers(node, lineage = nil, role = nil, options = {}) # Groups the application servers hash returned by find_application_servers # method based on application names. # - # @param servers [Hash{String, Hash}] the application servers hash + # @param servers [Mash{String, Mash}] the application servers hash # - # @return [Hash] the pools hash with pool name as the key and the server hash + # @return [Mash] the pools hash with pool name as the key and the server hash # as value # # @example @@ -436,15 +436,15 @@ def self.group_servers_by_application_name(servers) pools_hash[app_name][server_uuid] = app_hash end end - pools_hash + Mash.from_hash(pools_hash) end # Groups the application servers hash returned by find_application_servers # method based on application names. # - # @param servers [Hash{String, Hash}] the application servers hash + # @param servers [Mash{String, Mash}] the application servers hash # - # @return [Hash] the pools hash with pool name as the key and the server hash + # @return [Mash] the pools hash with pool name as the key and the server hash # as value # # @see .group_servers_by_application_name diff --git a/spec/unit_test/rightscale_tag_helper_spec.rb b/spec/unit_test/rightscale_tag_helper_spec.rb index 72f6609..752f81d 100644 --- a/spec/unit_test/rightscale_tag_helper_spec.rb +++ b/spec/unit_test/rightscale_tag_helper_spec.rb @@ -824,7 +824,7 @@ class Fake; end servers = fake.find_application_servers(node) response = Rightscale::RightscaleTag::group_servers_by_application_name(servers) - response.should be_kind_of(Hash) + response.should be_kind_of(Mash) response.should include('www') response['www'].should include('01-83PJQDO8911IT') @@ -841,10 +841,10 @@ class Fake; end end context 'when no application servers exists' do - it 'should return an empty Hash' do + it 'should return an empty Mash' do response = Rightscale::RightscaleTag::group_servers_by_application_name(Mash.new) - response.should be_kind_of(Hash) + response.should be_kind_of(Mash) response.should be_empty end end From f4e8030eb2bd7789ed45d4da0fb0b52d7427d0cb Mon Sep 17 00:00:00 2001 From: Kannan Manickam Date: Fri, 21 Feb 2014 23:10:14 +0530 Subject: [PATCH 52/54] Removed fake::default as it is not used. --- test/cookbooks/fake/recipes/default.rb | 40 -------------------------- 1 file changed, 40 deletions(-) delete mode 100644 test/cookbooks/fake/recipes/default.rb diff --git a/test/cookbooks/fake/recipes/default.rb b/test/cookbooks/fake/recipes/default.rb deleted file mode 100644 index c601647..0000000 --- a/test/cookbooks/fake/recipes/default.rb +++ /dev/null @@ -1,40 +0,0 @@ -# -# Cookbook Name:: fake -# Recipe:: default -# -# Copyright (C) 2013 RightScale, Inc. -# -# 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. -# - -marker "recipe_start_rightscale" do - template "rightscale_audit_entry.erb" -end - -if node['rightscale'] && node['rightscale']['instance_uuid'] - machine_tag "server:uuid=#{node['rightscale']['instance_uuid']}" -end - -if node['cloud'] - if node['cloud']['public_ips'] - node['cloud']['public_ips'].reject { |ip| ip.nil? || ip.empty? }.each_with_index do |public_ip, index| - machine_tag "server:public_ip_#{index}=#{public_ip}" - end - end - - if node['cloud']['private_ips'] - node['cloud']['private_ips'].reject { |ip| ip.nil? || ip.empty? }.each_with_index do |private_ip, index| - machine_tag "server:private_ip_#{index}=#{private_ip}" - end - end -end From 0322d72ab960e19baf5147edd070af26a574032a Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 21 Feb 2014 11:25:54 -0800 Subject: [PATCH 53/54] Fix naming of test recipes. --- .kitchen.yml | 30 +++++++++---------- test/cookbooks/fake/metadata.rb | 6 ++-- .../recipes/{app_server.rb => application.rb} | 2 +- .../recipes/{db_server.rb => database.rb} | 2 +- .../{lb_server.rb => load_balancer.rb} | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) rename test/cookbooks/fake/recipes/{app_server.rb => application.rb} (97%) rename test/cookbooks/fake/recipes/{db_server.rb => database.rb} (98%) rename test/cookbooks/fake/recipes/{lb_server.rb => load_balancer.rb} (97%) diff --git a/.kitchen.yml b/.kitchen.yml index 0e633b8..57680cd 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -33,11 +33,24 @@ suites: - "" - 10.0.2.15 +# Load Balancer server tests +- name: load_balancer + run_list: + - recipe[rightscale_tag] + - recipe[fake::load_balancer] + attributes: + rightscale: + instance_uuid: 04-DBCDEFG123459 + cloud: + provider: vagrant + public_ips: ['33.33.33.11'] + private_ips: ['10.0.2.16'] + # Application server tests - name: application run_list: - recipe[rightscale_tag] - - recipe[fake::app_server] + - recipe[fake::application] attributes: rightscale: instance_uuid: 02-BBCDEFG123457 @@ -50,7 +63,7 @@ suites: - name: database run_list: - recipe[rightscale_tag] - - recipe[fake::db_server] + - recipe[fake::database] attributes: rightscale: instance_uuid: 03-CBCDEFG123458 @@ -58,16 +71,3 @@ suites: provider: vagrant public_ips: ['33.33.33.12'] private_ips: ['10.0.2.17'] - -# Load Balancer server tests -- name: load_balancer - run_list: - - recipe[rightscale_tag] - - recipe[fake::lb_server] - attributes: - rightscale: - instance_uuid: 04-DBCDEFG123459 - cloud: - provider: vagrant - public_ips: ['33.33.33.11'] - private_ips: ['10.0.2.16'] diff --git a/test/cookbooks/fake/metadata.rb b/test/cookbooks/fake/metadata.rb index ee32724..94cac01 100644 --- a/test/cookbooks/fake/metadata.rb +++ b/test/cookbooks/fake/metadata.rb @@ -7,6 +7,6 @@ depends 'rightscale_tag' -recipe 'fake::app_server', 'Prepares the test application server database' -recipe 'fake::db_server', 'Prepares the test database server database' -recipe 'fake::lb_server', 'Prepares the test load balancer server database' +recipe 'fake::load_balancer', 'Prepares the test load balancer server database' +recipe 'fake::application', 'Prepares the test application server database' +recipe 'fake::database', 'Prepares the test database server database' diff --git a/test/cookbooks/fake/recipes/app_server.rb b/test/cookbooks/fake/recipes/application.rb similarity index 97% rename from test/cookbooks/fake/recipes/app_server.rb rename to test/cookbooks/fake/recipes/application.rb index c080e1a..86e2e1d 100644 --- a/test/cookbooks/fake/recipes/app_server.rb +++ b/test/cookbooks/fake/recipes/application.rb @@ -1,6 +1,6 @@ # # Cookbook Name:: fake -# Recipe:: app_server +# Recipe:: application # # Copyright (C) 2013 RightScale, Inc. # diff --git a/test/cookbooks/fake/recipes/db_server.rb b/test/cookbooks/fake/recipes/database.rb similarity index 98% rename from test/cookbooks/fake/recipes/db_server.rb rename to test/cookbooks/fake/recipes/database.rb index 15e48bc..1dbf46f 100644 --- a/test/cookbooks/fake/recipes/db_server.rb +++ b/test/cookbooks/fake/recipes/database.rb @@ -1,6 +1,6 @@ # # Cookbook Name:: fake -# Recipe:: db_server +# Recipe:: database # # Copyright (C) 2013 RightScale, Inc. # diff --git a/test/cookbooks/fake/recipes/lb_server.rb b/test/cookbooks/fake/recipes/load_balancer.rb similarity index 97% rename from test/cookbooks/fake/recipes/lb_server.rb rename to test/cookbooks/fake/recipes/load_balancer.rb index e75e7b9..1773c46 100644 --- a/test/cookbooks/fake/recipes/lb_server.rb +++ b/test/cookbooks/fake/recipes/load_balancer.rb @@ -1,6 +1,6 @@ # # Cookbook Name:: fake -# Recipe:: lb_server +# Recipe:: load_balancer # # Copyright (C) 2013 RightScale, Inc. # From d814f7629084b9f82e8da438de39ef2ab6231bef Mon Sep 17 00:00:00 2001 From: Douglas Thrift Date: Fri, 21 Feb 2014 11:42:50 -0800 Subject: [PATCH 54/54] Remove extraneous `delete = false` from recipe. --- test/cookbooks/fake/recipes/database.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/cookbooks/fake/recipes/database.rb b/test/cookbooks/fake/recipes/database.rb index 1dbf46f..8e5e1bc 100644 --- a/test/cookbooks/fake/recipes/database.rb +++ b/test/cookbooks/fake/recipes/database.rb @@ -17,8 +17,6 @@ # limitations under the License. # -delete = false - # Database setup rightscale_tag_database 'production' do bind_ip_address '10.0.0.2'