alterant 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/README.md +1 -7
- data/bin/alterant +5 -1
- data/lib/alterant/alterant.rb +10 -9
- data/lib/alterant/classes/finders.js +179 -0
- data/lib/alterant/version.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75ea4212fe9ff199e8d8b8447331ff908d2e5656b32761fd88faf017a837efc4
|
4
|
+
data.tar.gz: 55e19cf00b05ab47a58bcab3a46ce7cfbbd1b510c878b7d6ff53886d1cb37771
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '098f04bfe52130e4523d0bfd1e66489f1866aed4c8395926674f7ea8ffdea2c864ff0797eeda4839fb006b1fbdca6e5d4ed6e320ba40c8925c85a05a5ab596a9'
|
7
|
+
data.tar.gz: 7e8525ea905705450f4e8d320ddf1815eaacc47dd14adaf65a280f3089fac1909770152da2fac844e62aae897a8644bece4eb58a05726d7341d09538c25414a3
|
data/README.md
CHANGED
@@ -1,9 +1,3 @@
|
|
1
|
-

|
2
|
-
|
3
1
|
# Alterant
|
4
2
|
|
5
|
-
Alterant is a tool
|
6
|
-
|
7
|
-
```bash
|
8
|
-
alterant modify --in config.yml --out output.yml --modifier script.js
|
9
|
-
```
|
3
|
+
Alterant is a command line tool that lets you manipulate YAML and JSON files using simple Javascript files. This is useful when applying broad modifications to Kubernetes configuration files. For more information checkout [Alterant Website](https://help.cloud66.com/alterant/)
|
data/bin/alterant
CHANGED
@@ -32,6 +32,8 @@ module Alterant
|
|
32
32
|
option :diff, type: :boolean, default: false, desc: "Return the diff instead of the output itself"
|
33
33
|
option :debug, type: :boolean, default: false
|
34
34
|
option :input_format, type: :string, enum: ['yaml', 'json'], default: 'yaml', desc: "Input format if it's based on a stream and not a file"
|
35
|
+
option :mem, type: :numeric, default: 1048576, desc: 'Maximum memory allowed to the modifier in bytes'
|
36
|
+
option :timeout, type: :numeric, default: 500, desc: 'Timeout allowed for the modifier in milliseconds'
|
35
37
|
option :overwrite, type: :boolean, default: false
|
36
38
|
def modify
|
37
39
|
$debug = options[:debug] || false
|
@@ -39,6 +41,8 @@ module Alterant
|
|
39
41
|
diff = options[:diff]
|
40
42
|
output_format = options[:output_format]
|
41
43
|
input_format = options[:input_format]
|
44
|
+
max_mem = options[:mem]
|
45
|
+
timeout = options[:timeout]
|
42
46
|
|
43
47
|
in_file = options[:in]
|
44
48
|
if !in_file
|
@@ -121,7 +125,7 @@ module Alterant
|
|
121
125
|
|
122
126
|
run_context[:js_preload] = ::Alterant::Classes.LoadClasses
|
123
127
|
alter = ::Alterant::Alterant.new(input: data, modifier: modifier, filename: modifier_file, options: run_context)
|
124
|
-
results = alter.execute(timeout:
|
128
|
+
results = alter.execute(timeout: timeout, max_memory: max_mem)
|
125
129
|
|
126
130
|
if results.nil?
|
127
131
|
STDERR.puts "Aborting".red
|
data/lib/alterant/alterant.rb
CHANGED
@@ -22,22 +22,19 @@ module Alterant
|
|
22
22
|
snapshot = MiniRacer::Snapshot.new("$$ = #{@input.to_json};\n" + @js_preload.join("\n")) # this is more efficient but we lose debug info (filename) of helper classes
|
23
23
|
|
24
24
|
isolate = MiniRacer::Isolate.new(snapshot)
|
25
|
-
|
25
|
+
begin
|
26
26
|
ctx = ::MiniRacer::Context.new(isolate: isolate, timeout: timeout, max_memory: max_memory)
|
27
|
-
ctx.eval("$ = #{input.to_json}")
|
28
|
-
ctx.eval("$['fetch'] = function(key) { return jpath.fetch(JSON.stringify($), key); }")
|
29
27
|
ctx.attach('jpath.fetch', proc{|x, y| jpath.fetch(x, y)})
|
30
28
|
ctx.attach('console.log', proc{|x| STDERR.puts("DEBUG: #{x.inspect}") if $debug })
|
31
29
|
ctx.attach('console.exception', proc{|x| raise ::Alterant::RuntimeError, x })
|
32
|
-
ctx.
|
33
|
-
ctx.attach('$.index', proc{ idx })
|
30
|
+
ctx.eval('$$.replace = function(item) { replaceResource($$, item); } ', proc { |x| })
|
34
31
|
ctx.attach('YamlReader', ::Alterant::Classes::YamlReader.new(self, ctx))
|
35
32
|
ctx.attach('JsonReader', ::Alterant::Classes::JsonReader.new(self, ctx))
|
36
33
|
|
37
34
|
ctx.eval(@modifier, filename: @filename)
|
38
|
-
|
39
|
-
|
40
|
-
result
|
35
|
+
|
36
|
+
pre_convert = ctx.eval("JSON.stringify($$)")
|
37
|
+
result = JSON.parse(pre_convert)
|
41
38
|
|
42
39
|
ctx.dispose
|
43
40
|
isolate.idle_notification(100)
|
@@ -45,7 +42,11 @@ module Alterant
|
|
45
42
|
if $debug
|
46
43
|
raise
|
47
44
|
else
|
48
|
-
|
45
|
+
if defined? idx
|
46
|
+
raise ::Alterant::ParseError, "part: #{idx} - #{exc.message}, #{exc.backtrace.first}"
|
47
|
+
else
|
48
|
+
raise ::Alterant::ParseError, "#{exc.message}, #{exc.backtrace.first}"
|
49
|
+
end
|
49
50
|
end
|
50
51
|
rescue ::Alterant::AlterantError => exc
|
51
52
|
STDERR.puts exc.message.red
|
@@ -0,0 +1,179 @@
|
|
1
|
+
// finds the deployment that's used for a service given it's labels and service's selectors
|
2
|
+
function findDeploymentForService(list, selectors) {
|
3
|
+
return findByLabels(list, "Deployment", selectors);
|
4
|
+
}
|
5
|
+
|
6
|
+
function replaceResource(list, resource) {
|
7
|
+
replaceItem(list, resource.kind, resource.metadata.name, resource);
|
8
|
+
}
|
9
|
+
|
10
|
+
// replaces an item of the given kind and name with a replacement
|
11
|
+
function replaceItem(list, kind, name, replacement) {
|
12
|
+
for (let index = 0; index < list.length; index++) {
|
13
|
+
const element = list[index];
|
14
|
+
|
15
|
+
if ((element.kind == kind) && (element.metadata.name == name)) {
|
16
|
+
// found it.
|
17
|
+
list[index] = replacement;
|
18
|
+
return
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
function findByName(list, kind, name) {
|
24
|
+
var found;
|
25
|
+
list.forEach(resource => {
|
26
|
+
if ((resource.kind == kind) && (resource.metadata.name == name)) {
|
27
|
+
found = resource;
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
});
|
31
|
+
|
32
|
+
return found;
|
33
|
+
}
|
34
|
+
|
35
|
+
// finds an item using the labels and its kind
|
36
|
+
function findByLabels(list, kind, labels) {
|
37
|
+
var found;
|
38
|
+
list.forEach(element => {
|
39
|
+
if (element.kind == kind) {
|
40
|
+
if (doLabelsMatch(element, labels)) {
|
41
|
+
found = element;
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
});
|
46
|
+
|
47
|
+
return found;
|
48
|
+
}
|
49
|
+
|
50
|
+
// checks it two sets of labels (and selectors) match
|
51
|
+
function doLabelsMatch(item, labels) {
|
52
|
+
itemLabels = getLabels(item);
|
53
|
+
for (label in labels) {
|
54
|
+
if (labels[label] != itemLabels[label]) {
|
55
|
+
return false;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
return true;
|
60
|
+
}
|
61
|
+
|
62
|
+
function getLabels(item) {
|
63
|
+
return item.spec.template.metadata.labels;
|
64
|
+
}
|
65
|
+
|
66
|
+
function deepCompare () {
|
67
|
+
var i, l, leftChain, rightChain;
|
68
|
+
|
69
|
+
function compare2Objects (x, y) {
|
70
|
+
var p;
|
71
|
+
|
72
|
+
// remember that NaN === NaN returns false
|
73
|
+
// and isNaN(undefined) returns true
|
74
|
+
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
|
75
|
+
return true;
|
76
|
+
}
|
77
|
+
|
78
|
+
// Compare primitives and functions.
|
79
|
+
// Check if both arguments link to the same object.
|
80
|
+
// Especially useful on the step where we compare prototypes
|
81
|
+
if (x === y) {
|
82
|
+
return true;
|
83
|
+
}
|
84
|
+
|
85
|
+
// Works in case when functions are created in constructor.
|
86
|
+
// Comparing dates is a common scenario. Another built-ins?
|
87
|
+
// We can even handle functions passed across iframes
|
88
|
+
if ((typeof x === 'function' && typeof y === 'function') ||
|
89
|
+
(x instanceof Date && y instanceof Date) ||
|
90
|
+
(x instanceof RegExp && y instanceof RegExp) ||
|
91
|
+
(x instanceof String && y instanceof String) ||
|
92
|
+
(x instanceof Number && y instanceof Number)) {
|
93
|
+
return x.toString() === y.toString();
|
94
|
+
}
|
95
|
+
|
96
|
+
// At last checking prototypes as good as we can
|
97
|
+
if (!(x instanceof Object && y instanceof Object)) {
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
|
101
|
+
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
|
102
|
+
return false;
|
103
|
+
}
|
104
|
+
|
105
|
+
if (x.constructor !== y.constructor) {
|
106
|
+
return false;
|
107
|
+
}
|
108
|
+
|
109
|
+
if (x.prototype !== y.prototype) {
|
110
|
+
return false;
|
111
|
+
}
|
112
|
+
|
113
|
+
// Check for infinitive linking loops
|
114
|
+
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
|
115
|
+
return false;
|
116
|
+
}
|
117
|
+
|
118
|
+
// Quick checking of one object being a subset of another.
|
119
|
+
// todo: cache the structure of arguments[0] for performance
|
120
|
+
for (p in y) {
|
121
|
+
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
|
122
|
+
return false;
|
123
|
+
}
|
124
|
+
else if (typeof y[p] !== typeof x[p]) {
|
125
|
+
return false;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
for (p in x) {
|
130
|
+
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
|
131
|
+
return false;
|
132
|
+
}
|
133
|
+
else if (typeof y[p] !== typeof x[p]) {
|
134
|
+
return false;
|
135
|
+
}
|
136
|
+
|
137
|
+
switch (typeof (x[p])) {
|
138
|
+
case 'object':
|
139
|
+
case 'function':
|
140
|
+
|
141
|
+
leftChain.push(x);
|
142
|
+
rightChain.push(y);
|
143
|
+
|
144
|
+
if (!compare2Objects (x[p], y[p])) {
|
145
|
+
return false;
|
146
|
+
}
|
147
|
+
|
148
|
+
leftChain.pop();
|
149
|
+
rightChain.pop();
|
150
|
+
break;
|
151
|
+
|
152
|
+
default:
|
153
|
+
if (x[p] !== y[p]) {
|
154
|
+
return false;
|
155
|
+
}
|
156
|
+
break;
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
return true;
|
161
|
+
}
|
162
|
+
|
163
|
+
if (arguments.length < 1) {
|
164
|
+
return true; //Die silently? Don't know how to handle such case, please help...
|
165
|
+
// throw "Need two or more arguments to compare";
|
166
|
+
}
|
167
|
+
|
168
|
+
for (i = 1, l = arguments.length; i < l; i++) {
|
169
|
+
|
170
|
+
leftChain = []; //Todo: this can be cached
|
171
|
+
rightChain = [];
|
172
|
+
|
173
|
+
if (!compare2Objects(arguments[0], arguments[i])) {
|
174
|
+
return false;
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
return true;
|
179
|
+
}
|
data/lib/alterant/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alterant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khash Sajadi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -155,6 +155,7 @@ files:
|
|
155
155
|
- lib/alterant/classes/classes.rb
|
156
156
|
- lib/alterant/classes/containers.js
|
157
157
|
- lib/alterant/classes/docker_image.js
|
158
|
+
- lib/alterant/classes/finders.js
|
158
159
|
- lib/alterant/classes/json_reader.rb
|
159
160
|
- lib/alterant/classes/ports.js
|
160
161
|
- lib/alterant/classes/yaml_reader.rb
|