alterant 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
![Alterant Logo](https://s3.amazonaws.com/cdn.cloud66.com/images/alterant_logo.png)
|
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
|