knife-solo 0.3.0.pre2 → 0.3.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/CHANGELOG.md +70 -27
  2. data/README.rdoc +11 -6
  3. data/Rakefile +4 -2
  4. data/lib/chef/knife/bootstrap_solo.rb +40 -0
  5. data/lib/chef/knife/solo_bootstrap.rb +1 -1
  6. data/lib/chef/knife/solo_clean.rb +16 -4
  7. data/lib/chef/knife/solo_cook.rb +111 -36
  8. data/lib/chef/knife/solo_init.rb +14 -0
  9. data/lib/chef/knife/solo_prepare.rb +1 -1
  10. data/lib/knife-solo/bootstraps.rb +0 -18
  11. data/lib/knife-solo/bootstraps/darwin.rb +4 -16
  12. data/lib/knife-solo/bootstraps/linux.rb +36 -48
  13. data/lib/knife-solo/info.rb +1 -1
  14. data/lib/knife-solo/resources/knife.rb +4 -0
  15. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/.travis.yml +7 -0
  16. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/CHANGELOG +16 -0
  17. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/LICENSE +202 -0
  18. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/NOTICE +18 -0
  19. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/README.md +141 -0
  20. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/libraries/search.rb +72 -0
  21. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/libraries/search/overrides.rb +99 -0
  22. data/lib/{chef/knife/patches → knife-solo/resources/patch_cookbooks/chef-solo-search/libraries/search}/parser.rb +1 -2
  23. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene.treetop +150 -0
  24. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene_nodes.rb +285 -0
  25. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/query_transform.rb +65 -0
  26. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/metadata.rb +11 -0
  27. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/recipes/default.rb +2 -0
  28. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/Gemfile +8 -0
  29. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/data/data_bags/node/alpha.json +10 -0
  30. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/data/data_bags/node/beta.json +10 -0
  31. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/data/data_bags/node/without_json_class.json +7 -0
  32. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/data/data_bags/users/jerry.json +8 -0
  33. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/data/data_bags/users/lea.json +10 -0
  34. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/data/data_bags/users/mike.json +13 -0
  35. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/data/data_bags/users/tom.json +10 -0
  36. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/test_data_bags.rb +44 -0
  37. data/lib/knife-solo/resources/patch_cookbooks/chef-solo-search/tests/test_search.rb +241 -0
  38. data/lib/knife-solo/resources/solo.rb.erb +10 -0
  39. data/lib/knife-solo/ssh_command.rb +4 -3
  40. data/lib/knife-solo/tools.rb +22 -0
  41. data/test/bootstraps_test.rb +4 -11
  42. data/test/integration/cases/encrypted_data_bag.rb +3 -0
  43. data/test/integration/cases/knife_bootstrap.rb +14 -0
  44. data/test/integration/debian6_bootstrap_test.rb +1 -1
  45. data/test/integration/{debian7_bootstrap_test.rb → debian7_knife_bootstrap_test.rb} +3 -3
  46. data/test/knife_bootstrap_test.rb +61 -0
  47. data/test/solo_cook_test.rb +78 -3
  48. data/test/support/integration_test.rb +8 -3
  49. data/test/tools_test.rb +82 -0
  50. metadata +63 -21
  51. data/lib/chef/knife/patches/search.rb +0 -110
  52. data/lib/knife-solo/config.rb +0 -39
  53. data/lib/knife-solo/resources/solo.rb +0 -6
  54. data/test/knife-solo/config_test.rb +0 -38
