knife-attribute 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -15,8 +15,9 @@ gem install knife-attribute
15
15
  In this initial release, only `node attribute set` is implemented, more to
16
16
  follow in the near future.
17
17
 
18
- To work with attributes of type `default`, `normal`, `override` or `automatic`,
19
- use the `-t TYPE` flag (default if unspecified is `normal`).
18
+ To work with attributes of type `default`, `normal` or `override`, use the
19
+ `-t TYPE` flag (the default type if unspecified is `normal` for `nodes`, and
20
+ `default` for all other entity types).
20
21
 
21
22
  ### node attribute set
22
23
 
@@ -74,10 +75,42 @@ The above would delete the `foo.example.org` node's `normal` attribute `tz`.
74
75
  knife node attribute delete foo.example.org apache.listen_ports -t override
75
76
  ```
76
77
 
77
- The above would delete the `foo.example.org` node's `override` attribute.
78
+ The above would delete the `foo.example.org` node's `override` attribute
78
79
  `['apache']['listen_ports']`.
79
80
 
81
+ ### role attribute set
82
+
83
+ Valid attribute types for roles are: `['default', 'override']`.
84
+
85
+ For usage, see `node attribute set` above.
86
+
87
+ ### role attribute get
88
+
89
+ Valid attribute types for roles are: `['default', 'override']`.
90
+
91
+ For usage, see `node attribute get` above.
92
+
93
+ ### role attribute delete
94
+
95
+ Valid attribute types for roles are: `['default', 'override']`.
96
+
97
+ For usage, see `node attribute delete` above.
98
+
99
+ ### environment attribute set
100
+
101
+ Valid attribute types for environments are: `['default', 'override']`.
102
+
103
+ For usage, see `node attribute set` above.
104
+
105
+ ### environment attribute get
106
+
107
+ Valid attribute types for environments are: `['default', 'override']`.
108
+
109
+ For usage, see `node attribute get` above.
110
+
111
+ ### environment attribute delete
112
+
113
+ Valid attribute types for environments are: `['default', 'override']`.
114
+
115
+ For usage, see `node attribute delete` above.
80
116
 
81
- ## TODO
82
- - Implement attribute get/set/delete for roles
83
- - Implement attribute get/set/delete for environments
@@ -1,9 +1,19 @@
1
1
  require 'chef/knife'
2
2
  require 'knife-attribute/version'
3
- require 'knife-attribute/attribute_types'
4
- require 'knife-attribute/helpers'
5
3
  require 'knife-attribute/common_options'
4
+ require 'knife-attribute/helpers'
5
+ require 'knife-attribute/get'
6
+ require 'knife-attribute/set'
7
+ require 'knife-attribute/delete'
6
8
  require 'knife-attribute/node/helpers'
7
- require 'knife-attribute/node/set'
8
9
  require 'knife-attribute/node/get'
10
+ require 'knife-attribute/node/set'
9
11
  require 'knife-attribute/node/delete'
12
+ require 'knife-attribute/role/helpers'
13
+ require 'knife-attribute/role/get'
14
+ require 'knife-attribute/role/set'
15
+ require 'knife-attribute/role/delete'
16
+ require 'knife-attribute/environment/helpers'
17
+ require 'knife-attribute/environment/get'
18
+ require 'knife-attribute/environment/set'
19
+ require 'knife-attribute/environment/delete'
@@ -5,13 +5,12 @@ module KnifeAttribute
5
5
  option :attribute_type,
6
6
  short: '-t TYPE',
7
7
  long: '--type TYPE',
8
- default: 'normal',
9
- description: "Attribute type to set, one of: #{KnifeAttribute::ATTRIBUTE_TYPES} (default: 'normal')"
8
+ description: "Attribute type, one of: #{attribute_type_map.keys.map(&:to_s)} (default: '#{default_attribute_type.to_s}')"
10
9
  end
11
10
  end
12
11
 
13
12
  def check_type
14
- if config[:attribute_type] and !KnifeAttribute::ATTRIBUTE_TYPES.include?(config[:attribute_type])
13
+ if config[:attribute_type] and !attribute_type_map.keys.include?(config[:attribute_type].to_sym)
15
14
  show_usage
16
15
  ui.fatal("Invalid attribute type: '#{config[:attribute_type]}'")
17
16
  end
@@ -0,0 +1,60 @@
1
+ module KnifeAttribute
2
+ module Delete
3
+ def self.included(base)
4
+ base.class_eval do
5
+ include KnifeAttribute::CommonOptions
6
+
7
+ def run
8
+ check_arguments
9
+
10
+ if config[:attribute_type]
11
+ delete_attribute(entity.send(attribute_type_map[config[:attribute_type].to_sym]))
12
+ else
13
+ delete_attribute(entity.send(attribute_type_map[default_attribute_type]))
14
+ end
15
+ end
16
+
17
+ private
18
+ def check_arguments
19
+ if entity_name.nil?
20
+ show_usage
21
+ ui.fatal("You must specify a #{entity_type.to_s} name")
22
+ exit 1
23
+ end
24
+
25
+ if attribute.nil?
26
+ show_usage
27
+ ui.fatal('You must specify an attribute')
28
+ exit 1
29
+ end
30
+
31
+ check_type
32
+ end
33
+
34
+ def delete_attribute(target)
35
+ path = attribute.split('.')
36
+ key = path.pop
37
+
38
+ if path.length == 0
39
+ parent = target
40
+ else
41
+ parent = path.inject(target) { |obj, subkey| obj[subkey] || break }
42
+ end
43
+
44
+ result = false
45
+ if parent and parent.has_key?(key)
46
+ parent.delete(key)
47
+ result = entity.save
48
+ end
49
+
50
+ if result
51
+ ui.info("Successfully deleted #{entity_type.to_s} #{ui.color(entity_name, :cyan)} attribute #{ui.color(attribute, :green)}")
52
+ else
53
+ ui.fatal("Failed deleting #{entity_type.to_s} #{ui.color(entity_name, :magenta)} attribute #{ui.color(new_attribute, :magenta)}")
54
+ exit 1
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ module KnifeAttribute
2
+ module Environment
3
+ class EnvironmentAttributeDelete < Chef::Knife
4
+ include KnifeAttribute::Environment::Helpers
5
+ include KnifeAttribute::Delete
6
+
7
+ banner 'knife environment attribute delete ENVIRONMENT PERIOD.SEPARATED.ATTRIBUTE (options)'
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module KnifeAttribute
2
+ module Environment
3
+ class EnvironmentAttributeGet < Chef::Knife
4
+ include KnifeAttribute::Environment::Helpers
5
+ include KnifeAttribute::Get
6
+
7
+ banner 'knife environment attribute get ENVIRONMENT PERIOD.SEPARATED.ATTRIBUTE (options)'
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module KnifeAttribute
2
+ module Environment
3
+ module Helpers
4
+ include KnifeAttribute::Helpers
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ deps do
9
+ require 'chef/json_compat'
10
+ end
11
+
12
+ def self.attribute_type_map
13
+ {
14
+ default: :default_attributes,
15
+ override: :override_attributes,
16
+ }
17
+ end
18
+
19
+ def self.default_attribute_type
20
+ :default
21
+ end
22
+ end
23
+ end
24
+
25
+ def environment
26
+ @environment ||= Chef::Environment.load(entity_name)
27
+ end
28
+
29
+ def entity_type
30
+ :environment
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module KnifeAttribute
2
+ module Environment
3
+ class EnvironmentAttributeSet < Chef::Knife
4
+ include KnifeAttribute::Environment::Helpers
5
+ include KnifeAttribute::Set
6
+
7
+ banner 'knife environment attribute set ENVIRONMENT PERIOD.SEPARATED.ATTRIBUTE STRING_OR_JSON_VALUE (options)'
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,43 @@
1
+ module KnifeAttribute
2
+ module Get
3
+ def self.included(base)
4
+ base.class_eval do
5
+ include KnifeAttribute::CommonOptions
6
+
7
+ def run
8
+ check_arguments
9
+
10
+ if config[:attribute_type]
11
+ get_attribute(entity.send(attribute_type_map[config[:attribute_type].to_sym]))
12
+ elsif entity.respond_to?(:construct_attributes)
13
+ get_attribute(entity.construct_attributes)
14
+ else
15
+ get_attribute(entity.send(attribute_type_map[default_attribute_type]))
16
+ end
17
+ end
18
+
19
+ private
20
+ def check_arguments
21
+ if entity_name.nil?
22
+ show_usage
23
+ ui.fatal("You must specify a #{entity_type.to_s} name")
24
+ exit 1
25
+ end
26
+
27
+ if attribute.nil?
28
+ show_usage
29
+ ui.fatal('You must specify an attribute')
30
+ exit 1
31
+ end
32
+
33
+ check_type
34
+ end
35
+
36
+ def get_attribute(target)
37
+ result = ui.presenter.extract_nested_value(target, attribute)
38
+ output(format_for_display(result))
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,44 @@
1
1
  module KnifeAttribute
2
2
  module Helpers
3
+ def self.included(base)
4
+ base.class_eval do
5
+ def self.attribute_type_map
6
+ fail NotImplementedError, "Missing `attribute_types` implementation for current object"
7
+ end
8
+
9
+ def self.default_attribute_type
10
+ fail NotImplementedError, "Missing `default_attribute_type` implementation for current object"
11
+ end
12
+ end
13
+ end
14
+ def attribute
15
+ @attribute ||= @name_args[1]
16
+ end
17
+
18
+ def value
19
+ @value ||= @name_args[2]
20
+ end
21
+
22
+ def entity_name
23
+ @entity_name ||= @name_args[0]
24
+ end
25
+
26
+ def entity
27
+ @entity = send(entity_type)
28
+ end
29
+
30
+ def entity_type
31
+ fail NotImplementedError, "Missing `entity_type` implementation for current object"
32
+ end
33
+
34
+ def attribute_type_map
35
+ self.class.attribute_type_map
36
+ end
37
+
38
+ def default_attribute_type
39
+ self.class.default_attribute_type
40
+ end
41
+
3
42
  def mapped_config
4
43
  @mapped_config ||= config[:attribute_type] == 'normal' ? {} : {all_attributes: true}
5
44
  end
@@ -1,68 +1,11 @@
1
1
  module KnifeAttribute
2
2
  module Node
3
3
  class NodeAttributeDelete < Chef::Knife
4
- include KnifeAttribute::CommonOptions
5
4
  include KnifeAttribute::Node::Helpers
5
+ include KnifeAttribute::Delete
6
6
 
7
7
  banner 'knife node attribute delete NODE PERIOD.SEPARATED.ATTRIBUTE (options)'
8
8
 
9
- def run
10
- check_arguments
11
-
12
- case config[:attribute_type]
13
- when 'default'
14
- delete_attribute(node.default_attrs)
15
- when 'override'
16
- delete_attribute(node.override_attrs)
17
- when 'automatic'
18
- delete_attribute(node.automatic_attrs)
19
- when 'normal'
20
- delete_attribute(node.normal_attrs)
21
- else
22
- delete_attribute(node.normal_attrs)
23
- end
24
- end
25
-
26
- private
27
- def check_arguments
28
- if node_name.nil?
29
- show_usage
30
- ui.fatal('You must specify a node name')
31
- exit 1
32
- end
33
-
34
- if attribute.nil?
35
- show_usage
36
- ui.fatal('You must specify an attribute')
37
- exit 1
38
- end
39
-
40
- check_type
41
- end
42
-
43
- def delete_attribute(target)
44
- path = attribute.split('.')
45
- key = path.pop
46
-
47
- if path.length == 0
48
- parent = target
49
- else
50
- parent = path.inject(target) { |obj, item| obj[item] || break }
51
- end
52
-
53
- result = false
54
- if parent and parent.has_key?(key)
55
- parent.delete(key)
56
- result = node.save
57
- end
58
-
59
- if result
60
- ui.info("Successfully deleted node #{ui.color(node_name, :cyan)} attribute #{ui.color(attribute, :green)}")
61
- else
62
- ui.fatal("Failed deleting node #{ui.color(node_name, :magenta)} attribute #{ui.color(new_attribute, :magenta)}")
63
- exit 1
64
- end
65
- end
66
9
  end
67
10
  end
68
11
  end
@@ -1,49 +1,11 @@
1
1
  module KnifeAttribute
2
2
  module Node
3
3
  class NodeAttributeGet < Chef::Knife
4
- include KnifeAttribute::CommonOptions
5
4
  include KnifeAttribute::Node::Helpers
5
+ include KnifeAttribute::Get
6
6
 
7
7
  banner 'knife node attribute get NODE PERIOD.SEPARATED.ATTRIBUTE (options)'
8
8
 
9
- def run
10
- check_arguments
11
-
12
- case config[:attribute_type]
13
- when 'default'
14
- get_attribute(node.default_attrs)
15
- when 'override'
16
- get_attribute(node.override_attrs)
17
- when 'automatic'
18
- get_attribute(node.automatic_attrs)
19
- when 'normal'
20
- get_attribute(node.normal_attrs)
21
- else
22
- get_attribute(node.construct_attributes)
23
- end
24
- end
25
-
26
- private
27
- def check_arguments
28
- if node_name.nil?
29
- show_usage
30
- ui.fatal('You must specify a node name')
31
- exit 1
32
- end
33
-
34
- if attribute.nil?
35
- show_usage
36
- ui.fatal('You must specify an attribute')
37
- exit 1
38
- end
39
-
40
- check_type
41
- end
42
-
43
- def get_attribute(target)
44
- result = ui.presenter.extract_nested_value(target, attribute)
45
- output(format_for_display(result))
46
- end
47
9
  end
48
10
  end
49
11
  end
@@ -9,23 +9,27 @@ module KnifeAttribute
9
9
  require 'chef/node'
10
10
  require 'chef/json_compat'
11
11
  end
12
- end
13
- end
14
12
 
15
- def node_name
16
- @node_name ||= @name_args[0]
17
- end
13
+ def self.attribute_type_map
14
+ {
15
+ default: :default_attrs,
16
+ normal: :normal_attrs,
17
+ override: :override_attrs,
18
+ }
19
+ end
18
20
 
19
- def attribute
20
- @attribute ||= @name_args[1]
21
+ def self.default_attribute_type
22
+ :normal
23
+ end
24
+ end
21
25
  end
22
26
 
23
- def value
24
- @value ||= @name_args[2]
27
+ def node
28
+ @node ||= Chef::Node.load(entity_name)
25
29
  end
26
30
 
27
- def node
28
- @node ||= Chef::Node.load(node_name)
31
+ def entity_type
32
+ :node
29
33
  end
30
34
  end
31
35
  end
@@ -1,65 +1,11 @@
1
1
  module KnifeAttribute
2
2
  module Node
3
3
  class NodeAttributeSet < Chef::Knife
4
- include KnifeAttribute::CommonOptions
5
4
  include KnifeAttribute::Node::Helpers
5
+ include KnifeAttribute::Set
6
6
 
7
7
  banner 'knife node attribute set NODE PERIOD.SEPARATED.ATTRIBUTE STRING_OR_JSON_VALUE (options)'
8
8
 
9
- def run
10
- check_arguments
11
-
12
- case config[:attribute_type]
13
- when 'default'
14
- set_attribute(node.default_attrs)
15
- when 'override'
16
- set_attribute(node.override_attrs)
17
- when 'automatic'
18
- set_attribute(node.automatic_attrs)
19
- when 'normal', nil
20
- set_attribute(node.normal_attrs)
21
- end
22
- end
23
-
24
- private
25
- def check_arguments
26
- if node_name.nil?
27
- show_usage
28
- ui.fatal('You must specify a node name')
29
- exit 1
30
- end
31
-
32
- if attribute.nil?
33
- show_usage
34
- ui.fatal('You must specify an attribute')
35
- exit 1
36
- end
37
-
38
- if value.nil?
39
- show_usage
40
- ui.fatal('You must specify a value')
41
- exit 1
42
- end
43
-
44
- check_type
45
- end
46
-
47
- def set_attribute(target)
48
- begin
49
- new_value = Chef::JSONCompat.from_json(value)
50
- rescue JSON::ParserError, Yajl::ParseError
51
- new_value = value
52
- end
53
- new_attribute = attribute.split('.').reverse.inject(new_value) { |result, key| { key => result } }
54
- target.merge!(new_attribute)
55
-
56
- if node.save
57
- ui.info("Successfully set node #{ui.color(node_name, :cyan)} attribute #{ui.color(attribute, :cyan)} to: #{ui.color(new_value.inspect, :green)}")
58
- else
59
- ui.fatal("Failed updating node #{ui.color(node_name, :magenta)} attribute #{ui.color(new_attribute, :magenta)}")
60
- exit 1
61
- end
62
- end
63
9
  end
64
10
  end
65
11
  end
@@ -0,0 +1,11 @@
1
+ module KnifeAttribute
2
+ module Role
3
+ class RoleAttributeDelete < Chef::Knife
4
+ include KnifeAttribute::Role::Helpers
5
+ include KnifeAttribute::Delete
6
+
7
+ banner 'knife role attribute delete ROLE PERIOD.SEPARATED.ATTRIBUTE (options)'
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module KnifeAttribute
2
+ module Role
3
+ class RoleAttributeGet < Chef::Knife
4
+ include KnifeAttribute::Role::Helpers
5
+ include KnifeAttribute::Get
6
+
7
+ banner 'knife role attribute get ROLE PERIOD.SEPARATED.ATTRIBUTE (options)'
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module KnifeAttribute
2
+ module Role
3
+ module Helpers
4
+ include KnifeAttribute::Helpers
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ deps do
9
+ require 'chef/json_compat'
10
+ end
11
+
12
+ def self.attribute_type_map
13
+ {
14
+ default: :default_attributes,
15
+ override: :override_attributes,
16
+ }
17
+ end
18
+
19
+ def self.default_attribute_type
20
+ :default
21
+ end
22
+ end
23
+ end
24
+
25
+ def role
26
+ @role ||= Chef::Role.load(entity_name)
27
+ end
28
+
29
+ def entity_type
30
+ :role
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module KnifeAttribute
2
+ module Role
3
+ class RoleAttributeSet < Chef::Knife
4
+ include KnifeAttribute::Role::Helpers
5
+ include KnifeAttribute::Set
6
+
7
+ banner 'knife role attribute set ROLE PERIOD.SEPARATED.ATTRIBUTE STRING_OR_JSON_VALUE (options)'
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,59 @@
1
+ module KnifeAttribute
2
+ module Set
3
+ def self.included(base)
4
+ base.class_eval do
5
+ include KnifeAttribute::CommonOptions
6
+
7
+ def run
8
+ check_arguments
9
+
10
+ if config[:attribute_type]
11
+ set_attribute(entity.send(attribute_type_map[config[:attribute_type].to_sym]))
12
+ else
13
+ set_attribute(entity.send(attribute_type_map[default_attribute_type]))
14
+ end
15
+ end
16
+
17
+ private
18
+ def check_arguments
19
+ if entity_name.nil?
20
+ show_usage
21
+ ui.fatal("You must specify a #{entity_type.to_s} name")
22
+ exit 1
23
+ end
24
+
25
+ if attribute.nil?
26
+ show_usage
27
+ ui.fatal('You must specify an attribute')
28
+ exit 1
29
+ end
30
+
31
+ if value.nil?
32
+ show_usage
33
+ ui.fatal('You must specify a value')
34
+ exit 1
35
+ end
36
+
37
+ check_type
38
+ end
39
+
40
+ def set_attribute(target)
41
+ begin
42
+ new_value = Chef::JSONCompat.from_json(value)
43
+ rescue JSON::ParserError, Yajl::ParseError
44
+ new_value = value
45
+ end
46
+ new_attribute = attribute.split('.').reverse.inject(new_value) { |result, key| { key => result } }
47
+ target.merge!(new_attribute)
48
+
49
+ if entity.save
50
+ ui.info("Successfully set #{entity_type.to_s} #{ui.color(entity_name, :cyan)} attribute #{ui.color(attribute, :cyan)} to: #{ui.color(new_value.inspect, :green)}")
51
+ else
52
+ ui.fatal("Failed updating #{entity_type.to_s} #{ui.color(entity_name, :magenta)} attribute #{ui.color(new_attribute, :magenta)}")
53
+ exit 1
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,3 +1,3 @@
1
1
  module KnifeAttribute
2
- VERSION = "0.1.2"
2
+ VERSION = '1.0.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-attribute
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -75,13 +75,23 @@ files:
75
75
  - knife-attribute.gemspec
76
76
  - lib/chef/knife/attribute.rb
77
77
  - lib/knife-attribute.rb
78
- - lib/knife-attribute/attribute_types.rb
79
78
  - lib/knife-attribute/common_options.rb
79
+ - lib/knife-attribute/delete.rb
80
+ - lib/knife-attribute/environment/delete.rb
81
+ - lib/knife-attribute/environment/get.rb
82
+ - lib/knife-attribute/environment/helpers.rb
83
+ - lib/knife-attribute/environment/set.rb
84
+ - lib/knife-attribute/get.rb
80
85
  - lib/knife-attribute/helpers.rb
81
86
  - lib/knife-attribute/node/delete.rb
82
87
  - lib/knife-attribute/node/get.rb
83
88
  - lib/knife-attribute/node/helpers.rb
84
89
  - lib/knife-attribute/node/set.rb
90
+ - lib/knife-attribute/role/delete.rb
91
+ - lib/knife-attribute/role/get.rb
92
+ - lib/knife-attribute/role/helpers.rb
93
+ - lib/knife-attribute/role/set.rb
94
+ - lib/knife-attribute/set.rb
85
95
  - lib/knife-attribute/version.rb
86
96
  homepage: https://github.com/pdf/knife-attribute
87
97
  licenses:
@@ -98,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
108
  version: '0'
99
109
  segments:
100
110
  - 0
101
- hash: -2202112453603936614
111
+ hash: -2632599109379407878
102
112
  required_rubygems_version: !ruby/object:Gem::Requirement
103
113
  none: false
104
114
  requirements:
@@ -107,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
117
  version: '0'
108
118
  segments:
109
119
  - 0
110
- hash: -2202112453603936614
120
+ hash: -2632599109379407878
111
121
  requirements: []
112
122
  rubyforge_project:
113
123
  rubygems_version: 1.8.25
@@ -1,4 +0,0 @@
1
- module KnifeAttribute
2
- ATTRIBUTE_TYPES = %w{default normal override automatic}
3
- end
4
-