hyrb 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|