bbc-cosmos-tools-config 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5e8874cee85d4fd53b2c33173a143864e7298dde
4
+ data.tar.gz: 4b2d5c3aaa545245153ff264b2a69c69de18621d
5
+ SHA512:
6
+ metadata.gz: da91f4582bc46f8bb59c3a94b87bbe30ca7cef8489988f05978a7be74162b51c4dea25e64cf3e833e872f5e0a8309d3e521707ec5e99c4ffce0089a62ea6a6b6
7
+ data.tar.gz: 3d5f3d24ccd3c241e6077679aa93682fdfca4e3126e41adfe1b8343ca973cd0233d4f23dfb45072d64795ca9546933198f6d11bafcb0f432d98e9a42b21039cc
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ configs
19
+
20
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bbc-cosmos-config.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Steven Jack
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # BBC::Cosmos::Tools::Config
2
+
3
+ This gem provides functionality to generate and push config to the cosmos platform.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'bbc-cosmos-tools-config'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install bbc-cosmos-tools-config
18
+
19
+ ## Usage
20
+
21
+ The gem expects a certain folder structure for the config files:
22
+
23
+ #### Folder structure
24
+
25
+ ```bash
26
+ ├── configs
27
+ │ ├── {env_name (int/test/stage/live)}
28
+ │ │ ├── {project_name}.yaml
29
+ │ ├── app_config.yaml
30
+ ```
31
+
32
+ an example of this would be:
33
+
34
+ ```bash
35
+ ├── configs
36
+ │ ├── int
37
+ │ │ ├── my_project.yaml
38
+ │ ├── test
39
+ │ │ ├── my_project.yaml
40
+ │ ├── stage
41
+ │ │ ├── my_project.yaml
42
+ │ ├── live
43
+ │ │ ├── my_project.yaml
44
+ │ ├── app_config.yaml
45
+ ```
46
+
47
+ #### Project Config structure
48
+
49
+ All of the configs are in yaml format, the project yaml has the following format:
50
+
51
+ ```yaml
52
+
53
+ components:
54
+ "component_id":
55
+ a_config_key: "it's value"
56
+ another_key: "Another value"
57
+
58
+ shared:
59
+ shared_key: "shared_value"
60
+
61
+ ```
62
+
63
+ The config has a number of components under a project, and the shared key allows you to
64
+ have shared config for the components. The config is built up from the shared data with
65
+ the component config merged in afterwards.
66
+
67
+ #### Application config
68
+
69
+ There's also an application config that stores data used by the app, at the moment this
70
+ is only the api endpoints.
71
+
72
+ ```yaml
73
+ bbc:
74
+ cosmos:
75
+ api: "https://www.my.api.com"
76
+ endpoint: "/some/restful/endpoint"
77
+ ```
78
+
79
+ The gem is a cli application and currently has two functions:
80
+
81
+ ### Generating config
82
+
83
+ ```bash
84
+ bbc-cosmos-tools-config generate {project_name} [{component_id = nil, environment = 'int' --cosmos_format]
85
+ ```
86
+
87
+ `project_name`
88
+ The project name is required, the other parameters are optional.
89
+
90
+ `component_id`
91
+ This is the id of the component in the components block of the project config. If you omit the component id then all components for the project are output.
92
+
93
+ `environment`
94
+ This maps to the folder underneath the configs directory, is omitted `int` is chosen as default.
95
+
96
+ `--cosmos_output`
97
+ As the cosmos API requires a slightly different JSON structure, you can have it formatted this way by passing this flag.
98
+
99
+ ### Pushing config
100
+
101
+ ```bash
102
+ bbc-cosmos-tools-config push {project_name} [{cert_path = nil, component_id = nil, environment = 'int' --force]
103
+ ```
104
+
105
+ `project_name`
106
+ The project name is required, the other parameters are optional.
107
+
108
+ `cert_path`
109
+ This is the path to a valid client cert that can authenticate with the supplied API.
110
+
111
+ `component_id`
112
+ This is the id of the component in the components block of the project config. If you omit the component id then all components for the project have their configs updated.
113
+
114
+ `environment`
115
+ This maps to the folder underneath the configs directory, is omitted `int` is chosen as default.
116
+
117
+ `--force`
118
+ By default, before pushing changes to the API you're asked to confirm the action - This flag removes that confirmation.
119
+
120
+ ## Contributing
121
+
122
+ 1. Fork it
123
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
124
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
125
+ 4. Push to the branch (`git push origin my-new-feature`)
126
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bbc/cosmos/tools/config/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bbc-cosmos-tools-config"
8
+ spec.version = Bbc::Cosmos::Tools::Config::VERSION
9
+ spec.authors = ["Steven Jack"]
10
+ spec.email = ["stevenmajack@gmail.com"]
11
+ spec.description = %q{Tool for generating and pushing config to BBC Cosmos platform}
12
+ spec.summary = %q{Tool for generating and pushing config to BBC Cosmos platform}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables << 'bbc-cosmos-tools-config'
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_runtime_dependency 'thor'
25
+ spec.add_runtime_dependency 'faraday'
26
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ root = Pathname.new(__FILE__).dirname.parent
6
+ lib_path = (root + 'lib').realdirpath
7
+ config_path = root + 'configs'
8
+
9
+ $LOAD_PATH.unshift(lib_path)
10
+
11
+ require 'bbc/cosmos/tools/config/app'
12
+ include BBC::Cosmos::Tools::Config
13
+
14
+ App.start
@@ -0,0 +1,9 @@
1
+ require "bbc/cosmos/config/version"
2
+
3
+ module Bbc
4
+ module Cosmos
5
+ module Config
6
+ # Your code goes here...
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,40 @@
1
+ require 'pathname'
2
+ require 'faraday'
3
+ require 'openssl'
4
+
5
+ module BBC
6
+ module Cosmos
7
+ module Tools
8
+ module Config
9
+ class API
10
+
11
+ def initialize(host, key_path)
12
+ @connection = Faraday.new host, :ssl => {:client_key => client_key(key_path), :client_cert => client_cert(key_path), :verify => false }
13
+ end
14
+
15
+ def client_key(path)
16
+ OpenSSL::PKey::RSA.new(File.read path)
17
+ end
18
+
19
+ def client_cert(path)
20
+ OpenSSL::X509::Certificate.new(File.read path)
21
+ end
22
+
23
+ def get(path)
24
+ @connection.get path
25
+ end
26
+
27
+ def put(path, payload, content_type = 'application/json')
28
+ content_type_from content_type
29
+ @connection.put path, payload
30
+ end
31
+
32
+ def content_type_from(type)
33
+ @connection.headers[:content_type] = type
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,117 @@
1
+ require "thor"
2
+ require "json"
3
+ require "bbc/cosmos/tools/config/project_config"
4
+ require "bbc/cosmos/tools/config/configuration"
5
+ require "bbc/cosmos/tools/config/api"
6
+ require "pathname"
7
+
8
+ module BBC
9
+ module Cosmos
10
+ module Tools
11
+ module Config
12
+ class App < Thor
13
+ include Thor::Actions
14
+
15
+ def initialize(args = [], local_options = {}, config = {})
16
+ super(args, local_options, config)
17
+ end
18
+
19
+ package_name "BBC Cosmos config tool"
20
+
21
+ desc "generate PROJECT COMPONENT_ID (--cosmos_format, --env", "Generates the cosmos config for a given component id"
22
+ method_options :cosmos_format => :boolean, :config => :string
23
+ method_option :env, :type => :string, :default => 'int'
24
+ def generate(project, component_id)
25
+ begin
26
+ config_base(options[:config])
27
+ config = config_from(project, options[:env])
28
+
29
+ say "\nComponent: #{component_id}\nProject: #{project}\nEnvironement: #{options[:env]}\n", :green
30
+ if options[:cosmos_format]
31
+ say JSON.pretty_generate(config.generate_cosmos component_id)
32
+ else
33
+ say JSON.pretty_generate(config.generate component_id)
34
+ end
35
+ rescue Exception => e
36
+ error e.message
37
+ end
38
+
39
+ end
40
+
41
+ desc "list PROJECT (--config, --env)", "Lists all components for a given project"
42
+ method_options :config => :string
43
+ method_option :env, :type => :string, :default => 'int'
44
+ def list(project)
45
+ begin
46
+ config_base(options[:config])
47
+ config = config_from(project, options[:env])
48
+
49
+ say "\nComponents: \n", :green
50
+ config.components.each do |component_id|
51
+ say "#{component_id}", :blue
52
+ end
53
+ rescue Exception => e
54
+ error e.message
55
+ end
56
+
57
+ end
58
+
59
+ desc "push PROJECT KEY_PATH = nil COMPONENT = nil (--force, --config, --env)", "Push config for a component to the cosmos API"
60
+ method_options :force => :boolean, :config => :string
61
+ method_option :env, :type => :string, :default => 'int'
62
+ def push(project, key_path = nil, component_id = nil)
63
+ begin
64
+ config_base(options[:config])
65
+ config = config_from(project, options[:env])
66
+ components = component_id.nil? ? config.components : [component_id]
67
+
68
+ reply = yes?("Are you sure you want to push changes for #{components.length} components(s) to #{options[:env]}?", :blue) unless options[:force]
69
+ if reply || reply.nil?
70
+
71
+ components.each do |id|
72
+ cosmos_config = JSON.generate(config.generate_cosmos id)
73
+
74
+ @api = BBC::Cosmos::Tools::Config::API.new(app_config['api'], key_path)
75
+ response = @api.put sprintf(app_config['endpoint'], options[:env], id), cosmos_config
76
+
77
+ if response.success?
78
+ say "Configuration for component '#{id}' successfully saved", :green
79
+ else
80
+ say "There was an error saving your config: #{response.body}", :red
81
+ end
82
+ end
83
+
84
+ else
85
+ say "Action cancelled", :red
86
+ end
87
+
88
+ rescue Exception => e
89
+ error e.message
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def error(message)
96
+ say message, :red
97
+ exit 1
98
+ end
99
+
100
+ def config_from(project, env)
101
+ BBC::Cosmos::Tools::Config::ProjectConfig.new(@config_base, project, env)
102
+ end
103
+
104
+ def app_config
105
+ @app_config ||= BBC::Cosmos::Tools::Config::Configuration::get(@config_base)['bbc']['cosmos']
106
+ end
107
+
108
+ def config_base(override = nil)
109
+ @config_base = !override.nil? && File.directory?(override) ? Pathname.new(override) : Pathname.pwd.join('configs')
110
+ raise("Config directory doesn't exist") unless File.directory?(@config_base)
111
+ end
112
+
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,21 @@
1
+ require 'yaml'
2
+
3
+ module BBC
4
+ module Cosmos
5
+ module Tools
6
+ module Config
7
+ class Configuration
8
+
9
+ def self.get(config_base)
10
+ config_path = config_base.join('app.yaml')
11
+ raise('Invalid application config path') unless File.exists? config_path
12
+ YAML::load(File.open(config_path).read)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+
@@ -0,0 +1,61 @@
1
+ require 'pathname'
2
+ require 'yaml'
3
+
4
+ module BBC
5
+ module Cosmos
6
+ module Tools
7
+ module Config
8
+ class ProjectConfig
9
+
10
+ def initialize(config_path, project, env = 'int')
11
+ @project = project
12
+ @env = env
13
+ @config_path = config_path
14
+ end
15
+
16
+ def components
17
+ config['components'].keys
18
+ end
19
+
20
+ def generate(id)
21
+ component_config id
22
+ end
23
+
24
+ def generate_cosmos(id)
25
+ generate(id).reduce([]) do |object, (key, value)|
26
+ object.tap { |o| o << {:value => value, :key => key} }
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def environment_exists?
33
+ File.directory? File.join(@config_path, @env)
34
+ end
35
+
36
+ def config_path
37
+ if environment_exists?
38
+ path = File.join(@config_path, @env, "#{@project}.yaml")
39
+ if File.exist? path
40
+ File.open(path).read
41
+ else
42
+ raise("#{@project} isn't a valid project")
43
+ end
44
+ else
45
+ raise("#{@env} is an invalid environment")
46
+ end
47
+ end
48
+
49
+ def config
50
+ @config ||= YAML::load(config_path)
51
+ end
52
+
53
+ def component_config(id)
54
+ raise('Invalid component id') if config['components'][id].nil?
55
+ config['components'][id]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,9 @@
1
+ module Bbc
2
+ module Cosmos
3
+ module Tools
4
+ module Config
5
+ VERSION = "0.0.1"
6
+ end
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bbc-cosmos-tools-config
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Steven Jack
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Tool for generating and pushing config to BBC Cosmos platform
70
+ email:
71
+ - stevenmajack@gmail.com
72
+ executables:
73
+ - bbc-cosmos-tools-config
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bbc-cosmos-tools-config.gemspec
83
+ - bin/bbc-cosmos-tools-config
84
+ - lib/bbc/cosmos/tools/config.rb
85
+ - lib/bbc/cosmos/tools/config/api.rb
86
+ - lib/bbc/cosmos/tools/config/app.rb
87
+ - lib/bbc/cosmos/tools/config/configuration.rb
88
+ - lib/bbc/cosmos/tools/config/project_config.rb
89
+ - lib/bbc/cosmos/tools/config/version.rb
90
+ homepage: ''
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.0.3
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: Tool for generating and pushing config to BBC Cosmos platform
114
+ test_files: []