mantra 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +8 -2
  5. data/README.md +126 -16
  6. data/bin/mantra +17 -0
  7. data/ci/README.md +6 -0
  8. data/ci/docker/Dockerfile +20 -0
  9. data/ci/docker/build-docker-image +10 -0
  10. data/ci/pipeline.yml +42 -0
  11. data/ci/scripts/run-tests +3 -0
  12. data/ci/stub.example.yml +6 -0
  13. data/ci/stub.yml +33 -0
  14. data/ci/tasks/run-tests-dev.yml +10 -0
  15. data/ci/tasks/run-tests-stable.yml +13 -0
  16. data/lib/mantra/certificate.rb +35 -0
  17. data/lib/mantra/certificates/cortege.rb +64 -0
  18. data/lib/mantra/certificates/group.rb +26 -0
  19. data/lib/mantra/command.rb +51 -0
  20. data/lib/mantra/commands/find.rb +38 -0
  21. data/lib/mantra/commands/transform.rb +38 -0
  22. data/lib/mantra/helpers/object_with_type.rb +60 -0
  23. data/lib/mantra/helpers/regexp_helper.rb +12 -0
  24. data/lib/mantra/helpers/template_helper.rb +70 -0
  25. data/lib/mantra/manifest/array_element.rb +84 -0
  26. data/lib/mantra/manifest/element.rb +175 -0
  27. data/lib/mantra/manifest/ext.rb +33 -0
  28. data/lib/mantra/manifest/hash_element.rb +88 -0
  29. data/lib/mantra/manifest/leaf_element.rb +38 -0
  30. data/lib/mantra/manifest/root_element.rb +38 -0
  31. data/lib/mantra/manifest/scope/array_scope.rb +53 -0
  32. data/lib/mantra/manifest/scope/empty_scope.rb +24 -0
  33. data/lib/mantra/manifest/scope/hash_scope.rb +20 -0
  34. data/lib/mantra/manifest/scope/leaf_scope.rb +0 -0
  35. data/lib/mantra/manifest/scope.rb +94 -0
  36. data/lib/mantra/manifest.rb +47 -0
  37. data/lib/mantra/merge_tool/spiff.rb +23 -0
  38. data/lib/mantra/merge_tool.rb +13 -0
  39. data/lib/mantra/transform/extract.rb +10 -0
  40. data/lib/mantra/transform/extract_certificates.rb +18 -0
  41. data/lib/mantra/transform/extract_certificates_to_files.rb +12 -0
  42. data/lib/mantra/transform/extract_section.rb +10 -0
  43. data/lib/mantra/transform/inputs/any.rb +10 -0
  44. data/lib/mantra/transform/inputs/array.rb +16 -0
  45. data/lib/mantra/transform/inputs/file.rb +16 -0
  46. data/lib/mantra/transform/inputs/folder.rb +9 -0
  47. data/lib/mantra/transform/inputs/hash.rb +16 -0
  48. data/lib/mantra/transform/inputs/string.rb +9 -0
  49. data/lib/mantra/transform/merge.rb +26 -0
  50. data/lib/mantra/transform/replace.rb +34 -0
  51. data/lib/mantra/transform/templatize_ip_address.rb +129 -0
  52. data/lib/mantra/transform/templatize_value.rb +63 -0
  53. data/lib/mantra/transform.rb +118 -0
  54. data/lib/mantra/version.rb +1 -1
  55. data/lib/mantra.rb +9 -1
  56. data/mantra.gemspec +6 -5
  57. metadata +69 -8
  58. data/bin/console +0 -14
  59. data/bin/setup +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 993ccf8b86579e3bcf76e407de934c053bafd6d2
4
- data.tar.gz: d8904bfab735ac2ff3eafadbbe6ecaf457847c3d
3
+ metadata.gz: f071f30737a66c7b81b0b0100831abfe981a5032
4
+ data.tar.gz: 1c0015a38b4ecd69be8d38688bb6c8284d5ff6dc
5
5
  SHA512:
