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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +8 -0
- data/bin/hyrb +9 -0
- data/hyrb.gemspec +35 -0
- data/lib/hyrb/cli.rb +27 -0
- data/lib/hyrb/command.rb +74 -0
- data/lib/hyrb/commands/ansible.rb +13 -0
- data/lib/hyrb/commands/creds.rb +20 -0
- data/lib/hyrb/commands/defaults.rb +20 -0
- data/lib/hyrb/commands/developers.rb +15 -0
- data/lib/hyrb/commands/digital_ocean.rb +15 -0
- data/lib/hyrb/commands/environment.rb +11 -0
- data/lib/hyrb/commands/github.rb +15 -0
- data/lib/hyrb/commands/hipchat.rb +20 -0
- data/lib/hyrb/commands/project.rb +36 -0
- data/lib/hyrb/commands/provision.rb +17 -0
- data/lib/hyrb/commands/rackspace.rb +11 -0
- data/lib/hyrb/model.rb +96 -0
- data/lib/hyrb/models/ansible_host.rb +28 -0
- data/lib/hyrb/models/ansible_site.rb +46 -0
- data/lib/hyrb/models/cache.rb +35 -0
- data/lib/hyrb/models/creds.rb +24 -0
- data/lib/hyrb/models/defaults.rb +11 -0
- data/lib/hyrb/models/developer.rb +28 -0
- data/lib/hyrb/models/environment.rb +41 -0
- data/lib/hyrb/models/project.rb +35 -0
- data/lib/hyrb/pipeline.rb +63 -0
- data/lib/hyrb/task.rb +46 -0
- data/lib/hyrb/tasks/ansible.rb +96 -0
- data/lib/hyrb/tasks/creds.rb +39 -0
- data/lib/hyrb/tasks/defaults.rb +43 -0
- data/lib/hyrb/tasks/developers.rb +120 -0
- data/lib/hyrb/tasks/digital_ocean.rb +84 -0
- data/lib/hyrb/tasks/environment.rb +56 -0
- data/lib/hyrb/tasks/github.rb +120 -0
- data/lib/hyrb/tasks/google.rb +15 -0
- data/lib/hyrb/tasks/hipchat.rb +76 -0
- data/lib/hyrb/tasks/project/bootstrap.rb +88 -0
- data/lib/hyrb/tasks/project.rb +48 -0
- data/lib/hyrb/tasks/provision.rb +91 -0
- data/lib/hyrb/tasks/rackspace.rb +95 -0
- data/lib/hyrb/version.rb +3 -0
- data/lib/hyrb.rb +18 -0
- data/lib/templates/ansible/Vagrantfile.erb +21 -0
- data/lib/templates/ansible/roles/db/handlers/main.yml +2 -0
- data/lib/templates/ansible/roles/db/tasks/main.yml +24 -0
- data/lib/templates/ansible/roles/lamp/tasks/main.yml +53 -0
- data/lib/templates/ansible/roles/lamp.yml +6 -0
- data/lib/templates/ansible/roles/site/handlers/main.yml +3 -0
- data/lib/templates/ansible/roles/site/tasks/db.yml +23 -0
- data/lib/templates/ansible/roles/site/tasks/main.yml +16 -0
- data/lib/templates/ansible/roles/site/templates/vhost.conf.j2 +24 -0
- data/lib/templates/ansible/site.yml +10 -0
- data/lib/templates/roles/db/handlers/main.yml +2 -0
- data/lib/templates/roles/db/tasks/main.yml +24 -0
- data/lib/templates/roles/lamp/tasks/main.yml +36 -0
- data/lib/templates/roles/lamp.yml +6 -0
- data/lib/templates/roles/site/handlers/main.yml +3 -0
- data/lib/templates/roles/site/tasks/db.yml +23 -0
- data/lib/templates/roles/site/tasks/main.yml +16 -0
- data/lib/templates/roles/site/templates/vhost.conf.j2 +24 -0
- data/spec/hyrb/pipeline_spec.rb +91 -0
- data/spec/spec_helper.rb +5 -0
- metadata +295 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
module Hyrb
|
2
|
+
module Tasks
|
3
|
+
module Environment
|
4
|
+
class Inject < Task
|
5
|
+
depends Project::Init
|
6
|
+
|
7
|
+
def run(env)
|
8
|
+
unless env.environment_name
|
9
|
+
if env.project.environments.any?
|
10
|
+
say "Environments: #{env.project.environments.keys.join(", ")}"
|
11
|
+
end
|
12
|
+
|
13
|
+
env.environment_name = ask "Environment", default: "production"
|
14
|
+
end
|
15
|
+
|
16
|
+
env.environment = Hyrb::Models::Environment.new(env.project, env.environment_name)
|
17
|
+
env.environment.label = env.project.name
|
18
|
+
env.environment.label += "-#{env.environment_name}" unless env.environment_name == "production"
|
19
|
+
|
20
|
+
prompt "Domain (FQDN)", env.environment, :domain, "#{env.environment.label}.#{env.defaults.domain}"
|
21
|
+
|
22
|
+
env.environment.save!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Init < Task
|
27
|
+
depends Inject
|
28
|
+
end
|
29
|
+
|
30
|
+
class SetupExisting < Task
|
31
|
+
depends Init
|
32
|
+
|
33
|
+
prompt :environment, :host, default: ->(env) { env.environment.domain }
|
34
|
+
end
|
35
|
+
|
36
|
+
class Deployment < Task
|
37
|
+
depends SetupExisting
|
38
|
+
|
39
|
+
prompt :environment, :deploy_user, default: "deploy"
|
40
|
+
prompt :environment, :base_path, default: "/var/www"
|
41
|
+
prompt :environment, :relative_web_root, default: "/current/public"
|
42
|
+
|
43
|
+
def run(env)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Database < Task
|
48
|
+
depends Deployment
|
49
|
+
|
50
|
+
prompt :environment, :database_host, default: "localhost"
|
51
|
+
prompt :environment, :database_name, default: ->(env) { env.environment.label.underscore }
|
52
|
+
prompt :environment, :database_user, default: ->(env) { env.environment.label.underscore }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
|
3
|
+
module Hyrb
|
4
|
+
module Tasks
|
5
|
+
module Github
|
6
|
+
class Inject < Task
|
7
|
+
depends Creds::Init
|
8
|
+
|
9
|
+
prompt :creds, :github_org
|
10
|
+
prompt :creds, :github_api_key
|
11
|
+
|
12
|
+
def run(env)
|
13
|
+
env.github_client = Octokit::Client.new({
|
14
|
+
access_token: env.creds.github_api_key,
|
15
|
+
auto_pagination: true,
|
16
|
+
})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Init < Task
|
21
|
+
depends Inject
|
22
|
+
end
|
23
|
+
|
24
|
+
class Repos < Task
|
25
|
+
depends Init
|
26
|
+
|
27
|
+
def run(env)
|
28
|
+
env.github_repos = env.github_client.org_repos(per_page: 100, org: env.creds.github_org)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ShowRepos < Task
|
33
|
+
depends Repos
|
34
|
+
|
35
|
+
def run(env)
|
36
|
+
say env.github_repos.map(&:name).to_yaml
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class CreateRepo < Task
|
41
|
+
depends Init, Project::Init
|
42
|
+
|
43
|
+
prompt :project, :github_org, default: ->(env) { env.creds.github_org }
|
44
|
+
prompt :project, :repo_name, default: ->(env) { env.project.name }
|
45
|
+
|
46
|
+
def run(env)
|
47
|
+
if env.github_repo = env.github_client.repository?(env.project.repo_path)
|
48
|
+
say "Github repo #{env.project.repo_path} exists", :yellow
|
49
|
+
else
|
50
|
+
# TODO: gitignore, teams
|
51
|
+
env.github_repo = env.github_client.create(env.project.repo_name, {
|
52
|
+
organization: env.project.github_org,
|
53
|
+
description: env.project.description,
|
54
|
+
private: true,
|
55
|
+
})
|
56
|
+
say "Created Github repo #{env.project.repo_path}", :green
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class CreateProjectTeam < Task
|
62
|
+
depends CreateRepo, Developers::Init
|
63
|
+
|
64
|
+
prompt :project, :github_team, default: ->(env) { env.project.repo_name }
|
65
|
+
|
66
|
+
def run(env)
|
67
|
+
env.github_team = env.github_client.organization_teams(env.project.github_org).find do |t|
|
68
|
+
t.name == env.project.github_team
|
69
|
+
end
|
70
|
+
|
71
|
+
if env.github_team
|
72
|
+
say "Github team #{env.project.github_team} exists", :yellow
|
73
|
+
else
|
74
|
+
env.github_team = env.github_client.create_team(env.project.github_org, {
|
75
|
+
name: env.project.github_team,
|
76
|
+
repo_names: [env.project.repo_name],
|
77
|
+
permission: "push"
|
78
|
+
})
|
79
|
+
say "Created Github team #{env.project.github_team} exists", :green
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class SyncProjectTeam < Task
|
85
|
+
depends CreateProjectTeam
|
86
|
+
|
87
|
+
def run(env)
|
88
|
+
team = env.github_team
|
89
|
+
new_devs = env.project.developers(env.developers)
|
90
|
+
current_members = env.github_client.team_members(team.id)
|
91
|
+
|
92
|
+
members_to_remove = current_members.reject do |member|
|
93
|
+
new_devs.map(&:github_username).include?(member.login)
|
94
|
+
end
|
95
|
+
|
96
|
+
devs_to_add = new_devs.reject do |dev|
|
97
|
+
current_members.map(&:login).include?(dev.github_username)
|
98
|
+
end
|
99
|
+
|
100
|
+
members_to_remove.each do |member|
|
101
|
+
if env.github_client.remove_team_member(team.id, member.login)
|
102
|
+
say "Removed #{member.login} from team #{env.project.github_org}/#{team.slug}", :green
|
103
|
+
else
|
104
|
+
say "Couldn't remove #{member.login} from team #{env.project.github_org}/#{team.slug}", :red
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
devs_to_add.each do |dev|
|
109
|
+
if env.github_client.add_team_member(team.id, dev.github_username)
|
110
|
+
say "Added #{dev.github_username} to team #{env.project.github_org}/#{team.slug}", :green
|
111
|
+
else
|
112
|
+
say "Couldn't add #{dev.github_username} to team #{env.project.github_org}/#{team.slug}", :red
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hyrb
|
2
|
+
module Tasks
|
3
|
+
module Google
|
4
|
+
class Init < Task
|
5
|
+
# depends Inject
|
6
|
+
depends Creds::Init
|
7
|
+
|
8
|
+
prompt :creds, :google_client_id
|
9
|
+
prompt :creds, :google_client_secret
|
10
|
+
prompt :creds, :google_refresh_token
|
11
|
+
prompt :creds, :google_spreadsheet_key
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'hipchat-api'
|
2
|
+
|
3
|
+
module Hyrb
|
4
|
+
module Tasks
|
5
|
+
module Hipchat
|
6
|
+
class Inject < Task
|
7
|
+
depends Creds::Init
|
8
|
+
|
9
|
+
prompt :creds, :hipchat_api_key
|
10
|
+
|
11
|
+
def run(env)
|
12
|
+
env.hipchat_client = HipChat::API.new(env.creds.hipchat_api_key)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Init < Task
|
17
|
+
depends Inject
|
18
|
+
end
|
19
|
+
|
20
|
+
class Rooms < Task
|
21
|
+
depends Init
|
22
|
+
|
23
|
+
def run(env)
|
24
|
+
env.hipchat_rooms = env.hipchat_client.rooms_list['rooms']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class ShowRooms < Task
|
29
|
+
depends Rooms
|
30
|
+
|
31
|
+
def run(env)
|
32
|
+
say env.hipchat_rooms.map { |r| "#{r.name} (#{r.room_id})" }.to_yaml
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class CreateRoom < Task
|
37
|
+
depends Rooms, Project::Init
|
38
|
+
|
39
|
+
prompt :project, :room_name, default: ->(env) { env.project.title }
|
40
|
+
prompt :creds, :hipchat_user_id
|
41
|
+
|
42
|
+
def run(env)
|
43
|
+
# TODO: should unarchive room if it exists
|
44
|
+
if env.hipchat_rooms.any? { |r| r.name == env.project.room_name }
|
45
|
+
say "HipChat room #{env.project.room_name} exists", :yellow
|
46
|
+
else
|
47
|
+
env.hipchat_client.rooms_create(env.project.room_name, env.creds.hipchat_user_id,
|
48
|
+
'public', env.project.description)
|
49
|
+
say "Created HipChat room #{env.project.room_name}", :green
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class ArchiveOldRooms < Task
|
55
|
+
depends Rooms
|
56
|
+
|
57
|
+
def run(env)
|
58
|
+
floor = Time.now - 3.months
|
59
|
+
say "Listing all unarchived room last active before #{floor}"
|
60
|
+
say "CTRL+C to exit"
|
61
|
+
old_rooms = env.hipchat_rooms.select do |room|
|
62
|
+
room["is_archived"] == false && room["last_active"] < floor.to_i
|
63
|
+
end
|
64
|
+
|
65
|
+
old_rooms.each do |room|
|
66
|
+
if yes? "Archive #{room["name"]}? (last active at #{Time.at(room["last_active"])})"
|
67
|
+
say "Hipchat does not support archiving rooms via the API :(", :red
|
68
|
+
else
|
69
|
+
say "Spared #{room["name"]}", :yellow
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Hyrb
|
2
|
+
module Tasks
|
3
|
+
module Project
|
4
|
+
class CreateHipchatHook < Task
|
5
|
+
depends Hipchat::CreateRoom, Github::CreateRepo
|
6
|
+
|
7
|
+
def run(env)
|
8
|
+
hook = env.github_client.create_hook(env.project.repo_path, 'hipchat', {
|
9
|
+
room: env.project.room_name,
|
10
|
+
auth_token: env.creds.hipchat_api_key,
|
11
|
+
},{
|
12
|
+
active: true,
|
13
|
+
events: %w( commit_comment gollum issues issue_comment pull_request
|
14
|
+
pull_request_review_comment push team_add ),
|
15
|
+
})
|
16
|
+
|
17
|
+
say "Created HipChat hook linking #{env.project.repo_path} to #{env.project.room_name}", :green
|
18
|
+
env.github_client.test_hook(env.project.repo_path, hook.id)
|
19
|
+
say "Test post sent!", :green
|
20
|
+
env.project.has_hipchat_hook = true
|
21
|
+
env.project.save!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Bootstrap < Task
|
26
|
+
depends Project::Init
|
27
|
+
|
28
|
+
def run(env)
|
29
|
+
prompt "Project title", env.project, :title, env.project.name.humanize
|
30
|
+
prompt "Project description", env.project, :description
|
31
|
+
|
32
|
+
if ! env.project.users.try(:any?) || yes?("Update users for this project?")
|
33
|
+
invoke Developers::Download
|
34
|
+
invoke Developers::AddToProject
|
35
|
+
end
|
36
|
+
|
37
|
+
if ! env.project.repo_name && yes?("Should the project have a Github repo?")
|
38
|
+
invoke Github::CreateRepo
|
39
|
+
end
|
40
|
+
|
41
|
+
if ! env.project.github_team && yes?("Should the project have a Github team?")
|
42
|
+
invoke Github::CreateProjectTeam
|
43
|
+
end
|
44
|
+
|
45
|
+
if env.project.github_team
|
46
|
+
invoke Github::SyncProjectTeam
|
47
|
+
end
|
48
|
+
|
49
|
+
if ! env.project.room_name
|
50
|
+
invoke Hipchat::CreateRoom if yes? "Should the project have a Hipchat room?"
|
51
|
+
end
|
52
|
+
|
53
|
+
if env.project.repo_name && env.project.room_name && ! env.project.has_hipchat_hook
|
54
|
+
invoke CreateHipchatHook
|
55
|
+
end
|
56
|
+
|
57
|
+
if env.environment_name || yes?("Work on a project environment?")
|
58
|
+
invoke Environment::Init
|
59
|
+
|
60
|
+
if env.environment.host
|
61
|
+
say "Sever for evironment exists: #{env.environment.host}", :yellow
|
62
|
+
elsif yes?("Provision a server for this environment?")
|
63
|
+
provisioners = {
|
64
|
+
digital_ocean: Provision::DigitalOcean,
|
65
|
+
rackspace: Provision::Rackspace,
|
66
|
+
}
|
67
|
+
|
68
|
+
provider_name = ask "Provider:", { limited_to: provisioners.keys.map(&:to_s) }
|
69
|
+
invoke provisioners[provider_name.to_sym]
|
70
|
+
end
|
71
|
+
|
72
|
+
if ! env.environment.has_dns_record && yes?("Create a DNS record?")
|
73
|
+
invoke Rackspace::CreateDNSRecord
|
74
|
+
end
|
75
|
+
|
76
|
+
invoke Environment::SetupExisting
|
77
|
+
|
78
|
+
if yes? "Set up ansible for this environment?"
|
79
|
+
invoke Ansible::CreatePlaybook
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Hyrb
|
2
|
+
module Tasks
|
3
|
+
module Project
|
4
|
+
autoload :Bootstrap, "hyrb/tasks/project/bootstrap"
|
5
|
+
|
6
|
+
class Inject < Task
|
7
|
+
depends Creds::Init
|
8
|
+
|
9
|
+
def run(env)
|
10
|
+
env.project = Hyrb::Models::Project.new(env.project_name || ask("Project name"))
|
11
|
+
env.project.save!
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Init < Task
|
16
|
+
depends Project::Inject
|
17
|
+
end
|
18
|
+
|
19
|
+
class Show < Task
|
20
|
+
depends Project::Init
|
21
|
+
|
22
|
+
def run(env)
|
23
|
+
say env.project.data.to_hash.to_yaml
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Edit < Task
|
28
|
+
depends Project::Init
|
29
|
+
|
30
|
+
def run(env)
|
31
|
+
edit(env.project.filepath)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Create < Task
|
36
|
+
depends Project::Init
|
37
|
+
|
38
|
+
def run(env)
|
39
|
+
prompt "Project title", env.project, :title, env.project.name.humanize
|
40
|
+
prompt "Project description", env.project, :description
|
41
|
+
prompt "Github org", env.project, :github_org, env.creds.github_org
|
42
|
+
prompt "Github repo", env.project, :repo_name, env.project.name
|
43
|
+
prompt "Hipchat room", env.project, :room_name, env.project.name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'fog/digitalocean'
|
2
|
+
require 'fog/rackspace'
|
3
|
+
require 'parallel'
|
4
|
+
|
5
|
+
module Hyrb
|
6
|
+
module Tasks
|
7
|
+
module Provision
|
8
|
+
class Init < Task
|
9
|
+
depends Environment::Init
|
10
|
+
|
11
|
+
prompt :environment, :server_name, default: ->(env) { env.environment.domain || env.environment.label }
|
12
|
+
end
|
13
|
+
|
14
|
+
class DigitalOcean < Task
|
15
|
+
depends Init, Hyrb::Tasks::DigitalOcean::SSHKeys, Developers::AddToProject
|
16
|
+
|
17
|
+
def run(env)
|
18
|
+
ssh_key_ids = env.project.developers(env.developers).map(&:digital_ocean_id).compact
|
19
|
+
|
20
|
+
flavor_id = option_list(env.digital_ocean_cache, :flavors, 2) do |f, i|
|
21
|
+
"#{i+1}: #{f.name} ram / #{f.cpu} cpu / #{'$%.2f/mo' % f.cost_per_month}"
|
22
|
+
end.id
|
23
|
+
|
24
|
+
image_id = option_list(env.digital_ocean_cache, :images, 16) do |f, i|
|
25
|
+
"#{i+1}: #{f.name} / id: #{f.id}"
|
26
|
+
end.id
|
27
|
+
|
28
|
+
region_id = option_list(env.digital_ocean_cache, :regions, 2) do |f, i|
|
29
|
+
"#{i+1}: #{f.name} / id: #{f.id}"
|
30
|
+
end.id
|
31
|
+
|
32
|
+
say "Creating Digital Ocean Server"
|
33
|
+
server = env.digital_ocean_client.servers.create({
|
34
|
+
name: env.environment.server_name,
|
35
|
+
flavor_id: flavor_id,
|
36
|
+
image_id: image_id,
|
37
|
+
region_id: region_id,
|
38
|
+
ssh_key_ids: ssh_key_ids,
|
39
|
+
})
|
40
|
+
|
41
|
+
env.environment.provider = 'digital_ocean'
|
42
|
+
env.environment.server_id = server.id
|
43
|
+
|
44
|
+
sleep(4) until server.reload.ready?
|
45
|
+
env.environment.host = server.public_ip_address
|
46
|
+
|
47
|
+
env.environment.save!
|
48
|
+
|
49
|
+
say "Created Digital Ocean Server!", :green
|
50
|
+
say "IP Address: #{server.public_ip_address} / ID: #{server.id}", :green
|
51
|
+
say "\n\tssh root@#{server.public_ip_address}\n"
|
52
|
+
beep
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Rackspace < Task
|
57
|
+
depends Init, Hyrb::Tasks::Rackspace::Init
|
58
|
+
|
59
|
+
def run(env)
|
60
|
+
flavor_id = option_list(env.rackspace_cache, :flavors, 2) do |f, i|
|
61
|
+
"#{i+1}: #{f.name} / id: #{f.id}"
|
62
|
+
end.id
|
63
|
+
|
64
|
+
image_id = option_list(env.rackspace_cache, :images, 1) do |f, i|
|
65
|
+
"#{i+1}: #{f.name} / id: #{f.id}"
|
66
|
+
end.id
|
67
|
+
|
68
|
+
say "Creating Rackspace Server"
|
69
|
+
server = env.rackspace_client.servers.create({
|
70
|
+
name: env.environment.server_name,
|
71
|
+
flavor_id: flavor_id,
|
72
|
+
image_id: image_id,
|
73
|
+
})
|
74
|
+
|
75
|
+
env.environment.provider = 'rackspace'
|
76
|
+
env.environment.server_id = server.id
|
77
|
+
|
78
|
+
sleep(6) until server.reload.ready?
|
79
|
+
env.environment.host = server.public_ip_address
|
80
|
+
|
81
|
+
env.environment.save!
|
82
|
+
|
83
|
+
say "Created Rackspace Server!", :green
|
84
|
+
say "IP Address: #{server.public_ip_address} / ID: #{server.id}", :green
|
85
|
+
say "\n\tssh root@#{server.public_ip_address}\n"
|
86
|
+
beep
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
require 'parallel'
|
4
|
+
require 'fog/rackspace'
|
5
|
+
|
6
|
+
module Hyrb
|
7
|
+
module Tasks
|
8
|
+
module Rackspace
|
9
|
+
class Inject < Task
|
10
|
+
depends Creds::Init
|
11
|
+
|
12
|
+
prompt :creds, :rackspace_username
|
13
|
+
prompt :creds, :rackspace_api_key
|
14
|
+
prompt :defaults, :rackspace_region, default: ->(env) { env.rackspace_region }
|
15
|
+
|
16
|
+
def run(env)
|
17
|
+
env.rackspace_client = Fog::Compute.new({
|
18
|
+
provider: 'rackspace',
|
19
|
+
rackspace_username: env.creds.rackspace_username,
|
20
|
+
rackspace_api_key: env.creds.rackspace_api_key,
|
21
|
+
version: :v2,
|
22
|
+
rackspace_region: env.defaults.rackspace_region,
|
23
|
+
})
|
24
|
+
|
25
|
+
env.rackspace_dns_client = Fog::DNS.new({
|
26
|
+
provider: 'rackspace',
|
27
|
+
rackspace_username: env.creds.rackspace_username,
|
28
|
+
rackspace_api_key: env.creds.rackspace_api_key,
|
29
|
+
rackspace_region: env.defaults.rackspace_region,
|
30
|
+
})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Init < Task
|
35
|
+
depends Inject
|
36
|
+
|
37
|
+
def run(env)
|
38
|
+
env.rackspace_cache = Hyrb::Models::Cache::Rackspace.new
|
39
|
+
env.rackspace_cache.class.keys.each do |key|
|
40
|
+
env.rackspace_cache[key] ||= env.rackspace_client.send(key).map(&:attributes)
|
41
|
+
end
|
42
|
+
env.rackspace_cache.save!
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class DNSZones < Task
|
47
|
+
depends Init
|
48
|
+
|
49
|
+
def run(env)
|
50
|
+
env.rackspace_dns_zones = env.rackspace_dns_client.zones
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class CreateDNSRecord < Task
|
55
|
+
depends DNSZones, Environment::Init
|
56
|
+
|
57
|
+
prompt :environment, :domain, default: ->(env) { "#{env.environment.label}.#{env.defaults.domain}" }
|
58
|
+
prompt :environment, :host
|
59
|
+
|
60
|
+
def run(env)
|
61
|
+
record_type = (IPAddr.new(env.environment.host) rescue false) ? 'A' : 'CNAME'
|
62
|
+
|
63
|
+
# assume zone is going to be x.com
|
64
|
+
proj_zone = env.environment.domain.split('.')[-2..-1].join('.')
|
65
|
+
|
66
|
+
zone = env.rackspace_dns_zones.find { |z| z.domain == proj_zone }
|
67
|
+
zone ||= env.rackspace_dns_client.zones.create({
|
68
|
+
domain: proj_zone,
|
69
|
+
email: env.defaults.admin_email,
|
70
|
+
})
|
71
|
+
|
72
|
+
record = zone.records.find do |r|
|
73
|
+
r.name == env.environment.domain && r.type == record_type
|
74
|
+
end
|
75
|
+
|
76
|
+
if record
|
77
|
+
say "Record exists: '#{record.type} #{record.name} #{record.value} (#{record.ttl})'", :yellow
|
78
|
+
else
|
79
|
+
record = zone.records.create({
|
80
|
+
name: env.environment.domain,
|
81
|
+
value: env.environment.host,
|
82
|
+
type: record_type,
|
83
|
+
ttl: 300,
|
84
|
+
})
|
85
|
+
say "Created record: '#{record.type} #{record.name} #{record.value} (#{record.ttl})'", :green
|
86
|
+
end
|
87
|
+
env.environment.has_dns_record = true
|
88
|
+
env.environment.save!
|
89
|
+
beep
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/hyrb/version.rb
ADDED
data/lib/hyrb.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'hashie/mash'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
require 'hyrb/version'
|
6
|
+
|
7
|
+
module Hyrb
|
8
|
+
DEFAULT_PATH = File.join(File.expand_path("~"), ".hyfn")
|
9
|
+
TEMPLATE_PATH = File.join(File.dirname(__FILE__), "templates")
|
10
|
+
|
11
|
+
def self.autoload_each(base, base_path, files)
|
12
|
+
files.each {|f| base.autoload f.camelcase.to_sym, "#{base_path}/#{f}" }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'hyrb/pipeline'
|
17
|
+
require 'hyrb/task'
|
18
|
+
require 'hyrb/model'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Vagrant.configure("2") do |config|
|
2
|
+
config.ssh.forward_agent = true
|
3
|
+
|
4
|
+
config.vm.box = "raring64"
|
5
|
+
config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/raring/current/raring-server-cloudimg-amd64-vagrant-disk1.box"
|
6
|
+
|
7
|
+
config.vm.hostname = "<%= project.name %>"
|
8
|
+
config.vm.network :private_network, ip: "33.33.33.10"
|
9
|
+
config.vm.provision :ansible do |ansible|
|
10
|
+
ansible.playbook = "roles/lamp.yml"
|
11
|
+
ansible.verbose = true
|
12
|
+
end
|
13
|
+
|
14
|
+
config.vm.provider :virtualbox do |provider|
|
15
|
+
# Don't boot with headless mode
|
16
|
+
# vb.gui = true
|
17
|
+
|
18
|
+
# Use VBoxManage to customize the VM. For example to change memory:
|
19
|
+
# vb.customize ["modifyvm", :id, "--memory", "1024"]
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
- name: mysql | install
|
3
|
+
apt: "pkg={{item}} state=latest"
|
4
|
+
with_items:
|
5
|
+
- mysql-client
|
6
|
+
- mysql-server
|
7
|
+
- python-mysqldb
|
8
|
+
|
9
|
+
- name: mysql | start
|
10
|
+
service: name=mysql state=started
|
11
|
+
|
12
|
+
- name: mysql | create root user
|
13
|
+
mysql_user: "name=root password=root state=present host='{{ item }}'"
|
14
|
+
with_items:
|
15
|
+
- 127.0.0.1
|
16
|
+
- "{{ ansible_hostname }}"
|
17
|
+
- ::1
|
18
|
+
- localhost
|
19
|
+
ignore_errors: true
|
20
|
+
|
21
|
+
- name: mysql | set bind address
|
22
|
+
lineinfile: regexp=^bind-address line="bind_address=0.0.0.0" dest=/etc/mysql/my.cnf state=present
|
23
|
+
notify:
|
24
|
+
- restart mysql
|