ncedit 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/Makefile +3 -0
- data/README.md +9 -0
- data/exe/ncedit +37 -0
- data/lib/ncedit/cmd.rb +79 -30
- data/lib/ncedit/version.rb +1 -1
- data/ncedit.gemspec +4 -4
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e96cfedf083f77d881e84689e8126fcb2eacd5e965a1c78a8bfbbb3957468ccd
|
4
|
+
data.tar.gz: b2f81404318ea89f27d49bf7f2275c570aacb89816857ad76802479ba93e1fad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47c9753e923f1c6410093a8cc55506b6344bc8c13b0ce89d6a1f295fdfd4b3a2b3d0f0ac82b9cce6566c754300954a9dd58c2b599c0b97237e470be5d4e144f1
|
7
|
+
data.tar.gz: a8d646edffb771c405fccc8726769612f66126868e07c05cafb852df35d14f6b6ebfca44f9ff02cbc255cea59d49503b6e7c7081537c1e6a50cd775d2f45156d
|
data/.travis.yml
CHANGED
data/Makefile
ADDED
data/README.md
CHANGED
@@ -13,6 +13,7 @@ You can:
|
|
13
13
|
* Add or remove classes
|
14
14
|
* Add or remove class parameters
|
15
15
|
* Add or remove rules
|
16
|
+
* Add or edit environment groups
|
16
17
|
|
17
18
|
...All from the convenience of the CLI. This allows us to be called from scripts and other systems in order to setup Puppet Enterprise the way you want and with the minimum of effort.
|
18
19
|
|
@@ -223,6 +224,14 @@ ncedit classes --group-name FOO --rule 'JSON_FRAGMENT' --rule-mode append
|
|
223
224
|
* Example JSON_FRAGMENT: `["and",["=",["fact","osfamily"],"RedHat"]]`
|
224
225
|
* Notice in our example JSON_FRAGMENT that we have *kept* the outer `and` rule. If we supply a conjuctive different to the rule's current value we will change it for the whole rule
|
225
226
|
|
227
|
+
### Add/edit an environment group (experimental)
|
228
|
+
|
229
|
+
```shell
|
230
|
+
ncedit groups --group-name "Agent-specified environment" --environment agent-specified --environment-trumps --rule '["~",["fact","fqdn"],".*"]' --rule-mode replace
|
231
|
+
```
|
232
|
+
* Group will be created if it doesn't exit
|
233
|
+
* Will be nested under `All Environments`
|
234
|
+
|
226
235
|
## Smart updates
|
227
236
|
The NC API will only accept rules for classes that currently exist on the system, so its likely that your rules will be rejected if they have not yet been deployed to the master. To make this process as seamless as possible, the `--smart-update` option will perform this task for you as-and-when required. This assumes you have already setup RBAC to grant access to Code Manager, this can be done in a single command using the [pe_rbac gem](https://github.com/declarativesystems/pe_rbac#setting-up-code-manager-on-the-command-line)
|
228
237
|
|
data/exe/ncedit
CHANGED
@@ -104,6 +104,43 @@ Escort::App.create do |app|
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
+
app.command :groups do |command|
|
108
|
+
command.summary "Create/Edit groups"
|
109
|
+
command.description "Create or edit groups (and set environment)"
|
110
|
+
command.options do |opts|
|
111
|
+
opts.opt(:group_name,
|
112
|
+
'NC group name',
|
113
|
+
:long => '--group-name',
|
114
|
+
:type => :string,
|
115
|
+
)
|
116
|
+
opts.opt(:environment,
|
117
|
+
'Group should use this environment',
|
118
|
+
:long => '--environment',
|
119
|
+
:type => :string,
|
120
|
+
)
|
121
|
+
opts.opt(:environment_trumps,
|
122
|
+
'Group environment overrides all others',
|
123
|
+
:long => '--environment-trumps',
|
124
|
+
:type => :boolean,
|
125
|
+
)
|
126
|
+
opts.opt(:rule,
|
127
|
+
'Update the NC group with this rule (JSON fragment)',
|
128
|
+
:long => '--rule',
|
129
|
+
:type => :string,
|
130
|
+
)
|
131
|
+
|
132
|
+
opts.opt(:rule_mode,
|
133
|
+
"Processing instruction for rule supplied with --rule (allowed: 'replace', 'append')",
|
134
|
+
:long => '--rule-mode',
|
135
|
+
:type => :string,
|
136
|
+
)
|
137
|
+
end
|
138
|
+
command.action do |options, arguments|
|
139
|
+
NCEdit::Cmd::groups(options[:global][:commands][:groups][:options])
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
107
144
|
app.command :update_classes do |command|
|
108
145
|
command.summary "Refresh the classes available in the console"
|
109
146
|
command.description "Invalidate class cache and ask puppet to re-scan classes"
|
data/lib/ncedit/cmd.rb
CHANGED
@@ -75,7 +75,7 @@ module NCEdit
|
|
75
75
|
end
|
76
76
|
|
77
77
|
# Fetch a group by ID, make the group if it doesn't already exist
|
78
|
-
def self.nc_group_id(group_name)
|
78
|
+
def self.nc_group_id(group_name, parent_name: "All Nodes")
|
79
79
|
if ! @puppetclassify
|
80
80
|
init
|
81
81
|
end
|
@@ -86,7 +86,7 @@ module NCEdit
|
|
86
86
|
res = @puppetclassify.groups.create_group(
|
87
87
|
{
|
88
88
|
"name" => group_name,
|
89
|
-
"parent" => @puppetclassify.groups.get_group_id(
|
89
|
+
"parent" => @puppetclassify.groups.get_group_id(parent_name),
|
90
90
|
"classes" => {},
|
91
91
|
}
|
92
92
|
)
|
@@ -101,14 +101,14 @@ module NCEdit
|
|
101
101
|
group_id
|
102
102
|
end
|
103
103
|
|
104
|
-
def self.nc_group(group_name)
|
104
|
+
def self.nc_group(group_name, parent_name:nil)
|
105
105
|
if ! @puppetclassify
|
106
106
|
init
|
107
107
|
end
|
108
108
|
# Get the wanted group from the API
|
109
109
|
# 1. Get the id of the wanted group
|
110
110
|
# 2. Use the id to fetch the group
|
111
|
-
group_id
|
111
|
+
group_id = nc_group_id(group_name, parent_name: parent_name)
|
112
112
|
Escort::Logger.output.puts "Group #{group_name} found, getting definition"
|
113
113
|
group = @puppetclassify.groups.get_group(group_id)
|
114
114
|
|
@@ -142,7 +142,7 @@ module NCEdit
|
|
142
142
|
nc_class == class_delta_reformatted
|
143
143
|
end
|
144
144
|
|
145
|
-
def self.update_group(group_name, classes: nil, rule: nil)
|
145
|
+
def self.update_group(group_name, classes: nil, rule: nil, environment: nil, environment_trumps: nil)
|
146
146
|
# group_delta will actually replace all classes/rules with whatever is
|
147
147
|
# specified, so we need to merge this with any existing definition if
|
148
148
|
# one of these fields is not needed for a particular update otherwise
|
@@ -155,10 +155,20 @@ module NCEdit
|
|
155
155
|
rule = nc_group(group_name)["rule"]
|
156
156
|
end
|
157
157
|
|
158
|
+
if environment == nil
|
159
|
+
environment = nc_group(group_name)["environment"]
|
160
|
+
end
|
161
|
+
|
162
|
+
if ! environment_trumps
|
163
|
+
environment_trumps = nc_group(group_name)["environment_trumps"]
|
164
|
+
end
|
165
|
+
|
158
166
|
group_delta = {
|
159
|
-
'id'
|
160
|
-
'rule'
|
161
|
-
'classes'
|
167
|
+
'id' => nc_group_id(group_name),
|
168
|
+
'rule' => rule,
|
169
|
+
'classes' => classes,
|
170
|
+
'environment' => environment,
|
171
|
+
'environment_trumps' => environment_trumps,
|
162
172
|
}
|
163
173
|
res = @puppetclassify.groups.update_group(group_delta)
|
164
174
|
|
@@ -170,7 +180,10 @@ module NCEdit
|
|
170
180
|
# previously seen some output since puppetclassify prints some useful
|
171
181
|
# debug output
|
172
182
|
re_read_group = nc_group(group_name)
|
173
|
-
if delta_saved?(re_read_group["classes"], classes)
|
183
|
+
if delta_saved?(re_read_group["classes"], classes) &&
|
184
|
+
re_read_group["rule"] == rule &&
|
185
|
+
re_read_group["environment"] == environment &&
|
186
|
+
re_read_group["environment_trumps"] == environment_trumps
|
174
187
|
Escort::Logger.output.puts "changes saved"
|
175
188
|
else
|
176
189
|
Escort::Logger.error.error "re-read #{group_name} results in #{re_read_group} should have delta of #{group_delta}"
|
@@ -445,6 +458,36 @@ module NCEdit
|
|
445
458
|
updated
|
446
459
|
end
|
447
460
|
|
461
|
+
# process any rule changes separately since they are valid for all actions
|
462
|
+
# returns true if changes were made
|
463
|
+
def self.rule_change(group, rule, rule_mode)
|
464
|
+
rule_change = false
|
465
|
+
|
466
|
+
rule_modes = ['replace', 'append']
|
467
|
+
if rule and (! rule_modes.include?(rule_mode))
|
468
|
+
raise "Invalid rule mode '#{rule_mode}'. Allowed: #{rule_modes}"
|
469
|
+
end
|
470
|
+
|
471
|
+
if rule
|
472
|
+
begin
|
473
|
+
rule_json = JSON.parse(rule)
|
474
|
+
rescue JSON::ParserError
|
475
|
+
raise "Syntax error in data supplied to --rule (must be valid JSON)"
|
476
|
+
end
|
477
|
+
|
478
|
+
if rule_mode == 'replace'
|
479
|
+
if group['rule'] != rule_json
|
480
|
+
group['rule'] = rule_json
|
481
|
+
rule_change = true
|
482
|
+
end
|
483
|
+
else
|
484
|
+
rule_change = ensure_rules(group, rule_json)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
rule_change
|
489
|
+
end
|
490
|
+
|
448
491
|
def self.classes(options)
|
449
492
|
group_name = options[:group_name]
|
450
493
|
class_name = options[:class_name]
|
@@ -465,11 +508,6 @@ module NCEdit
|
|
465
508
|
raise "All operations require a valid group_name"
|
466
509
|
end
|
467
510
|
|
468
|
-
rule_modes = ['replace', 'append']
|
469
|
-
if rule and (! rule_modes.include?(rule_mode))
|
470
|
-
raise "Invalid rule mode '#{rule_mode}'. Allowed: #{rule_modes}"
|
471
|
-
end
|
472
|
-
|
473
511
|
if class_name and delete_class
|
474
512
|
# delete a class from a group
|
475
513
|
Escort::Logger.output.puts "Deleting class #{class_name} from #{group_name}"
|
@@ -501,22 +539,7 @@ module NCEdit
|
|
501
539
|
end
|
502
540
|
|
503
541
|
# process any rule changes separately since they are valid for all actions
|
504
|
-
|
505
|
-
begin
|
506
|
-
rule_json = JSON.parse(rule)
|
507
|
-
rescue JSON::ParserError
|
508
|
-
raise "Syntax error in data supplied to --rule (must be valid JSON)"
|
509
|
-
end
|
510
|
-
|
511
|
-
if rule_mode == 'replace'
|
512
|
-
if group['rule'] != rule_json
|
513
|
-
group['rule'] = rule_json
|
514
|
-
rule_change = true
|
515
|
-
end
|
516
|
-
else
|
517
|
-
rule_change = ensure_rules(group, rule_json)
|
518
|
-
end
|
519
|
-
end
|
542
|
+
rule_change = rule_change(group, rule, rule_mode)
|
520
543
|
|
521
544
|
# save changes
|
522
545
|
if class_change or rule_change
|
@@ -597,5 +620,31 @@ module NCEdit
|
|
597
620
|
# Return the found elements if there were any, otherwise simplify to false
|
598
621
|
! found.empty? ? found : false
|
599
622
|
end
|
623
|
+
|
624
|
+
def self.groups(options)
|
625
|
+
group_name = options[:group_name]
|
626
|
+
environment = options[:environment]
|
627
|
+
environment_trumps = options[:environment_trumps]
|
628
|
+
rule = options[:rule]
|
629
|
+
rule_mode = options[:rule_mode]
|
630
|
+
|
631
|
+
# step 1: create the group with the parent "All Environments"
|
632
|
+
nc_group(group_name, parent_name: "All Environments")
|
633
|
+
|
634
|
+
# step 2: set the environment + environment trumps
|
635
|
+
update_group(
|
636
|
+
group_name,
|
637
|
+
environment: environment,
|
638
|
+
environment_trumps: environment_trumps,
|
639
|
+
)
|
640
|
+
|
641
|
+
# step 3: set the rules - separate step because rule_mode needs special
|
642
|
+
# handling
|
643
|
+
group = nc_group(group_name)
|
644
|
+
rule_change = rule_change(group, rule, rule_mode)
|
645
|
+
if rule_change
|
646
|
+
update_group(group_name, rule: group["rule"])
|
647
|
+
end
|
648
|
+
end
|
600
649
|
end
|
601
650
|
end
|
data/lib/ncedit/version.rb
CHANGED
data/ncedit.gemspec
CHANGED
@@ -22,11 +22,11 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_development_dependency "bundler", "~> 2.
|
26
|
-
spec.add_development_dependency "rake", "~>
|
27
|
-
spec.add_development_dependency "rspec", "~> 3.
|
25
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
26
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
28
28
|
|
29
29
|
spec.add_runtime_dependency "escort", "0.4.0"
|
30
|
-
spec.add_runtime_dependency "json_pure", "2.
|
30
|
+
spec.add_runtime_dependency "json_pure", "2.3.0"
|
31
31
|
spec.add_runtime_dependency "puppetclassify", "0.1.8"
|
32
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ncedit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Declarative Systems
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.1'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
26
|
+
version: '2.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.9'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.9'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: escort
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - '='
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 2.
|
75
|
+
version: 2.3.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - '='
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.
|
82
|
+
version: 2.3.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: puppetclassify
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- ".travis.yml"
|
108
108
|
- Gemfile
|
109
109
|
- LICENSE
|
110
|
+
- Makefile
|
110
111
|
- README.md
|
111
112
|
- Rakefile
|
112
113
|
- bin/console
|
@@ -137,8 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
138
|
- !ruby/object:Gem::Version
|
138
139
|
version: '0'
|
139
140
|
requirements: []
|
140
|
-
|
141
|
-
rubygems_version: 2.7.6
|
141
|
+
rubygems_version: 3.0.3
|
142
142
|
signing_key:
|
143
143
|
specification_version: 4
|
144
144
|
summary: Edit Puppet Enterprise Node Classifier rules
|