6
- metadata.gz: 7d32e81a7b46e059f15136db0665a0670b7b30fe31b39628b34a9a7ae9643a0c4617925bcb11543039a1297faf9e85b05b8e40cf4f8f56f4403c8b3eb0cc7770
7
- data.tar.gz: 06f8c0903e36c59a67f3dd71500ca5834d7890b44de7c0331bea02fc4ccb24644f447ccb3bae92003d551fa83e889769ad149c0c2822d1eabbb432be465ff515
6
+ metadata.gz: 5a85bda3e4389db1b75a9bfde752f5aa8185ad03fec4caadf8239c4bd4a266891167d57388fb1699b11fe2e5c154763642c97dfef51e712e6c66daada7e9af2b
7
+ data.tar.gz: fec5710aaed34e7961fe4a63ff405390bb416a57370bce2b44f9d5e4303e1fb3b492bbf0ed6bda5d56de342a7e4a4178497bdc6b048c3949240ae48dfd50e2d5
data/.gitignore CHANGED
@@ -7,3 +7,5 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ *.gem
11
+ .ruby-*
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --format documentation
2
2
  --color
3
+ --require spec_helper
data/.travis.yml CHANGED
@@ -1,4 +1,10 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.3.0
4
- before_install: gem install bundler -v 1.11.2
3
+ - 2.1.10
4
+ - 2.2.2
5
+ - 2.3.1
6
+ before_install:
7
+ - gem install bundler -v 1.11.2
8
+ - bundle install
9
+ script:
10
+ - "bundle exec rake"
data/README.md CHANGED
@@ -1,34 +1,144 @@
1
- # Mantra
1
+ # Mantra - मंत्र
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mantra`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Build Status](https://travis-ci.org/allomov/mantra.svg?branch=master)](https://travis-ci.org/allomov/mantra)
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ### Description
6
6
 
7
- ## Installation
7
+ Mantra (/ˈmæntrə/, abr. **Man**ifest **Tra**nsformation) is a tool to ease work with manifests.
8
+
9
+ It allows to do following:
10
+
11
+ * find manifest parts
12
+ * extract cloud config from you BOSH v1 manifest
13
+ * convert your manifest into spiff templates with
14
+ * extracted passwords
15
+ * extracted certificates to different files
16
+ * templatized network configuration
17
+ * extracted or changed properties
18
+ * and much more
19
+
20
+ Mantra is tend to be an easily extendable tool, so you can add new commands and transforms.
21
+
22
+ ### Concepts
23
+
24
+ While some actions performed on manifest can be automated, anther require special configuration and extra knowledges about source manifes. Here is a small glossery that I use:
25
+
26
+ `Transformation Manifest` - config file that describes how your manifest should be udpated
27
+ `Source Manifest` - your source BOSH manifest, if you run templatizers on source manifest they can change it.
28
+ `Target Manifest` - manifest that will contain extracted template properties, to restore source manifest you'll need to run merge tool with resulting source manifest.
29
+ `Transform` - a ruby class that declares how specific transformation should be done.
30
+
31
+ ### Examples
32
+
33
+ Find and output in json some manifest parts:
34
+
35
+ ```
36
+ mantra find jobs[name=consul].properties -m manifest.yml -f json
37
+ # alias: mantra f
38
+ ```
8
39
 
9
- Add this line to your application's Gemfile:
40
+ Transform BOSH v1 manifest to extract cloud config:
10
41
 
11
- ```ruby
12
- gem 'mantra'
42
+ ```
43
+ mantra transform -c transformation-manifest.yml -m manifest.yml
44
+ # mantra t
13
45
  ```
14
46
 