@@ -0,0 +1,18 @@
1
+ ========================
2
+ chef-solo-search Notices
3
+ ========================
4
+
5
+ Developed at edelight GmbH (http://www.edelight-group.com/).
6
+
7
+ Contributors:
8
+
9
+ * Brian p o'rourke <bpo@somnambulance.net>
10
+ * Chris Roberts <chrisroberts.code@gmail.com>
11
+ * Jeff Wallace <jeff@tjwallace.ca>
12
+ * Miquel Torres <miquel.torres@edelight.de>
13
+ * Markus Korn <markus.korn@edelight.de>
14
+ * Matt Gleeson <matt@gleeson.org>
15
+ * Patrick Debois <Patrick.Debois@jedi.be>
16
+ * Patrick Wyatt <pat@codeofhonor.com>
17
+ * Seth Chisamore <schisamo@opscode.com>
18
+ * Tyler Rick
@@ -0,0 +1,141 @@
1
+ # chef-solo-search
2
+
3
+ Chef-solo-search is a cookbook library that adds data bag search powers
4
+ to Chef Solo. Data bag support was added to Chef Solo by Chef 0.10.4.
5
+ Please see *Supported queries* for a list of query types which are supported.
6
+
7
+ ## Requirements
8
+
9
+ * ruby >= 1.8
10
+ * ruby-chef >= 0.10.4
11
+
12
+ ## Installation
13
+
14
+ In order to use this extension, create a (dummy-) cookbook and add a directory
15
+ called *libraries*. Next copy *libraries/search.rb* and *libraries/parser.rb* to the newly created directory.
16
+ Now you have to make sure chef-solo knows about data bags, therefore add
17
+
18
+ data_bag_path "<node_work_path>/data_bags"
19
+
20
+ to the config file of chef-solo (defaults to /etc/chef/solo.rb).
21
+
22
+ The same for your roles, add
23
+
24
+ role_path "<node_work_path>/roles"
25
+
26
+ ## Supported queries
27
+
28
+ The search methods supports a basic sub-set of the lucene query language.
29
+ Sample supported queries are:
30
+
31
+ ### General queries:
32
+
33
+ search(:users, "*:*")
34
+ search(:users)
35
+ search(:users, nil)
36
+ getting all items in ':users'
37
+ search(:users, "username:*")
38
+ search(:users, "username:[* TO *]")
39
+ getting all items from ':users' which have a 'username' attribute
40
+ search(:users, "(NOT username:*)")
41
+ search(:users, "(NOT username:[* TO *])")
42
+ getting all items from ':users' which don't have a 'username' attribute
43
+
44
+ ### Queries on attributes with string values:
45
+
46
+ search(:users, "username:speedy")
47
+ getting all items from ':users' with username equals 'speedy'
48
+ search(:users, "NOT username:speedy")
49
+ getting all items from ':users' with username is unequal to 'speedy'
50
+ search(:users, "username:spe*")
51
+ getting all items which 'username'-value begins with 'spe'
52
+
53
+ ### Queries on attributes with array values:
54
+
55
+ search(:users, "children:tom")
56
+ getting all items which 'children' attribute contains 'tom'
57
+ search(:users, "children:t*")
58
+ getting all items which have at least one element in 'children'
59
+ which starts with 't'
60
+
61
+ ### Queries on attributes with boolean values:
62
+
63
+ search(:users, "married:true")
64
+
65
+ ### Queries in attributes with integer values:
66
+
67
+ search(:users, "age:35")
68
+
69
+ ### OR conditions in queries:
70
+
71
+ search(:users, "age:42 OR age:22")
72
+
73
+ ### AND conditions in queries:
74
+
75
+ search(:users, "married:true AND age:35")
76
+
77
+ ### NOT condition in queries:
78
+
79
+ search(:users, "children:tom NOT gender:female")
80
+
81
+ ### More complex queries:
82
+
83
+ search(:users, "children:tom NOT gender:female AND age:42")
84
+
85
+
86
+ ## Supported Objects
87
+ The search methods have support for 'roles', 'nodes' and 'databags'.
88
+
89
+ ### Roles
90
+ You can use the standard role objects in json form and put them into your role path
91
+
92
+ {
93
+ "name": "monitoring",
94
+ "default_attributes": { },
95
+ "override_attributes": { },
96
+ "json_class": "Chef::Role",
97
+ "description": "This is just a monitoring role, no big deal.",
98
+ "run_list": [
99
+ ],
100
+ "chef_type": "role"
101
+
102
+
103
+ ### Nodes
104
+ Nodes are injected through a databag called 'node'. Create a databag called 'node' and put your json files there
105
+ You can use the standard node objects in json form.
106
+
107
+ {
108
+ "id": "vagrant",
109
+ "name": "vagrant-vm",
110
+ "chef_environment": "_default",
111
+ "json_class": "Chef::Node",
112
+ "automatic": {
113
+ "hostname": "vagrant.vm",
114
+ "os": "centos"
115
+ },
116
+ "normal": {
117
+ },
118
+ "chef_type": "node",
119
+ "default": {
120
+ },
121
+ "override": {
122
+ },
123
+ "run_list": [
124
+ "role[monitoring]"
125
+ ]
126
+ }
127
+
128
+ ### Databags
129
+ You can use the standard databag objects in json form
130
+
131
+ {
132
+ "id": "my-ssh",
133
+ "hostgroup_name": "all",
134
+ "command_line": "$USER1$/check_ssh $HOSTADDRESS$"
135
+ }
136
+
137
+ ## Running tests
138
+
139
+ Running tests is as simple as:
140
+
141
+ % ruby -Ilibraries tests/test_search.rb -v
@@ -0,0 +1,72 @@
1
+ #
2
+ # Copyright 2011, edelight GmbH
3
+ #
4
+ # Authors:
5
+ # Markus Korn <markus.korn@edelight.de>
6
+ # Seth Chisamore <schisamo@opscode.com>
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ if Chef::Config[:solo]
22
+
23
+ # add currrent dir to load path
24
+ $: << File.dirname(__FILE__)
25
+
26
+ # All chef/solr_query/* classes were removed in Chef 11; Load vendored copy
27
+ # that ships with this cookbook
28
+ $: << File.expand_path("vendor", File.dirname(__FILE__)) if Chef::VERSION.to_i >= 11
29
+
30
+ # Ensure the treetop gem is installed and available
31
+ begin
32
+ require 'treetop'
33
+ rescue LoadError
34
+ run_context = Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)
35
+ Chef::Resource::ChefGem.new("treetop", run_context).run_action(:install)
36
+ end
37
+
38
+ require 'search/overrides'
39
+ require 'search/parser'
40
+
41
+ module Search; class Helper; end; end
42
+
43
+ # The search and data_bag related methods moved form `Chef::Mixin::Language`
44
+ # to `Chef::DSL::DataQuery` in Chef 11.
45
+ if Chef::VERSION.to_i >= 11
46
+ module Chef::DSL::DataQuery
47
+ def self.included(base)
48
+ base.send(:include, Search::Overrides)
49
+ end
50
+ end
51
+ Search::Helper.send(:include, Chef::DSL::DataQuery)
52
+ else
53
+ module Chef::Mixin::Language
54
+ def self.included(base)
55
+ base.send(:include, Search::Overrides)
56
+ end
57
+ end
58
+ Search::Helper.send(:include, Chef::Mixin::Language)
59
+ end
60
+
61
+ class Chef
62
+ class Search
63
+ class Query
64
+ def initialize(*args)
65
+ end
66
+ def search(*args, &block)
67
+ ::Search::Helper.new.search(*args, &block)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,99 @@
1
+ #
2
+ # Copyright 2011, edelight GmbH
3
+ #
4
+ # Authors:
5
+ # Markus Korn <markus.korn@edelight.de>
6
+ # Seth Chisamore <schisamo@opscode.com>
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ module Search
22
+ module Overrides
23
+ # Overwrite the search method of recipes to operate locally by using
24
+ # data found in data_bags.
25
+ # Only very basic lucene syntax is supported and also sorting the result
26
+ # is not implemented, if this search method does not support a given query
27
+ # an exception is raised.
28
+ # This search() method returns a block iterator or an Array, depending
29
+ # on how this method is called.
30
+ def search(obj, query=nil, sort=nil, start=0, rows=1000, &block)
31
+ if !sort.nil?
32
+ raise "Sorting search results is not supported"
33
+ end
34
+ _query = Query.parse(query)
35
+ if _query.nil?
36
+ raise "Query #{query} is not supported"
37
+ end
38
+ _result = []
39
+
40
+ case obj
41
+ when :node
42
+ nodes = search_nodes(_query, start, rows, &block)
43
+ _result += nodes
44
+ when :role
45
+ roles = search_roles(_query, start, rows, &block)
46
+ _result += roles
47
+ else
48
+ bags = search_data_bag(_query, obj, start, rows, &block)
49
+ _result += bags
50
+ end
51
+
52
+
53
+ if block_given?
54
+ pos = 0
55
+ while (pos >= start and pos < (start + rows) and pos < _result.size)
56
+ yield _result[pos]
57
+ pos += 1
58
+ end
59
+ else
60
+ return _result.slice(start, rows)
61
+ end
62
+ end
63
+
64
+ def search_nodes(_query, start, rows, &block)
65
+ _result = []
66
+ Dir.glob(File.join(Chef::Config[:data_bag_path], "node", "*.json")).map do |f|
67
+ # parse and hashify the node
68
+ node = Chef::JSONCompat.from_json(IO.read(f))
69
+ if _query.match(node.to_hash)
70
+ _result << node
71
+ end
72
+ end
73
+ return _result
74
+ end
75
+
76
+ def search_roles(_query, start, rows, &block)
77
+ _result = []
78
+ Dir.glob(File.join(Chef::Config[:role_path], "*.json")).map do |f|
79
+ # parse and hashify the role
80
+ role = Chef::JSONCompat.from_json(IO.read(f))
81
+ if _query.match(role.to_hash)
82
+ _result << role
83
+ end
84
+ end
85
+ return _result
86
+ end
87
+
88
+ def search_data_bag(_query, bag_name, start, rows, &block)
89
+ _result = []
90
+ data_bag(bag_name.to_s).each do |bag_item_id|
91
+ bag_item = data_bag_item(bag_name.to_s, bag_item_id)
92
+ if _query.match(bag_item)
93
+ _result << bag_item
94
+ end
95
+ end
96
+ return _result
97
+ end
98
+ end
99
+ end
@@ -17,7 +17,6 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require 'treetop'
21
20
  require 'chef/solr_query/query_transform'
22
21
 
23
22
  # mock QueryTransform such that we can access the location of the lucene grammar
@@ -107,7 +106,7 @@ module Lucene
107
106
  part = self.text_value.chomp("*")
108
107
  item.keys.collect{ |key| key.start_with?(part)? key: nil}.compact
109
108
  else
110
- if item[self.text_value]
109
+ if item.has_key?(self.text_value)
111
110
  [self.text_value,]
112
111
  else
113
112
  nil
@@ -0,0 +1,150 @@
1
+ #
2
+ # Author:: Seth Falcon (<seth@opscode.com>)
3
+ # Copyright:: Copyright (c) 2010-2011 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ grammar Lucene
20
+
21
+ rule body
22
+ (expression / space)* <Body>
23
+ end
24
+
25
+ rule expression
26
+ operation / group / field / field_range / term / string
27
+ end
28
+
29
+ rule term
30
+ keyword valid_letter+ <Term> / !keyword !"?" valid_letter <Term>
31
+ end
32
+
33
+ rule field
34
+ field_name ":" (term/string/group) <Field>
35
+ end
36
+
37
+ rule field_range
38
+ field_name ":" "[" range_value " TO " range_value "]" <InclFieldRange>
39
+ /
40
+ field_name ":" "{" range_value " TO " range_value "}" <ExclFieldRange>
41
+ end
42
+
43
+ rule field_name
44
+ !keyword valid_letter+ <FieldName>
45
+ end
46
+
47
+ rule range_value
48
+ valid_letter+ <RangeValue> / "*" <RangeValue>
49
+ end
50
+
51
+ rule group
52
+ space? '(' body ')' space? <Group>
53
+ end
54
+
55
+ rule operation
56
+ binary_op / unary_op / fuzzy_op / boost_op
57
+ end
58
+
59
+ rule unary_op
60
+ not_op / required_op / prohibited_op
61
+ end
62
+
63
+ rule binary_op
64
+ (group / field / field_range / term) space? boolean_operator space+ body <BinaryOp>
65
+ end
66
+
67
+ rule boolean_operator
68
+ and_operator / or_operator
69
+ end
70
+
71
+ rule and_operator
72
+ 'AND' <AndOperator> / '&&' <AndOperator>
73
+ end
74
+
75
+ rule or_operator
76
+ 'OR' <OrOperator> / '||' <OrOperator>
77
+ end
78
+
79
+ rule not_op
80
+ not_operator space (group / field / field_range / term / string) <UnaryOp>
81
+ /
82
+ bang_operator space? (group / field / field_range / term / string) <UnaryOp>
83
+ end
84
+
85
+ rule not_operator
86
+ 'NOT' <NotOperator>
87
+ end
88
+
89
+ rule bang_operator
90
+ '!' <NotOperator>
91
+ end
92
+
93
+ rule required_op
94
+ !valid_letter required_operator (term/string) <UnaryOp>
95
+ /
96
+ required_operator (term/string) <UnaryOp>
97
+ end
98
+
99
+ rule required_operator
100
+ '+' <RequiredOperator>
101
+ end
102
+
103
+ rule prohibited_op
104
+ !valid_letter prohibited_operator (field/field_range/term/string) <UnaryOp>
105
+ end
106
+
107
+ rule prohibited_operator
108
+ '-' <ProhibitedOperator>
109
+ end
110
+
111
+ rule boost_op
112
+ (term/string) '^' fuzzy_param <BoostOp>
113
+ end
114
+
115
+ rule fuzzy_op
116
+ (term/string) '~' fuzzy_param? (space / !valid_letter) <FuzzyOp>
117
+ end
118
+
119
+ rule fuzzy_param
120
+ [0-9] '.'? [0-9] <FuzzyParam> / [0-9]+ <FuzzyParam>
121
+ end
122
+
123
+ rule string
124
+ '"' term (space term)* '"' <Phrase>
125
+ end
126
+
127
+ rule keyword
128
+ 'AND' / 'OR' / 'NOT'
129
+ end
130
+
131
+ rule valid_letter
132
+ start_letter+ ([a-zA-Z0-9@*?_.-] / '\\' special_char)*
133
+ end
134
+
135
+ rule start_letter
136
+ [a-zA-Z0-9@._*] / '\\' special_char
137
+ end
138
+
139
+ rule end_letter
140
+ [a-zA-Z0-9*?_.] / '\\' special_char
141
+ end
142
+
143
+ rule special_char
144
+ [-+&|!(){}\[\]^"~*?:\\]
145
+ end
146
+
147
+ rule space
148
+ [\s]+
149
+ end
150
+ end