hyrb 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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +61 -0
  6. data/Rakefile +8 -0
  7. data/bin/hyrb +9 -0
  8. data/hyrb.gemspec +35 -0
  9. data/lib/hyrb/cli.rb +27 -0
  10. data/lib/hyrb/command.rb +74 -0
  11. data/lib/hyrb/commands/ansible.rb +13 -0
  12. data/lib/hyrb/commands/creds.rb +20 -0
  13. data/lib/hyrb/commands/defaults.rb +20 -0
  14. data/lib/hyrb/commands/developers.rb +15 -0
  15. data/lib/hyrb/commands/digital_ocean.rb +15 -0
  16. data/lib/hyrb/commands/environment.rb +11 -0
  17. data/lib/hyrb/commands/github.rb +15 -0
  18. data/lib/hyrb/commands/hipchat.rb +20 -0
  19. data/lib/hyrb/commands/project.rb +36 -0
  20. data/lib/hyrb/commands/provision.rb +17 -0
  21. data/lib/hyrb/commands/rackspace.rb +11 -0
  22. data/lib/hyrb/model.rb +96 -0
  23. data/lib/hyrb/models/ansible_host.rb +28 -0
  24. data/lib/hyrb/models/ansible_site.rb +46 -0
  25. data/lib/hyrb/models/cache.rb +35 -0
  26. data/lib/hyrb/models/creds.rb +24 -0
  27. data/lib/hyrb/models/defaults.rb +11 -0
  28. data/lib/hyrb/models/developer.rb +28 -0
  29. data/lib/hyrb/models/environment.rb +41 -0
  30. data/lib/hyrb/models/project.rb +35 -0
  31. data/lib/hyrb/pipeline.rb +63 -0
  32. data/lib/hyrb/task.rb +46 -0
  33. data/lib/hyrb/tasks/ansible.rb +96 -0
  34. data/lib/hyrb/tasks/creds.rb +39 -0
  35. data/lib/hyrb/tasks/defaults.rb +43 -0
  36. data/lib/hyrb/tasks/developers.rb +120 -0
  37. data/lib/hyrb/tasks/digital_ocean.rb +84 -0
  38. data/lib/hyrb/tasks/environment.rb +56 -0
  39. data/lib/hyrb/tasks/github.rb +120 -0
  40. data/lib/hyrb/tasks/google.rb +15 -0
  41. data/lib/hyrb/tasks/hipchat.rb +76 -0
  42. data/lib/hyrb/tasks/project/bootstrap.rb +88 -0
  43. data/lib/hyrb/tasks/project.rb +48 -0
  44. data/lib/hyrb/tasks/provision.rb +91 -0
  45. data/lib/hyrb/tasks/rackspace.rb +95 -0
  46. data/lib/hyrb/version.rb +3 -0
  47. data/lib/hyrb.rb +18 -0
  48. data/lib/templates/ansible/Vagrantfile.erb +21 -0
  49. data/lib/templates/ansible/roles/db/handlers/main.yml +2 -0
  50. data/lib/templates/ansible/roles/db/tasks/main.yml +24 -0
  51. data/lib/templates/ansible/roles/lamp/tasks/main.yml +53 -0
  52. data/lib/templates/ansible/roles/lamp.yml +6 -0
  53. data/lib/templates/ansible/roles/site/handlers/main.yml +3 -0
  54. data/lib/templates/ansible/roles/site/tasks/db.yml +23 -0
  55. data/lib/templates/ansible/roles/site/tasks/main.yml +16 -0
  56. data/lib/templates/ansible/roles/site/templates/vhost.conf.j2 +24 -0
  57. data/lib/templates/ansible/site.yml +10 -0
  58. data/lib/templates/roles/db/handlers/main.yml +2 -0
  59. data/lib/templates/roles/db/tasks/main.yml +24 -0
  60. data/lib/templates/roles/lamp/tasks/main.yml +36 -0
  61. data/lib/templates/roles/lamp.yml +6 -0
  62. data/lib/templates/roles/site/handlers/main.yml +3 -0
  63. data/lib/templates/roles/site/tasks/db.yml +23 -0
  64. data/lib/templates/roles/site/tasks/main.yml +16 -0
  65. data/lib/templates/roles/site/templates/vhost.conf.j2 +24 -0
  66. data/spec/hyrb/pipeline_spec.rb +91 -0
  67. data/spec/spec_helper.rb +5 -0
  68. metadata +295 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fe123a584f3bade6baea0b74efcc5a258e5c3bc3