15
- And then execute:
47
+ Here is an example of `transformation-manifest.yml`:
48
+
49
+ ```yaml
50
+ global:
51
+ source: manifest.yml
52
+ target: cloud-config.yml
53
+ transforms:
54
+ - filter:
55
+ sections: ["networks", "compilation", "update", "resource_pools", "disk_pools"]
56
+ - rename:
57
+ section: "resource_pools"
58
+ to: "vm_types"
59
+ - rename:
60
+ section: "disk_pools"
61
+ to: "disk_types"
62
+ - type: add
63
+ section:
64
+ az: z1
65
+ to: "networks[].subnets[]"
66
+ - add:
67
+ section:
68
+ az: z1
69
+ to: "update"
70
+ - add:
71
+ section:
72
+ az: z1
73
+ to: "compilation"
74
+ - add:
75
+ section:
76
+ azs:
77
+ - name: z1
78
+ to: ""
79
+ ```
16
80
 
17
- $ bundle
18
81
 
19
- Or install it yourself as:
82
+ ```yaml
83
+ global_vars:
84
+ source: manifest.yml
85
+ transforms:
86
+ - extract:
87
+ section: jobs
88
+ to: workspace/jobs.yml
89
+ - extract-certs:
90
+ from: workspace/properties.yml
91
+ to: workspace/secrets.yml
92
+ - extract-certs-to-files:
93
+ from: workspace/secrets.yml
94
+ to: workspace/secrets
95
+ - extract:
96
+ section: jobs
97
+ to:
98
+ file: manifest.yml
99
+ with_scope: meta.jobs
100
+ - extract:
101
+ source: manifest.yml
102
+ section: resource_pools
103
+ - extract:
104
+ section: resource_pools
105
+ to: resource_pools.yml
106
+ - extract:
107
+ section: networks
108
+ to: networks.yml
109
+ - templatize-ip-address:
110
+ from: networks.yml
111
+ to: workspace/stub.yml
112
+ quads:
113
+ - range: "1-2"
114
+ scope: meta.networks.cf.prefix
115
+ with_value: "192.168"
116
+ - number: 3
117
+ scope: meta.networks.cf.quad1
118
+ with_value: 2
119
+ - number: 3
120
+ scope: meta.networks.cf.quad2
121
+ with_value: 3
122
+ - templatize-value:
123
+ source: manifest.yml
124
+ to: workspace/stub.yml
125
+ value: cfdomain.com
126
+ in: "*.cfdomain.com"
127
+ scope: meta.domain
128
+ ```
20
129
 
21
- $ gem install mantra
22
130
 
23
- ## Usage
131
+ ## Installation
24
132
 
25
- TODO: Write usage instructions here
133
+ Install it as a gem:
26
134
 
27
- ## Development
135
+ ```
136
+ $ gem install mantra
137
+ ```
28
138
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
139
+ ## Dependencies
30
140
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
141
+ `openssl`!
32
142
 
33
143
  ## Contributing
34
144
 
