ccs 0.2.0 → 3.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.
- checksums.yaml +5 -5
- data/CODE_OF_CONDUCT.md +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +55 -3
- data/exe/ccs +84 -0
- data/lib/ccs.rb +9 -4
- data/lib/ccs/commands/copy.rb +36 -0
- data/lib/ccs/decrypter.rb +3 -1
- data/lib/ccs/document.rb +25 -0
- data/lib/ccs/downloader.rb +20 -15
- data/lib/ccs/encrypter.rb +26 -0
- data/lib/ccs/uploader.rb +46 -0
- data/lib/ccs/version.rb +3 -1
- metadata +94 -20
- data/bin/ccs +0 -57
- data/lib/ccs/configuration_file.rb +0 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ddc7a13cb4e185260a511ead10fd9f75387fecdd42a4138d19e0a0de35cd9caf
|
|
4
|
+
data.tar.gz: 8c99aa2c31cbd7a66bb1023f8b32872478691268b475b80f9bf6c203ebb978a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6c8f8bff758c7917bee0a1f779f5a97594c863d19ae96a673b8ca630cfe0189649d326130c44b622799ce489b9486492c1bf9fb74ee38c6e998167f29a7cb8a5
|
|
7
|
+
data.tar.gz: 0ac4cd8805f4addd47e7b224a7eff2a7fab360856294aed60444846946d9563c294d415bdbba9f72da3d7fe2f966b1cec18d5f51b97fc615e6a0da49d6da8d94
|
data/CODE_OF_CONDUCT.md
CHANGED
|
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|
|
55
55
|
## Enforcement
|
|
56
56
|
|
|
57
57
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
-
reported by contacting the project team at
|
|
58
|
+
reported by contacting the project team at me@tkowalewski.pl. All
|
|
59
59
|
complaints will be reviewed and investigated and will result in a response that
|
|
60
60
|
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
61
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# CCS
|
|
2
2
|
|
|
3
|
+
Configuration control system
|
|
3
4
|
|
|
4
5
|
## Installation
|
|
5
6
|
|
|
@@ -19,17 +20,68 @@ Or install it yourself as:
|
|
|
19
20
|
|
|
20
21
|
## Usage
|
|
21
22
|
|
|
23
|
+
ccs cp [OPTIONS] <(LocalPath|STDIN)|(CCSUri|Uri)> <(CCSUri|Uri)|(LocalPath|STDOUT)>
|
|
24
|
+
|
|
25
|
+
Options:
|
|
26
|
+
-a CCS_ACCESS_TOKEN, CCS Access Token
|
|
27
|
+
--access-token
|
|
28
|
+
-p CCS_PASSPHRASE, CCS Passphrase
|
|
29
|
+
--passphrase
|
|
30
|
+
|
|
31
|
+
|
|
22
32
|
## Example
|
|
23
33
|
|
|
34
|
+
Download to STDOUT
|
|
35
|
+
|
|
36
|
+
ccs cp ccs://workspace-name/0.1.0/path/to/file.yml -
|
|
37
|
+
ccs cp http://host.tld:9292/workspace-name/0.1.0/path/to/file.yml -
|
|
38
|
+
ccs cp https://host.tld/workspace-name/0.1.0/path/to/file.yml -
|
|
39
|
+
|
|
40
|
+
Download to local file
|
|
41
|
+
|
|
42
|
+
ccs cp ccs://workspace-name/0.1.0/path/to/file.yml /local/path/to/file.yml
|
|
43
|
+
|
|
44
|
+
Upload local file
|
|
45
|
+
|
|
46
|
+
ccs cp /local/path/to/file.yml ccs://workspace-name/0.1.0/path/to/file.yml
|
|
47
|
+
|
|
48
|
+
Upload content from STDIN
|
|
49
|
+
|
|
50
|
+
echo "{ a: 1 }" | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml
|
|
51
|
+
cat /local/path/to/file.yml | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
Upload
|
|
56
|
+
|
|
57
|
+
require 'ccs'
|
|
58
|
+
|
|
59
|
+
destination = 'ccs://workspace-name/0.1.0/path/to/file.yml'
|
|
60
|
+
access_token = ENV.fetch('CCS_ACCESS_TOKEN')
|
|
61
|
+
passphrase = 'MyPassphrase'
|
|
62
|
+
content = 'RAILS_ENV=production'
|
|
63
|
+
|
|
64
|
+
Ccs::Document.new(destination, access_token, passphrase).upload(content)
|
|
65
|
+
|
|
66
|
+
Download
|
|
67
|
+
|
|
68
|
+
require 'ccs'
|
|
69
|
+
|
|
70
|
+
source = 'ccs://workspace-name/0.1.0/path/to/file.yml'
|
|
71
|
+
access_token = ENV.fetch('CCS_ACCESS_TOKEN')
|
|
72
|
+
passphrase = 'MyPassphrase'
|
|
73
|
+
|
|
74
|
+
Ccs::Document.new(source, access_token, passphrase).download
|
|
75
|
+
|
|
24
76
|
## Development
|
|
25
77
|
|
|
26
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `
|
|
78
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
27
79
|
|
|
28
|
-
To install this gem onto your local machine, run `
|
|
80
|
+
To install this gem onto your local machine, run `bin/rake install`. To release a new version, update the version number in `version.rb`, and then run `bin/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).
|
|
29
81
|
|
|
30
82
|
## Contributing
|
|
31
83
|
|
|
32
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
|
84
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/occson/ccs. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
33
85
|
|
|
34
86
|
|
|
35
87
|
## License
|
data/exe/ccs
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'ccs'
|
|
6
|
+
require 'yaml'
|
|
7
|
+
require 'optparse'
|
|
8
|
+
require 'io/console'
|
|
9
|
+
|
|
10
|
+
options = {
|
|
11
|
+
'access_token' => ENV['CCS_ACCESS_TOKEN'],
|
|
12
|
+
'passphrase' => ENV['CCS_PASSPHRASE']
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
option_parser = OptionParser.new do |option_parser|
|
|
16
|
+
option_parser.banner = 'Usage: ccs [COMMAND [OPTIONS]]'
|
|
17
|
+
|
|
18
|
+
option_parser.separator ''
|
|
19
|
+
option_parser.separator 'Configuration Control System (CCS)'
|
|
20
|
+
option_parser.separator ''
|
|
21
|
+
option_parser.separator 'Commands:'
|
|
22
|
+
option_parser.separator ' cp Copy'
|
|
23
|
+
|
|
24
|
+
option_parser.separator ''
|
|
25
|
+
option_parser.separator format('Version: %<version>s', version: Ccs::VERSION)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
case ARGV.shift
|
|
29
|
+
when 'cp'
|
|
30
|
+
option_parser = OptionParser.new do |option_parser|
|
|
31
|
+
option_parser.banner = 'Usage: ccs cp [OPTIONS] <(LocalPath|STDIN)|(CCSUri|Uri)> <(CCSUri|Uri)|(LocalPath|STDOUT)>'
|
|
32
|
+
option_parser.separator ''
|
|
33
|
+
option_parser.separator 'Configuration Control System (CCS) - Copy'
|
|
34
|
+
option_parser.separator ''
|
|
35
|
+
option_parser.separator 'Options:'
|
|
36
|
+
|
|
37
|
+
option_parser.on('-a CCS_ACCESS_TOKEN', '--access-token CCS_ACCESS_TOKEN', String, 'CCS Access Token') do |v|
|
|
38
|
+
options['access_token'] = v
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
option_parser.on('-p CCS_PASSPHRASE', '--passphrase CCS_PASSPHRASE', String, 'CCS Passphrase') do |v|
|
|
42
|
+
options['passphrase'] = v
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
option_parser.separator ''
|
|
46
|
+
option_parser.separator 'Configure via environment variables:'
|
|
47
|
+
option_parser.separator ' CCS_ACCESS_TOKEN'
|
|
48
|
+
option_parser.separator ' CCS_PASSPHRASE'
|
|
49
|
+
|
|
50
|
+
option_parser.separator ''
|
|
51
|
+
option_parser.separator 'Examples:'
|
|
52
|
+
option_parser.separator ' Download to STDOUT'
|
|
53
|
+
option_parser.separator ' ccs cp ccs://workspace-name/0.1.0/path/to/file.yml -'
|
|
54
|
+
option_parser.separator ' ccs cp http://host.tld:9292/workspace-name/0.1.0/path/to/file.yml -'
|
|
55
|
+
option_parser.separator ' ccs cp https://host.tld/workspace-name/0.1.0/path/to/file.yml -'
|
|
56
|
+
option_parser.separator ' Download to local file'
|
|
57
|
+
option_parser.separator ' ccs cp ccs://workspace-name/0.1.0/path/to/file.yml /local/path/to/file.yml'
|
|
58
|
+
option_parser.separator ' Upload local file'
|
|
59
|
+
option_parser.separator ' ccs cp /local/path/to/file.yml ccs://workspace-name/0.1.0/path/to/file.yml'
|
|
60
|
+
option_parser.separator ' Upload content from STDIN'
|
|
61
|
+
option_parser.separator ' echo "{ a: 1 }" | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml'
|
|
62
|
+
option_parser.separator ' cat /local/path/to/file.yml | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml'
|
|
63
|
+
option_parser.separator ''
|
|
64
|
+
|
|
65
|
+
option_parser.separator format('Version: %<version>s', version: Ccs::VERSION)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
arguments = option_parser.parse!
|
|
69
|
+
|
|
70
|
+
unless options.values.any?
|
|
71
|
+
puts option_parser
|
|
72
|
+
exit(1)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
raise OptionParser::MissingArgument, 'access_token' unless options['access_token']
|
|
76
|
+
raise OptionParser::MissingArgument, 'passphrase' unless options['passphrase']
|
|
77
|
+
raise OptionParser::MissingArgument, 'source' unless arguments.fetch(0, nil)
|
|
78
|
+
raise OptionParser::MissingArgument, 'destination' unless arguments.fetch(1, nil)
|
|
79
|
+
|
|
80
|
+
exit(1) unless Ccs::Commands::Copy.new(arguments[0], arguments[1], options['access_token'], options['passphrase']).call
|
|
81
|
+
else
|
|
82
|
+
puts option_parser
|
|
83
|
+
exit(1)
|
|
84
|
+
end
|
data/lib/ccs.rb
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'net/http'
|
|
2
4
|
require 'json'
|
|
3
5
|
require 'openssl'
|
|
4
6
|
require 'base64'
|
|
7
|
+
require 'uri'
|
|
5
8
|
|
|
6
9
|
require 'ccs/version'
|
|
7
|
-
require 'ccs/
|
|
10
|
+
require 'ccs/encrypter'
|
|
8
11
|
require 'ccs/decrypter'
|
|
9
|
-
require 'ccs/
|
|
12
|
+
require 'ccs/uploader'
|
|
13
|
+
require 'ccs/downloader'
|
|
14
|
+
require 'ccs/document'
|
|
15
|
+
require 'ccs/commands/copy'
|
|
10
16
|
|
|
11
|
-
module Ccs
|
|
12
|
-
end
|
|
17
|
+
module Ccs; end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ccs
|
|
4
|
+
module Commands
|
|
5
|
+
class Copy
|
|
6
|
+
def initialize(source, destination, access_token, passphrase)
|
|
7
|
+
@source = source
|
|
8
|
+
@destination = destination
|
|
9
|
+
@access_token = access_token
|
|
10
|
+
@passphrase = passphrase
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call
|
|
14
|
+
download? ? download : upload
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def download?
|
|
20
|
+
@source.match?(%r{\A(ccs|https?):\/\/})
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def download
|
|
24
|
+
content = Document.new(@source, @access_token, @passphrase).download
|
|
25
|
+
return unless content
|
|
26
|
+
|
|
27
|
+
(@destination.eql?('-') ? STDOUT : File.new(@destination, 'w')).print content
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def upload
|
|
31
|
+
content = @source.eql?('-') ? STDIN.read : File.read(@source)
|
|
32
|
+
Document.new(@destination, @access_token, @passphrase).upload(content)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/ccs/decrypter.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Ccs
|
|
2
4
|
class Decrypter
|
|
3
5
|
def initialize(passphrase, content)
|
|
@@ -5,7 +7,7 @@ module Ccs
|
|
|
5
7
|
@content = content
|
|
6
8
|
end
|
|
7
9
|
|
|
8
|
-
def
|
|
10
|
+
def call
|
|
9
11
|
decryptor.pkcs5_keyivgen(@passphrase, ciphertext_salt, 1)
|
|
10
12
|
result = decryptor.update(encrypted)
|
|
11
13
|
result << decryptor.final
|
data/lib/ccs/document.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ccs
|
|
4
|
+
class Document
|
|
5
|
+
def initialize(uri, access_token, passphrase)
|
|
6
|
+
@uri = build_uri(uri)
|
|
7
|
+
@access_token = access_token
|
|
8
|
+
@passphrase = passphrase
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def upload(content)
|
|
12
|
+
Uploader.new(@uri, content, @access_token, @passphrase).call
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def download
|
|
16
|
+
Downloader.new(@uri, @access_token, @passphrase).call
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def build_uri(uri)
|
|
22
|
+
URI uri.sub('ccs://', 'https://api.occson.com/')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/ccs/downloader.rb
CHANGED
|
@@ -1,36 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Ccs
|
|
2
4
|
class Downloader
|
|
3
|
-
def initialize(
|
|
4
|
-
@
|
|
5
|
-
@
|
|
5
|
+
def initialize(uri, access_token, passphrase)
|
|
6
|
+
@uri = uri
|
|
7
|
+
@access_token = access_token
|
|
8
|
+
@passphrase = passphrase
|
|
6
9
|
end
|
|
7
10
|
|
|
8
|
-
def
|
|
11
|
+
def call
|
|
9
12
|
response = http.request(request)
|
|
13
|
+
body = response.body
|
|
14
|
+
return unless response.code.eql? '200'
|
|
15
|
+
json = JSON.parse body
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
JSON.parse(response.body)
|
|
17
|
+
Decrypter.new(@passphrase, json['encrypted_content']).call
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
private
|
|
17
21
|
|
|
18
|
-
def uri
|
|
19
|
-
@uri ||= URI format('https://pipello.io/api/v1/ccs/%s/%s', @configuration_file.version, @configuration_file.path)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
22
|
def http
|
|
23
|
-
Net::HTTP.new(uri.host, uri.port).tap do |http|
|
|
24
|
-
http.use_ssl = uri.scheme
|
|
23
|
+
@http ||= Net::HTTP.new(@uri.host, @uri.port).tap do |http|
|
|
24
|
+
http.use_ssl = @uri.scheme.eql?('https')
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def request
|
|
29
|
-
Net::HTTP::Get.new(uri.path, headers)
|
|
29
|
+
Net::HTTP::Get.new(@uri.path, headers).tap do |request|
|
|
30
|
+
request["User-Agent"] = format('ccs/%s', Ccs::VERSION)
|
|
31
|
+
end
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def headers
|
|
33
|
-
{
|
|
35
|
+
{
|
|
36
|
+
'Authorization' => format('Token token=%<access_token>s', access_token: @access_token),
|
|
37
|
+
'Content-Type' => 'application/json'
|
|
38
|
+
}
|
|
34
39
|
end
|
|
35
40
|
end
|
|
36
41
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ccs
|
|
4
|
+
class Encrypter
|
|
5
|
+
def initialize(passphrase, content, salt)
|
|
6
|
+
@passphrase = passphrase
|
|
7
|
+
@content = content
|
|
8
|
+
@salt = salt
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call
|
|
12
|
+
encryptor.pkcs5_keyivgen(@passphrase, @salt, 1)
|
|
13
|
+
encrypted = encryptor.update(@content)
|
|
14
|
+
encrypted << encryptor.final
|
|
15
|
+
|
|
16
|
+
openssl_salted_ciphertext = 'Salted__' + @salt + encrypted
|
|
17
|
+
Base64.strict_encode64(openssl_salted_ciphertext)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def encryptor
|
|
23
|
+
@encryptor ||= OpenSSL::Cipher::AES.new(256, :CBC).encrypt
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/ccs/uploader.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ccs
|
|
4
|
+
class Uploader
|
|
5
|
+
def initialize(uri, content, access_token, passphrase)
|
|
6
|
+
@uri = uri
|
|
7
|
+
@content = content
|
|
8
|
+
@access_token = access_token
|
|
9
|
+
@passphrase = passphrase
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call
|
|
13
|
+
request.body = { encrypted_content: encrypted_content }.to_json
|
|
14
|
+
http.request(request).code.eql? '201'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def http
|
|
20
|
+
@http ||= Net::HTTP.new(@uri.host, @uri.port).tap do |http|
|
|
21
|
+
http.use_ssl = @uri.scheme.eql?('https')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def request
|
|
26
|
+
@request ||= Net::HTTP::Post.new(@uri.path, headers).tap do |request|
|
|
27
|
+
request["User-Agent"] = format('ccs/%s', Ccs::VERSION)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def headers
|
|
32
|
+
{
|
|
33
|
+
'Authorization' => format('Token token=%<access_token>s', access_token: @access_token),
|
|
34
|
+
'Content-Type' => 'application/json'
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def encrypted_content
|
|
39
|
+
@encrypted_content ||= Encrypter.new(@passphrase, @content, salt).call
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def salt
|
|
43
|
+
@access_token[0...8]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/ccs/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,74 +1,146 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ccs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- tkowalewski
|
|
8
|
+
- paweljw
|
|
8
9
|
autorequire:
|
|
9
|
-
bindir:
|
|
10
|
+
bindir: exe
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
+
date: 2020-10-23 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
15
|
+
name: inch
|
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
|
16
17
|
requirements:
|
|
17
18
|
- - "~>"
|
|
18
19
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
20
|
+
version: 0.8.0
|
|
20
21
|
type: :development
|
|
21
22
|
prerelease: false
|
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
24
|
requirements:
|
|
24
25
|
- - "~>"
|
|
25
26
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
27
|
+
version: 0.8.0
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: pry
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - "~>"
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: 0.11.3
|
|
35
|
+
type: :development
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - "~>"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: 0.11.3
|
|
27
42
|
- !ruby/object:Gem::Dependency
|
|
28
43
|
name: rake
|
|
29
44
|
requirement: !ruby/object:Gem::Requirement
|
|
30
45
|
requirements:
|
|
31
46
|
- - "~>"
|
|
32
47
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
48
|
+
version: 13.0.1
|
|
34
49
|
type: :development
|
|
35
50
|
prerelease: false
|
|
36
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
52
|
requirements:
|
|
38
53
|
- - "~>"
|
|
39
54
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
55
|
+
version: 13.0.1
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: reek
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - "~>"
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: 4.7.3
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - "~>"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: 4.7.3
|
|
41
70
|
- !ruby/object:Gem::Dependency
|
|
42
71
|
name: rspec
|
|
43
72
|
requirement: !ruby/object:Gem::Requirement
|
|
44
73
|
requirements:
|
|
45
74
|
- - "~>"
|
|
46
75
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
76
|
+
version: 3.7.0
|
|
48
77
|
type: :development
|
|
49
78
|
prerelease: false
|
|
50
79
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
80
|
requirements:
|
|
52
81
|
- - "~>"
|
|
53
82
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
83
|
+
version: 3.7.0
|
|
55
84
|
- !ruby/object:Gem::Dependency
|
|
56
85
|
name: rubocop
|
|
57
86
|
requirement: !ruby/object:Gem::Requirement
|
|
58
87
|
requirements:
|
|
59
88
|
- - "~>"
|
|
60
89
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 0.
|
|
90
|
+
version: 0.52.1
|
|
62
91
|
type: :development
|
|
63
92
|
prerelease: false
|
|
64
93
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
94
|
requirements:
|
|
66
95
|
- - "~>"
|
|
67
96
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 0.
|
|
97
|
+
version: 0.52.1
|
|
98
|
+
- !ruby/object:Gem::Dependency
|
|
99
|
+
name: simplecov
|
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - "~>"
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: 0.15.1
|
|
105
|
+
type: :development
|
|
106
|
+
prerelease: false
|
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
108
|
+
requirements:
|
|
109
|
+
- - "~>"
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
version: 0.15.1
|
|
112
|
+
- !ruby/object:Gem::Dependency
|
|
113
|
+
name: webmock
|
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
|
115
|
+
requirements:
|
|
116
|
+
- - "~>"
|
|
117
|
+
- !ruby/object:Gem::Version
|
|
118
|
+
version: 3.3.0
|
|
119
|
+
type: :development
|
|
120
|
+
prerelease: false
|
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
122
|
+
requirements:
|
|
123
|
+
- - "~>"
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: 3.3.0
|
|
126
|
+
- !ruby/object:Gem::Dependency
|
|
127
|
+
name: yard
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
129
|
+
requirements:
|
|
130
|
+
- - ">="
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: 0.9.11
|
|
133
|
+
type: :development
|
|
134
|
+
prerelease: false
|
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - ">="
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: 0.9.11
|
|
69
140
|
description: ''
|
|
70
141
|
email:
|
|
71
|
-
-
|
|
142
|
+
- me@tkowalewski.pl
|
|
143
|
+
- p@steamshard.net
|
|
72
144
|
executables:
|
|
73
145
|
- ccs
|
|
74
146
|
extensions: []
|
|
@@ -78,13 +150,16 @@ files:
|
|
|
78
150
|
- CODE_OF_CONDUCT.md
|
|
79
151
|
- LICENSE.txt
|
|
80
152
|
- README.md
|
|
81
|
-
-
|
|
153
|
+
- exe/ccs
|
|
82
154
|
- lib/ccs.rb
|
|
83
|
-
- lib/ccs/
|
|
155
|
+
- lib/ccs/commands/copy.rb
|
|
84
156
|
- lib/ccs/decrypter.rb
|
|
157
|
+
- lib/ccs/document.rb
|
|
85
158
|
- lib/ccs/downloader.rb
|
|
159
|
+
- lib/ccs/encrypter.rb
|
|
160
|
+
- lib/ccs/uploader.rb
|
|
86
161
|
- lib/ccs/version.rb
|
|
87
|
-
homepage: https://github.com/
|
|
162
|
+
homepage: https://github.com/occson/ccs
|
|
88
163
|
licenses:
|
|
89
164
|
- MIT
|
|
90
165
|
metadata: {}
|
|
@@ -103,9 +178,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
103
178
|
- !ruby/object:Gem::Version
|
|
104
179
|
version: '0'
|
|
105
180
|
requirements: []
|
|
106
|
-
|
|
107
|
-
rubygems_version: 2.5.2
|
|
181
|
+
rubygems_version: 3.0.3
|
|
108
182
|
signing_key:
|
|
109
183
|
specification_version: 4
|
|
110
|
-
summary:
|
|
184
|
+
summary: Configuration Control System (CCS)
|
|
111
185
|
test_files: []
|
data/bin/ccs
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
require 'ccs'
|
|
4
|
-
require 'optparse'
|
|
5
|
-
require 'io/console'
|
|
6
|
-
|
|
7
|
-
options = {}
|
|
8
|
-
|
|
9
|
-
opt_parser = OptionParser.new do |opt|
|
|
10
|
-
opt.banner = 'Usage: ccs [OPTIONS] <CCSUri> <LocalPath|STDOUT>'
|
|
11
|
-
opt.separator ''
|
|
12
|
-
opt.separator 'Options:'
|
|
13
|
-
|
|
14
|
-
opt.on('-t TOKEN', '--token TOKEN', String, 'API Token') do |v|
|
|
15
|
-
options[:token] = v
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
opt.on('-d', '--decrypt', 'Ask for passphrase and decrypt') do |v|
|
|
19
|
-
options[:decrypt] = v
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
opt.on('-h','--help', 'help') do
|
|
23
|
-
puts opt_parser
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
opt.separator ''
|
|
27
|
-
opt.separator 'Examples:'
|
|
28
|
-
opt.separator ' ccs -t 8b5a196e-a116-4c64-8472-f7c6e1c2de3b ccs://0.1.0/path/to/file.yml'
|
|
29
|
-
opt.separator ' ccs -t 8b5a196e-a116-4c64-8472-f7c6e1c2de3b ccs://0.1.0/path/to/file.yml local/path/to/file.yml'
|
|
30
|
-
|
|
31
|
-
opt.separator ''
|
|
32
|
-
opt.separator format('Version: %s', Ccs::VERSION)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
arguments = opt_parser.parse!
|
|
36
|
-
|
|
37
|
-
if ARGV.empty?
|
|
38
|
-
puts opt_parser
|
|
39
|
-
exit(-1)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
raise OptionParser::MissingArgument if options[:token].nil?
|
|
43
|
-
raise OptionParser::MissingArgument if arguments[0].nil?
|
|
44
|
-
|
|
45
|
-
configuration_file = Ccs::ConfigurationFile.new(arguments[0])
|
|
46
|
-
destination = arguments[1] ? File.new(arguments[1], 'w') : STDOUT
|
|
47
|
-
|
|
48
|
-
json = Ccs::Downloader.new(options[:token], configuration_file).download
|
|
49
|
-
|
|
50
|
-
if options[:decrypt]
|
|
51
|
-
print 'Passphrase: '
|
|
52
|
-
passphrase = STDIN.noecho(&:gets)
|
|
53
|
-
|
|
54
|
-
destination.puts Ccs::Decrypter.new(passphrase.chomp, json['encrypted_content']).decrypt
|
|
55
|
-
else
|
|
56
|
-
destination.puts json['encrypted_content']
|
|
57
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
module Ccs
|
|
2
|
-
class ConfigurationFile
|
|
3
|
-
def initialize(uri)
|
|
4
|
-
@uri = uri
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def version
|
|
8
|
-
parts[0]
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def path
|
|
12
|
-
parts[1]
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def to_path
|
|
16
|
-
Pathname.new path
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def to_s
|
|
20
|
-
format 'ccs://%s/%s', version, path
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
def parts
|
|
26
|
-
@parts ||= @uri.sub('ccs://', '').split('/', 2)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|