4
+ data.tar.gz: 8f8917a50a6269c199d89c3cb79f14c82329ec31
5
+ SHA512:
6
+ metadata.gz: 614455754889a6e57ad0edc36edcf086b84d0171450f1c5dd86932024b23906e306611049ad3af71eac5721e8050b21e4fc207ef043df5a77a7018f59088f88d
7
+ data.tar.gz: b03e1193eb9d2f353465bfa5726098e01a6a27265c1953455dad7885429233dccf3f6fd334092bbfd24b250d29a5544f3239edb8facbd399198e736ae6e27275
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hyrb.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Daniel Leavitt
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,61 @@
1
+ # Hyrb
2
+
3
+ It's for bootstrapping projects. There's a lot left to do.
4
+
5
+ ## Setup
6
+
7
+ ### Prerequisites
8
+
9
+ - Required: ruby 2.0
10
+ - Optional: ansible, vagrant
11
+
12
+ ### Installation
13
+
14
+ As a CLI utility:
15
+
16
+ $ gem install hyrb
17
+
18
+ This will make the 'hyrb' command available to your shell.
19
+
20
+ ### Configuration
21
+
22
+ All optional, should work without any additional setup.
23
+
24
+ As you use it, it will prompt you for various pieces of information that it needs. This will all be stored in a `~/.hyfn` directory, which it will create (this location is overridable via the `HYFN_CONFIG_PATH` env variable.)
25
+
26
+ Most the files in here can safely be edited by hand as well, with the exception of the `cache` directory, which gets overwritten a lot.
27
+
28
+ ## Usage
29
+
30
+ List available tasks with:
31
+
32
+ $ hyrb
33
+
34
+ Then go crazy.
35
+
36
+ ## Hacking
37
+
38
+ ### Adding New Tasks
39
+
40
+ 1. Create a new task module in the `lib/hyrb/tasks` dir. Use one of the existing ones as a template.
41
+ 2. Create a new command class in the `lib/hyrb/commands` dir. Again, use an existing command as a template. Add a method for every task you want to be callable via the CLI.
42
+ 3. Require and register your subommand in `lib/hyrb/commands/main.rb`
43
+
44
+ ## Todo
45
+ - Add teams to ansible
46
+ - Require dependencies (esp. fog) on-demand only.
47
+ - Save environments correctly on project save.
48
+ - Improve flavor selection stuff for Rackspace
49
+ - Deal with rackspace pubkeys
50
+ - Make a DSL for this
51
+ - Automatically create Thor commands from tasks
52
+ - This will allow lazy loading as well
53
+ - Add coverage for at least the locals parts (config, etc)
54
+ - Refactor model attributes to support documentation, constraints, etc
55
+ - Allow a couple kinds of defaults
56
+ - Within a model, so that like, server_name and repo_name will fall back to name if not defined.
57
+ - For a project environment, so that an environment will use the project default for certain attributes if they're not defined on the current environment.
58
+ - Can we dump the default list of users into the project file and let users trim it down?
59
+ - Break project setup into two steps, first to prompt for everything needed in the config file, then let the user edit it, then create everything.
60
+ - Use vagrant-hostmanager.
61
+ - Thor task to install pre-reqs
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "rake/testtask"
2
+ require "bundler/gem_tasks"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.pattern = "spec/**/*_spec.rb"
6
+ t.libs.push 'spec'
7
+ t.libs.push 'lib'
8
+ end
data/bin/hyrb ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Signal.trap("INT") { exit 1 }
4
+
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
+
7
+ require 'hyrb/cli'
8
+
9
+ Hyrb::CLI.start(ARGV)
data/hyrb.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hyrb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hyrb"
8
+ spec.version = Hyrb::VERSION
9
+ spec.authors = ["Daniel Leavitt"]
10
+ spec.email = ["daniel.leavitt@gmail.com"]
11
+ spec.description = %q{Bootstrap HYFN Projects}
12
+ spec.summary = %q{Bootstrap HYFN Projects}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "hashie"
22
+ spec.add_dependency "parallel"
23
+ spec.add_dependency "thor_dleavitt"
24
+ spec.add_dependency "activesupport"
25
+ spec.add_dependency "hipchat-api"
26
+ spec.add_dependency "octokit"
27
+ spec.add_dependency "fog"
28
+ spec.add_dependency "faraday"
29
+ spec.add_dependency "google_doc_seed"
30
+ spec.add_dependency "yaml_inventory", ">= 0.0.3"
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.3"
33
+ spec.add_development_dependency "rake"
34
+ spec.add_development_dependency "pry"
35
+ end
data/lib/hyrb/cli.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'thor_dleavitt'
2
+
3
+ require 'hyrb'
4
+ require 'hyrb/command'
5
+
6
+ module Hyrb
7
+ class CLI < Command
8
+ class_option :verbose, :desc => "Verbose", :aliases => "-v"
9
+
10
+ desc "edit", "Open the configuration dir in your default editor"
11
+ def edit
12
+ Pipeline.new(Hyrb::Tasks::Base).edit(Hyrb::DEFAULT_PATH)
13
+ end
14
+
15
+ subc :defaults, "Manage Hyrb defaults"
16
+ subc :creds, "Manage service credentials"
17
+ subc :project, "Manage projects"
18
+ subc :environment, "Manage project environments"
19
+ subc :developers, "Manage developers"
20
+ subc :digital_ocean, "Manage Digital Ocean SSH Keys"
21
+ subc :hipchat, "Manage Hipchat Rooms"
22
+ subc :github, "Manage Github Repos"
23
+ subc :rackspace, "Manage Rackspace DNS"
24
+ subc :provision, "Create Project Servers"
25
+ subc :ansible, "Create Ansible Playbooks"
26
+ end
27
+ end
@@ -0,0 +1,74 @@
1
+ require 'hashie/mash'
2
+
3
+ module Hyrb
4
+ class Command < Thor
5
+ def self.subc(name, description)
6
+ desc name.to_sym, description
7
+ subcommand name.to_s, "hyrb/commands/#{name}".camelcase.constantize
8
+ end
9
+
10
+ no_commands do
11
+ def pipeline(task, env = {})
12
+ env.merge!(verbose: !!options[:verbose])
13
+ Commands::Pipeline.new(task).run(Hashie::Mash.new(env))
14
+ end
15
+ end
16
+ end
17
+
18
+ module Commands
19
+ Hyrb.autoload_each self, "hyrb/commands", %w( ansible creds defaults developers digital_ocean environment github hipchat project provision rackspace )
20
+
21
+ class Pipeline < Hyrb::Pipeline
22
+ def initialize(task_class)
23
+ super
24
+
25
+ # Thor:Shell defines a constructor so have to do this here
26
+ extend Thor::Shell
27
+ end
28
+
29
+ def prompt(prompt, hash, key, options = {})
30
+ unless options.is_a?(Hash)
31
+ default = options
32
+ options = {}
33
+ options[:default] = default
34
+ end
35
+
36
+ if options.delete(:always)
37
+ options[:default] = hash[key] if hash[key]
38
+ ask(prompt, options)
39
+ else
40
+ hash[key].blank? ? hash[key] = ask(prompt, options) : hash[key]
41
+ end
42
+
43
+ hash.save! if hash.respond_to? :save!
44
+ end
45
+
46
+ def edit(path)
47
+ editor = [ENV['VISUAL'], ENV['EDITOR']].find { |e| e.present? }
48
+ raise "Please set $EDITOR variable :)" unless editor
49
+ cmd = "#{editor} #{path}"
50
+ raise "Could not run '#{cmd}'" unless system(cmd)
51
+ end
52
+
53
+ def option_list(cache, attribute = nil, default = nil, &block)
54
+ list = attribute ? cache[attribute] : cache
55
+ choices = list.map.with_index(&block)
56
+ say choices.join("\n")
57
+ index = ask("Pick from #{attribute}:", default: default)
58
+ if index.try :include?, ","
59
+ index.split(",").map { |i| list[i.to_i - 1] }
60
+ else
61
+ list[index.to_i - 1]
62
+ end
63
+ end
64
+
65
+ def info(message)
66
+ say message
67
+ end
68
+
69
+ def beep
70
+ print "\a"
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,13 @@
1
+ require 'hyrb/tasks/digital_ocean'
2
+
3
+ module Hyrb
4
+ module Commands
5
+ class Ansible < Command
6
+ desc "create_playbook", "List Digital Ocean saved SSH keys"
7
+ def create_playbook(project = nil, environment = nil)
8
+ env = { project_name: project, environment_name: environment }
9
+ pipeline(Hyrb::Tasks::Ansible::CreatePlaybook, env)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Creds < Command
4
+ desc "show", "Show credentials for various services"
5
+ def show
6
+ pipeline(Hyrb::Tasks::Creds::Show)
7
+ end
8
+
9
+ desc "build", "Update credentials"
10
+ def build
11
+ pipeline(Hyrb::Tasks::Creds::Build)
12
+ end
13
+
14
+ desc "edit", "Edit credentials file in your default editor"
15
+ def edit
16
+ pipeline(Hyrb::Tasks::Creds::Edit)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Defaults < Command
4
+ desc "show", "Show defaults"
5
+ def show
6
+ pipeline(Hyrb::Tasks::Defaults::Show)
7
+ end
8
+
9
+ desc "build", "Update defaults"
10
+ def build
11
+ pipeline(Hyrb::Tasks::Defaults::Build)
12
+ end
13
+
14
+ desc "edit", "Edit defaults file in your default editor"
15
+ def edit
16
+ pipeline(Hyrb::Tasks::Defaults::Edit)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Developers < Command
4
+ desc "show", "Show developer info"
5
+ def show(developer_name = nil)
6
+ pipeline(Hyrb::Tasks::Developers::Show, developer_name: developer_name)
7
+ end
8
+
9
+ desc "download", "Download developer info from Google Docs"
10
+ def download(project = nil)
11
+ pipeline(Hyrb::Tasks::Developers::Download, project_name: project)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Hyrb
2
+ module Commands
3
+ class DigitalOcean < Command
4
+ desc "show_keys", "List Digital Ocean saved SSH keys"
5
+ def show_keys
6
+ pipeline(Hyrb::Tasks::DigitalOcean::ShowSSHKeys)
7
+ end
8
+
9
+ desc "sync_keys", "Sync Digital Ocean SSH keys with user list from Google Apps"
10
+ def sync_keys
11
+ pipeline(Hyrb::Tasks::DigitalOcean::SyncSSHKeys)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Environment < Command
4
+ desc "create <project> <environment>", "Create a new environment"
5
+ def create(project = nil, environment = nil)
6
+ env = { project_name: project, environment_name: environment }
7
+ pipeline(Hyrb::Tasks::Environment::Init, env)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Github < Command
4
+ desc "show_repos", "List Github repos"
5
+ def show_repos
6
+ pipeline(Hyrb::Tasks::Github::ShowRepos)
7
+ end
8
+
9
+ desc "create_repo <project>", "Create a Github repo for a project"
10
+ def create_repo(project_name = nil)
11
+ pipeline(Hyrb::Tasks::Github::CreateRepo, {project_name: project_name})
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Hipchat < Command
4
+ desc "show_rooms", "List Hipchat rooms"
5
+ def show_rooms
6
+ pipeline(Hyrb::Tasks::Hipchat::ShowRooms)
7
+ end
8
+
9
+ desc "ceate_room <project>", "Create a Hipchat room for a project"
10
+ def create_room(project_name = nil)
11
+ pipeline(Hyrb::Tasks::Hipchat::CreateRoom, {project_name: project_name})
12
+ end
13
+
14
+ desc "archive_old_rooms", "Interactively archive unused rooms"
15
+ def archive_old_rooms
16
+ pipeline(Hyrb::Tasks::Hipchat::ArchiveOldRooms)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Project < Command
4
+ desc "show <project>", "Show project info"
5
+ def show(project = nil)
6
+ pipeline(Hyrb::Tasks::Project::Show, project_name: project)
7
+ end
8
+
9
+ desc "create <project>", "Create a new project file"
10
+ def create(project = nil)
11
+ pipeline(Hyrb::Tasks::Project::Create, project_name: project)
12
+ end
13
+
14
+ desc "edit <project>", "Open a project file in your default editor"
15
+ def edit(project = nil)
16
+ pipeline(Hyrb::Tasks::Project::Edit, project_name: project)
17
+ end
18
+
19
+ desc "bootstrap <project>", "Build a project"
20
+ def bootstrap(project = nil, env = nil)
21
+ pipeline(Hyrb::Tasks::Project::Bootstrap, project_name: project)
22
+ end
23
+
24
+ desc "create_hipchat_hook <project>", "Link a Github repo to a Hipchat room"
25
+ def create_hipchat_hook(project = nil)
26
+ pipeline(Hyrb::Tasks::Project::CreateHipchatHook, project_name: project)
27
+ end
28
+
29
+ desc "developers <project>", "Manage developers for a project"
30
+ def developers(project = nil)
31
+ pipeline(Hyrb::Tasks::Developers::AddToProject, project_name: project)
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Provision < Command
4
+ desc "digital_ocean <project> <environment>", "Create a Digital Ocean server for a project"
5
+ def digital_ocean(project = nil, environment = nil)
6
+ env = { project_name: project, environment_name: environment }
7
+ pipeline(Hyrb::Tasks::Provision::DigitalOcean, env)
8
+ end
9
+
10
+ desc "rackspace <project> <environment>", "Create a Rackspace server for a project"
11
+ def rackspace(project = nil, environment = nil)
12
+ env = { project_name: project, environment_name: environment }
13
+ pipeline(Hyrb::Tasks::Provision::Rackspace, env)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module Hyrb
2
+ module Commands
3
+ class Rackspace < Command
4
+ desc "create_dns_record <project> <environment>", "Create a DNS record on Rackspace"
5
+ def create_dns_record(project = nil, environment = nil)
6
+ env = { project_name: project, environment_name: environment }
7
+ pipeline(Hyrb::Tasks::Rackspace::CreateDNSRecord, env)
8
+ end
9
+ end
10
+ end
11
+ end
data/lib/hyrb/model.rb ADDED
@@ -0,0 +1,96 @@
1
+ require 'yaml'
2
+ require 'hashie/mash'
3
+
4
+ module Hyrb
5
+ module Models
6
+ Hyrb.autoload_each self, "hyrb/models", %w( ansible_host ansible_site cache creds defaults developer environment project )
7
+ end
8
+
9
+ class Model
10
+ extend Forwardable
11
+ include Enumerable
12
+
13
+ attr_accessor :path, :data
14
+
15
+ def_delegators :data, :each
16
+
17
+ def initialize(path, data = nil)
18
+ @path = File.join(ENV["HYFN_CONFIG_PATH"] || Hyrb::DEFAULT_PATH, path)
19
+ @data = deserialize(load_config_file) || data
20
+ end
21
+
22
+ def load_config_file
23
+ YAML.load_file(filepath)
24
+ rescue Errno::ENOENT
25
+ nil
26
+ end
27
+
28
+ def filepath
29
+ @path + ".yml"
30
+ end
31
+
32
+ def reload!
33
+ @data = self.load_config_file
34
+ end
35
+
36
+ def save!
37
+ FileUtils.mkdir_p(File.dirname(@path))
38
+ File.open(filepath, File::RDWR|File::TRUNC|File::CREAT, 0600) do |file|
39
+ file.write(serialize(@data).to_yaml)
40
+ end
41
+ end
42
+
43
+ protected
44
+
45
+ def serialize(data)
46
+ data
47
+ end
48
+
49
+ def deserialize(data)
50
+ data
51
+ end
52
+ end
53
+
54
+ module Models
55
+ class Struct < Model
56
+ def self.keys
57
+ @keys
58
+ end
59
+
60
+ def self.define_keys(keys)
61
+ @keys = keys.each do |key|
62
+ define_method key do
63
+ @data[key]
64
+ end
65
+
66
+ define_method "#{key}=" do |val|
67
+ @data[key] = val
68
+ end
69
+ end
70
+ end
71
+
72
+ def initialize(path)
73
+ super
74
+ self.class.keys.each { |key| @data[key] ||= nil }
75
+ end
76
+
77
+ def [](key)
78
+ @data[key]
79
+ end
80
+
81
+ def []=(key, val)
82
+ @data[key] = val
83
+ end
84
+
85
+ protected
86
+
87
+ def serialize(data)
88
+ data.to_hash
89
+ end
90
+
91
+ def deserialize(data)
92
+ Hashie::Mash.new(data)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,28 @@
1
+ module Hyrb
2
+ module Models
3
+ class AnsibleHost < Model
4
+ attr_accessor :host, :ansible_ssh_host, :ansible_ssh_user
5
+
6
+ def initialize(project, environment)
7
+ @path = File.join(project.ansible_path, "hosts")
8
+ @data = deserialize(load_config_file) || []
9
+ self.host = environment.label
10
+ self.ansible_ssh_host = environment.host
11
+ # TODO: this should be different on eg EC2
12
+ self.ansible_ssh_user = "root"
13
+ end
14
+
15
+ def serialize(data)
16
+ # remove the host that we're working on
17
+ data.reject! { |h| h["host"] == host }
18
+ data += [{
19
+ host: host,
20
+ vars: {
21
+ ansible_ssh_host: ansible_ssh_host,
22
+ ansible_ssh_user: ansible_ssh_user,
23
+ }.stringify_keys,
24
+ }.stringify_keys]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ module Hyrb
2
+ module Models
3
+ class AnsibleSite < Struct
4
+ attr_accessor :vars_prompt, :roles, :hosts
5
+
6
+ define_keys %w( project_name
7
+ host
8
+ deploy_user
9
+ base_path
10
+ domain
11
+ relative_web_root
12
+ mysql_host
13
+ mysql_db
14
+ mysql_user
15
+ mysql_password )
16
+
17
+ def initialize(project, environment)
18
+ @path = File.join(project.ansible_path, environment.label)
19
+ @raw_playbook = load_config_file[0]
20
+ @data = deserialize(@raw_playbook)
21
+
22
+ @vars_prompt = @raw_playbook["vars_prompt"]
23
+ @roles = @raw_playbook["roles"]
24
+ @hosts = @raw_playbook["hosts"]
25
+ end
26
+
27
+ def load_config_file
28
+ super || YAML.load_file("#{TEMPLATE_PATH}/ansible/site.yml")
29
+ end
30
+
31
+ def serialize(data)
32
+ # yuck, this is no longer a pure fn
33
+ @raw_playbook["vars_prompt"] = vars_prompt
34
+ @raw_playbook["roles"] = roles
35
+ @raw_playbook["hosts"] = hosts
36
+
37
+ @raw_playbook["vars"] = @data.map { |k, v| {k.to_s => v} }
38
+ [@raw_playbook]
39
+ end
40
+
41
+ def deserialize(data)
42
+ data["vars"].reduce(Hash.new, :merge)
43
+ end
44
+ end
45
+ end
46
+ end