data/bin/mantra ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
4
+ require "mantra"
5
+
6
+ if ARGV.empty?
7
+ puts Mantra::Command.usage
8
+ exit 0
9
+ end
10
+
11
+ command_type = ARGV.shift
12
+ options = {type: command_type.to_sym, args: ARGV}
13
+
14
+ command = Mantra::Command.create(options)
15
+
16
+ command.run
17
+
data/ci/README.md ADDED
@@ -0,0 +1,6 @@
1
+ ### How to use
2
+
3
+ ```
4
+ fly set-pipeline -t tutorial -c pipeline.yml --load-vars-from stub.yml -p merrill-manifest-generator
5
+ fly unpause-pipeline -p merrill-manifest-generator
6
+ ```
@@ -0,0 +1,20 @@
1
+ FROM ruby:2.3.0
2
+ MAINTAINER Alex Lomov <lomov.as@gmail.com>
3
+ # should go to allomov/ruby#manifest-generator
4
+
5
+ RUN apt-get -y update --fix-missing
6
+ RUN apt-get -y install git git-core curl gawk g++ gcc make libc6-dev libreadline6-dev \
7
+ zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 autoconf \
8
+ libgdbm-dev libncurses5-dev automake libtool bison pkg-config libffi-dev
9
+
10
+ RUN apt-get install -y postgresql postgresql-contrib postgresql-client libpq5 libpq-dev
11
+
12
+ RUN apt-get install -y nodejs npm cmake
13
+ RUN ln -s /usr/bin/nodejs /usr/bin/node
14
+
15
+ RUN gem install bundler --no-ri --no-rdoc
16
+
17
+ COPY manifest-generator /manifest-generator
18
+
19
+ WORKDIR /manifest-generator
20
+ RUN bundle install
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+
3
+ cp Dockerfile ../../../Dockerfile
4
+
5
+ pushd ../../..
6
+ docker build -t allomov/ruby:manifest-generator .
7
+ docker push allomov/ruby:manifest-generator
8
+ popd
9
+
10
+ rm ../../../Dockerfile
data/ci/pipeline.yml ADDED
@@ -0,0 +1,42 @@
1
+ ---
2
+ resources:
3
+ - name: merrill-manifest-generator-dev
4
+ type: git
5
+ source:
6
+ uri: {{github-repo}}
7
+ branch: manifest-generator-dev
8
+ private_key: {{git-repo-private-key}}
9
+ - name: slack-notification
10
+ type: slack-notification
11
+ source:
12
+ url: {{slack-notification-url}}
13
+
14
+ jobs:
15
+ - name: dev-version
16
+ plan:
17
+ - get: merrill-manifest-generator-dev
18
+ trigger: true
19
+ - task: run-tests
20
+ file: merrill-manifest-generator-dev/manifest-generator/ci/tasks/run-tests-dev.yml
21
+ on_failure:
22
+ do:
23
+ - put: slack-notification
24
+ params:
25
+ channel: {{slack-channel}}
26
+ username: {{slack-username}}
27
+ icon_emoji: ":robot_face:"
28
+ text: "@here dev version of manifest-generator seems to be broken"
29
+ - name: stable-version
30
+ plan:
31
+ - get: merrill-manifest-generator-stable
32
+ trigger: true
33
+ - task: run-tests
34
+ file: merrill-manifest-generator-stable/manifest-generator/ci/tasks/run-tests-stable.yml
35
+ on_failure:
36
+ do:
37
+ - put: slack-notification
38
+ params:
39
+ channel: {{slack-channel}}
40
+ username: {{slack-username}}
41
+ icon_emoji: ":robot_face:"
42
+ text: "@here stable version of manifest-generator seems to be broken"
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+
3
+ bundle exec rake
@@ -0,0 +1,6 @@
1
+ slack-notification-url: "https://https://hooks.slack.com/services/XXXXXX/XXXXXX/ID"
2
+ slack-channel: "#general"
3
+ slack-username: "Merrill-Manifest-Generator-Bot"
4
+ github-repo: git@github.com:pivotalservices/merrill.git
5
+ git-repo-private-key: |
6
+ Your private key here
data/ci/stub.yml ADDED
@@ -0,0 +1,33 @@
1
+ ---
2
+ slack-notification-url: "https://hooks.slack.com/services/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"
3
+ slack-channel: "#general"
4
+ slack-username: "Merrill-Manifest-Generator-Bot"
5
+ github-repo: git@github.com:pivotalservices/merrill.git
6
+ git-repo-private-key: |
7
+ -----BEGIN RSA PRIVATE KEY-----
8
+ MIIEogIBAAKCAQEAz/SJ469kiOr3CysK7Tqp1ZQPYFviObH6N4ucmAiWb78KxqM+
9
+ BBMEsmdo/2Pe0CKfiMGW14LA4JlpQIguuNixUiSffBo7zlfxigm8MpgdF3i7kqOv
10
+ Ffv+zOpLfq1i0rRz+cV9RsowRxbRkWekiy0YqDqVW4pyzfXIMd81dhjQh25w6Zs+
11
+ PFyAlg9bU7QUl0F9vljqpHii0n7hCL2hcKN7Jq0XF4AHPyQg24UgagU955wvlWvx
12
+ iJZ4fRcG1bSNTCJvParS7Pl/wnCC73WJ0d8MMOVHbk3G0lYPtbaCwUctZ47MjB4f
13
+ j6+40sfkfoJZQ6eb43AHnCZVypS652hcKGiLpQIDAQABAoIBAGdKZ1MYQy9exeZe
14
+ MscyZDkZmama+fr+U/JS/izl1xMaKRgQ7TTI3YRfqN9xk7J+AA/FWE8jOvpUONs8
15
+ yTg3KZxLZIwX26zaMbcGrtvSgmCuLzze4JBi4mSV23nIVVWjHBfr6BXJR8GHrAA1
16
+ Ip2egKjOsHEPi4aRliZvX/aQzML3SxcpttyxaRT5ytokMSjNSNRk2fTdcCliLbnD
17
+ +UOsGwWiZpC1BDZXHeKsnyGLgK5cgG4Pygnr0gDZY73wflnGHWFBQhIaLfdZdBb6
18
+ zXyYD6XGM3p+SUOL0JxWLFCMLWntpzn0LRx3RBmicXiW82dLrjVo1nQw9+TtMOv3
19
+ kWrO9OECgYEA6FpU0AngbKDnWAjG0peYrIKFgF/9Gk60JCQsXkHyNJ/mVt4sjFtG
20
+ y5Ajh6QxKReF1Be+W7di2CH9/Sb0xYdeiFAWtqNeBEOMOZYAV22zoFAb97SIlSrT
21
+ oZSquzY6jXldZU1lH0Pknklmz8Y4jcRSHvUKDXlr2MHvXMP7RIHKvTcCgYEA5R6O
22
+ m/LgMVn8ahB8jTSVPO41Ely1oH6dUghaQEqFf0MJmKBKESq+SHId8wHD9Sbuirg/
23
+ /KtYBe0ouvtIddX4AIoO5NVOudUGzLZEBntHUnpAln/P3COJkd0LdbN/5okguMkb
24
+ uMHJdqL/OWAUGOVzpM+DxK53c70r1VpIr3IETAMCgYAVP1VsJMsSA/DD2yGbVmOO
25
+ uuzMXXq+sh3FBE3OXMdySoD8xppaR2qE6Oxm1fvs3wrM51Lv/igazZj1Ul+lxIg/
26
+ fNtm3i+VwjuLdI0ZcZ2wdkLodujagy0RJJAsSHw4PbXtspMhtcqtMtck/uJjDGXa
27
+ ENxXeRgEnU9vMzjB/gB1JwKBgDIttAvhcEo+q/JKtAx01K5oeQURetGwiSHbJHDq
28
+ ITyS4PolOLNzygKxw29iFpmNMjb9TT44BGof24i/2cm817i+g66ILNq0Fe4liNZm
29
+ j2M31Qdg7JQI0Gs6nvTjIALMS3dMzB51inrKDd1x9lTRg7c3n2Mm1pBpgL0ULdEG
30
+ xnwjAoGAD+S5jsF2m0amYbR3pUwWFHmThXhB+ud6Sx8WVt4lL4zPA0doh8yTrt0h
31
+ srNaVWjGC6DHW2u4f1ArkGB3Csi/RtYFGV06V2j9Z5vgEf/1BCW0peiLqsiUQfRo
32
+ zsZ7pCigQzaSJDYjkvUXibgXHK7cuZ+D6CdQVy1QGuxWsP4lzc0=
33
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,10 @@
1
+ ---
2
+ platform: linux
3
+ image_resource:
4
+ type: docker-image
5
+ source: {repository: "allomov/ruby", tag: "manifest-generator"}
6
+ inputs:
7
+ - name: merrill-manifest-generator-dev
8
+ run:
9
+ path: ci/scripts/run-tests
10
+ dir: merrill-manifest-generator-dev/manifest-generator
@@ -0,0 +1,13 @@
1
+ ---
2
+ platform: linux
3
+ image_resource:
4
+ type: docker-image
5
+ source: {repository: "allomov/ruby", tag: "manifest-generator"}
6
+ inputs:
7
+ - name: merrill-manifest-generator-stable
8
+ run:
9
+ # path: ci/scripts/run-tests
10
+ # dir: merrill-manifest-generator-stable/manifest-generator
11
+ path: bash
12
+ args:
13
+ - "ci/scripts/run-tests"
@@ -0,0 +1,35 @@
1
+ module Mantra
2
+ module Certificate
3
+ class DigitalCertificate
4
+ TEMPLATE_MESSAGE = "Difital Certificate from file:"
5
+ attr_accessor :path, :type, :value
6
+ def initialize(options)
7
+ self.path = options[:path]
8
+ self.type = options[:type].strip
9
+ self.value = options[:value].strip
10
+ end
11
+
12
+ def private_key?
13
+ self.type.include? "PRIVATE KEY"
14
+ end
15
+
16
+ def public_key?
17
+ self.type == "PUBLIC KEY"
18
+ end
19
+
20
+ def certificate?
21
+ self.type == "CERTIFICATE"
22
+ end
23
+
24
+ def scope
25
+ self.path.to_scope
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+ # require "mantra/certificates/string_ext"
33
+ require "mantra/certificates/cortege"
34
+ require "mantra/certificates/group"
35
+ # require "mantra/certificates"
@@ -0,0 +1,64 @@
1
+ require "tempfile"
2
+
3
+ module Mantra
4
+ class Certificates
5
+ class Cortege
6
+
7
+ attr_accessor :public_key, :private_key, :certificate
8
+ def initialize(options)
9
+ self.public_key = options[:public_key]
10
+ self.private_key = options[:private_key]
11
+ self.certificate = options[:certificate]
12
+ end
13
+
14
+ def matches?
15
+ if self.has_private_key? && self.has_certificate?
16
+ return private_key_matches_certificate?
17
+ elsif self.has_private_key? && self.has_public_key?
18
+ return private_key_matches_public_key?
19
+ else
20
+ puts "Warning: don't know what to do with following certificate cortege #{self.inspect}"
21
+ return false
22
+ end
23
+ end
24
+
25
+ def has_certificate?
26
+ !!self.certificate
27
+ end
28
+
29
+ def has_public_key?
30
+ !!self.public_key
31
+ end
32
+
33
+ def has_private_key?
34
+ !!self.private_key
35
+ end
36
+
37
+ private
38
+
39
+ # https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs
40
+ # https://www.sslshopper.com/article-most-common-openssl-commands.html
41
+ # TODO: find out if there are ruby wrappers for this calls
42
+ def private_key_matches_certificate?
43
+ private_key_file_path = temp_file_wrapper(self.private_key.value, "domain.key")
44
+ certificate_file_path = temp_file_wrapper(self.certificate.value, "domain.crt")
45
+ private_key_md5 = `openssl rsa -noout -modulus -in #{private_key_file_path} 2> /dev/null | openssl md5`
46
+ certificate_md5 = `openssl x509 -noout -modulus -in #{certificate_file_path} 2> /dev/null | openssl md5`
47
+ private_key_md5 == certificate_md5
48
+ end
49
+
50
+ def private_key_matches_public_key?
51
+ private_key_file_path = temp_file_wrapper(self.private_key.value, "domain.key")
52
+ private_key_public_key = `openssl rsa -in #{private_key_file_path} -pubout 2> /dev/null`
53
+ private_key_public_key.strip == self.public_key.value
54
+ end
55
+
56
+ def temp_file_wrapper(string, filename)
57
+ file = Tempfile.new(filename)
58
+ file.write(string)
59
+ file.close
60
+ file.path
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,26 @@
1
+ require "forwardable"
2
+
3
+ # this class acts as it was simple DigitalCertificate
4
+ module Mantra
5
+ class Certificates
6
+ class Group
7
+ extend Forwardable
8
+
9
+ attr_accessor :certificates
10
+ alias_method :collection, :certificates
11
+
12
+ def_delegators :@certificates, :sample
13
+ def_delegators :sample, :certificate?, :public_key?, :private_key?, :value
14
+
15
+
16
+ def initialize(certificate_list)
17
+ self.certificates = certificate_list
18
+ end
19
+
20
+ def private_keys
21
+ self.certificates.select { |c| c.private_key? }
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ require "optparse"
2
+
3
+ module Mantra
4
+ class Command
5
+ include Helpers::ObjectWithType
6
+
7
+ def self.option_descriptors
8
+ @options ||= []
9
+ end
10
+
11
+ def self.usage
12
+ "\n\tUsage: \tmantra <action> [options]\n" +
13
+ "\tactions:\t#{self.subclasses.map { |s| s.type }.join(", ")}\n\n"
14
+ end
15
+
16
+ def self.option(name, long_option, short_option, description)
17
+ self.option_descriptors << [name, long_option, short_option, description]
18
+ self.send(:define_method, name) do
19
+ @options[name.to_s]
20
+ end
21
+ end
22
+
23
+ def run
24
+ parse_options
25
+ perform
26
+ end
27
+
28
+ def initialize(options)
29
+ @args = options[:args]
30
+ end
31
+
32
+ attr_accessor :options
33
+ def parse_options
34
+ @options = {}
35
+ OptionParser.new do |options_parser|
36
+ options_parser.banner = "Usage: mantra #{} [options]"
37
+ self.class.option_descriptors.each do |option|
38
+ option_name = option.shift.to_s
39
+ options_parser.on(*option) do |value|
40
+ @options[option_name] = value
41
+ end
42
+ end
43
+ end.parse!
44
+ @options
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+ require "mantra/commands/find"
51
+ require "mantra/commands/transform"
@@ -0,0 +1,38 @@
1
+ require "yaml"
2
+ require "json"
3
+
4
+ module Mantra
5
+ class Commands
6
+ class Find < Command
7
+ type :find
8
+ alias_type :f
9
+ option :scope, "--scope scope-path", "-s scope", "path scope you want to find"
10
+ option :manifest, "--manifest manifest-file", "-m manifest-file", "manifest"
11
+ option :format, "--format format", "-f format", "format (yaml or json)"
12
+ option :with_parent, "--with-parent", "-p", "format (yaml or json)"
13
+
14
+ def perform
15
+ m = Manifest.new(manifest)
16
+ results = m.select(scope)
17
+
18
+ results = results.map do |element|
19
+ element.parent
20
+ end if with_parent
21
+
22
+ results = results.map do |element|
23
+ element.to_ruby_object
24
+ end
25
+
26
+ case format
27
+ when "yaml", "yml", "y", nil
28
+ puts results.to_yaml
29
+ when "json", "j"
30
+ puts JSON.pretty_generate(results)
31
+ else
32
+ raise "unknown format"
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require "yaml"
2
+
3
+ module Mantra
4
+ class Commands
5
+ class Transform < Command
6
+ type :transform
7
+ alias_type :t
8
+ attr_accessor :manifest
9
+
10
+ option :transform_config_path, "--config CONFIG", "-c", "Transformation config path"
11
+ option :manifest_path, "--manifest MANIFEST", "-m", "Manifest path"
12
+
13
+ def transform_config
14
+ @transform_config ||= YAML.load_file(transform_config_path)
15
+ end
16
+
17
+ def transforms
18
+ previous_transform = self
19
+ transform_config["transforms"].map do |t|
20
+ t.merge!(previous_transform: previous_transform)
21
+ previous_transform = Mantra::Transform.create(t)
22
+ end
23
+ end
24
+
25
+ def manifest
26
+ @manifest ||= Manifest.new(self.manifest_path)
27
+ end
28
+
29
+ def perform
30
+ transforms.each do |t|
31
+ t.run
32
+ end
33
+ puts manifest.to_ruby_object.to_yaml
34
+ end
35
+
36
+ end
37
+ end
38
+ end