jupiter 0.0.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,39 @@
1
+ module Jupiter
2
+ class Template
3
+
4
+ attr_reader :location, :sshuser, :sshpass, :sshport, :host, :vmhost
5
+
6
+ def initialize(vmhost)
7
+ @vmhost = vmhost
8
+ @location = Jupiter.templates.fetch(:location)
9
+ @sshuser = Jupiter.templates.fetch(:sshuser)
10
+ @sshpass = Jupiter.templates.fetch(:sshpass)
11
+ @sshport = Jupiter.templates.fetch(:sshport)
12
+ @host = Jupiter.templates.fetch(:host)
13
+ end
14
+
15
+ def templates_list
16
+ template_list = ssh.exec!("ls #{@location}").to_s
17
+ close_ssh
18
+ array_of_templates= template_list.split("\n")
19
+ array_of_templates.select! { |x| x.include? '.tar.gz'}
20
+ end
21
+
22
+ def transfer_template(file, new_name)
23
+ ssh.exec!("scp -P #{@vmhost.sshport} #{location}/#{file}.tar.gz #{@vmhost.sshuser}@#{@vmhost.host}:#{@vmhost.vmpath}/")
24
+ close_ssh
25
+ @vmhost.setup_template(file, new_name)
26
+ end
27
+
28
+ def ssh
29
+ @ssh ||= Net::SSH.start(@host, @sshuser, password: @sshpass, port: @sshport)
30
+ end
31
+
32
+ def close_ssh
33
+ ssh.close
34
+ @ssh = nil
35
+ true
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,20 @@
1
+ require 'digest/md5'
2
+ module Jupiter
3
+ class UUID
4
+
5
+ def pad(text)
6
+ v = text * (1 + (64 / text.length))
7
+ v[0,64]
8
+ end
9
+
10
+ def generate(text)
11
+ v = Digest::MD5.hexdigest(pad(text))
12
+ v.gsub!(/(.{2})(?=.)/, '\1 \2')
13
+ v.insert 23, "-"
14
+ v.slice!(24)
15
+ return v
16
+ end
17
+
18
+ end
19
+ end
20
+
@@ -1,3 +1,3 @@
1
1
  module Jupiter
2
- VERSION = "0.0.1"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -0,0 +1,123 @@
1
+ module Jupiter
2
+ class VirtualMachine
3
+
4
+ attr_reader :deploy_user, :deploy_pass, :sudo_user, :sudo_pass
5
+ attr_accessor :ip, :port
6
+
7
+ def initialize(ip, port)
8
+ @deploy_user = Jupiter.vmusers.fetch(:deploy_user)
9
+ @deploy_pass = Jupiter.vmusers.fetch(:deploy_pass)
10
+ @sudo_user = Jupiter.vmusers.fetch(:sudo_user)
11
+ @sudo_pass = Jupiter.vmusers.fetch(:sudo_pass)
12
+ self.ip = ip
13
+ self.port = port
14
+ end
15
+
16
+ def ssh_deploy
17
+ @ssh_deploy ||= Net::SSH.start(ip, @deploy_user, password: @deploy_pass, port: port)
18
+ end
19
+
20
+ def close_ssh_deploy
21
+ ssh_deploy.close
22
+ @ssh_deploy = nil
23
+ true
24
+ end
25
+
26
+ def get_users_groups(user)
27
+ groups = ssh_deploy.exec!(%Q[id -nG #{user}]).chomp.split(/ /)
28
+ end
29
+
30
+ def remove_from_sudo_group(user)
31
+ result = ssh_deploy.exec!(%Q[sudo gpasswd -d #{user} sudo])
32
+ end
33
+
34
+ def rename_linux_guest(newname)
35
+ old_hostname = ssh_deploy.exec!("hostname").to_s.chomp
36
+ puts %Q[\nCurrent hostname is: #{old_hostname}\n]
37
+ ssh_deploy.exec!(%Q[sudo /bin/hostname #{newname}])
38
+ ssh_deploy.exec!(%Q[sudo /bin/chmod 666 /etc/hostname])
39
+ ssh_deploy.exec!(%Q[sudo /bin/echo '#{newname}' > /etc/hostname])
40
+ ssh_deploy.exec!(%Q[sudo /bin/chmod 644 /etc/hostname])
41
+ ssh_deploy.exec!(%Q[sudo /bin/chmod 666 /etc/hosts])
42
+ ssh_deploy.exec!(%Q[sudo /bin/sed -i 's|#{old_hostname}|#{newname}|g' /etc/hosts])
43
+ ssh_deploy.exec!(%Q[sudo /bin/chmod 644 /etc/hosts])
44
+ ssh_deploy.exec!(%Q[sudo /etc/init.d/hostname restart])
45
+ puts %Q[\nNew hostname is....]
46
+ puts ssh_deploy.exec!("hostname")
47
+ close_ssh_deploy
48
+ puts %Q[\nFinished changing hostname.]
49
+ end
50
+
51
+ def resize_lvm_volume_step_1
52
+ partitions = read_output_lines('sudo fdisk -l /dev/sda')
53
+ lvm_partition = detect_lvm_partition(partitions)
54
+ lvm_partition_number = lvm_partition.tr!('^0-9', '')
55
+ cylinders = detect_cylinders(partitions)
56
+
57
+ ssh_deploy.exec!(%Q[sudo /sbin/fdisk /dev/sda]) do |channel, stream, data|
58
+ channel.send_data(%Q[p\n])
59
+ channel.send_data(%Q[d\n])
60
+ channel.send_data(%Q[#{lvm_partition_number}\n])
61
+ channel.send_data(%Q[n\n])
62
+ channel.send_data(%Q[p\n])
63
+ channel.send_data(%Q[#{lvm_partition_number}\n])
64
+ channel.send_data(%Q[\n])
65
+ channel.send_data(%Q[\n])
66
+ channel.send_data(%Q[t\n])
67
+ channel.send_data(%Q[#{lvm_partition_number}\n])
68
+ channel.send_data(%Q[8e\n])
69
+ channel.send_data(%Q[w\n])
70
+ end
71
+ close_ssh_deploy
72
+ result = "\nThe system needs to reboot to read the new partition table. Please wait...\n"
73
+ # VM must be rebooted before moving on to step 2.
74
+ end
75
+
76
+ def resize_lvm_volume_step_2
77
+ partitions = read_output_lines('sudo fdisk -l /dev/sda')
78
+ lvm_partition = detect_lvm_partition(partitions)
79
+ pvs = ssh_deploy.exec!(%Q[sudo pvs])
80
+ pvresize = ssh_deploy.exec!(%Q[sudo pvresize #{lvm_partition}])
81
+ vgs = ssh_deploy.exec!(%Q[sudo vgs])
82
+ logical_vol = detect_lvm_group_path
83
+ lvextend = ssh_deploy.exec!(%Q[sudo lvextend -l +100%FREE #{logical_vol}])
84
+ resize2fs = ssh_deploy.exec!(%Q[sudo resize2fs #{logical_vol}])
85
+ close_ssh_deploy
86
+ result = "\n#{pvresize}\n\n#{vgs}\n\n#{lvextend}\n\n#{resize2fs}\n"
87
+ end
88
+
89
+ def detect_lvm_group_path
90
+ df_output = read_output_lines('df -h')
91
+ lvm_path = array_element(df_output, '/dev/mapper/')
92
+ raise CantFindLogicalVolPathError.new("Can't detect path to logical volume where the root partition resides.") if lvm_path.kind_of?(Array)
93
+ return lvm_path.split[0]
94
+ end
95
+
96
+ def detect_lvm_partition(fdisk_output)
97
+ lvm_entry = array_element(fdisk_output, '8e Linux LVM')
98
+ raise InvalidLVMError.new("No LVM partition detected.") if lvm_entry.kind_of?(Array)
99
+ return lvm_entry.split[0]
100
+ end
101
+
102
+ def detect_cylinders(fdisk_output)
103
+ cylinder_entry = array_element(fdisk_output, '255 heads, 63 sectors')
104
+ raise InvalidCylindersError.new("There was an error retrieving the cylinders information.") if cylinder_entry.kind_of?(Array)
105
+ seperated_entries = cylinder_entry.split(',')
106
+ cylinder_count = array_element(seperated_entries, 'cylinders')
107
+ return cylinder_count.tr!('^.0-9', '')
108
+ end
109
+
110
+ def read_output_lines(command)
111
+ output = ssh_deploy.exec!(command).to_s
112
+ output.split("\n")
113
+ end
114
+
115
+ def array_element(array, some_string)
116
+ array.each { |x| return x.to_s if x.include? some_string }
117
+ end
118
+
119
+ class InvalidLVMError < StandardError; end
120
+ class InvalidCylindersError < StandardError; end
121
+ class CantFindLogicalVolPathError < StandardError; end
122
+ end
123
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe Jupiter::Input do
4
+
5
+ it "is a class" do
6
+ expect(Jupiter::Input).to be_a(Class)
7
+ end
8
+
9
+ it "can clean a file name" do
10
+ file = Jupiter::Input.new.clean_filename('This is a filename &%$!12()LOL')
11
+ expect(file).to eq('This-is-a-filename-12LOL')
12
+ end
13
+ end
14
+
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe Jupiter::Host do
4
+
5
+ let(:options) { {:name => 'TestHost', :vmpath => '/vmfs/test_path', :host => '192.168.11.11', :sshport => '22', :sshuser => 'TestUser', :sshpass => 'TestPass', :dcname => 'TestDCName' }}
6
+
7
+ it "is a class" do
8
+ expect(Jupiter::Host).to be_a(Class)
9
+ end
10
+
11
+ it "should recieve the correct credentials" do
12
+ testssh = Jupiter::Host.new(options)
13
+ expect(testssh).instance_of?(Class)
14
+ Net::SSH.should_receive(:start).with("192.168.11.11", "TestUser", {:password=>"TestPass", :port=>"22"})
15
+ testssh.ssh
16
+ end
17
+
18
+ it "can generate a valid mac address" do
19
+ mac_regex = /^([0-9a-f]{2}([:-]|$)){6}$/i
20
+ mac = Jupiter::Host.new(options).generate_mac_address
21
+ mac.should =~ mac_regex
22
+ end
23
+
24
+ it "can flatten a hash" do
25
+ hash_to_flatten = {:foo => 'bar', :red => 'dwarf', :yoda => 'dork with the force'}
26
+ string = Jupiter::Host.new(options).flatten_hash(hash_to_flatten)
27
+ expect(string).to eq(%Q[foo = "bar"\nred = "dwarf"\nyoda = "dork with the force"])
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+
3
+ describe Jupiter::Nagios do
4
+
5
+ it "is a class" do
6
+ expect(Jupiter::Nagios).to be_a(Class)
7
+ end
8
+
9
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ describe Jupiter::UUID do
4
+
5
+ it "correctly calculates a VMWare style UUID" do
6
+ expect(Jupiter::UUID.new.generate('TestSeedForGeneratingUUID')).to eq('74 06 6c fa 54 fe a4 1d-1a e2 88 25 c3 c9 31 4d')
7
+ end
8
+
9
+ it "is a class" do
10
+ expect(Jupiter::UUID).to be_a(Class)
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe Jupiter::VirtualMachine do
4
+
5
+ let(:ip) { '192.168.11.1111' }
6
+ let(:port) { '2500' }
7
+
8
+ it "is a class" do
9
+ expect(Jupiter::VirtualMachine).to be_a(Class)
10
+ end
11
+
12
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe Jupiter do
4
+ it "is a module" do
5
+ expect(Jupiter).to be_a(Module)
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ $:.unshift("./lib")
2
+ require "jupiter"
3
+
4
+ RSpec.configure do |config|
5
+ config.treat_symbols_as_metadata_keys_with_true_values = true
6
+ config.run_all_when_everything_filtered = true
7
+ config.filter_run :focus
8
+
9
+ # Run specs in random order to surface order dependencies. If you find an
10
+ # order dependency and want to debug it, you can fix the order by providing
11
+ # the seed, which is printed after each run.
12
+ # --seed 1234
13
+ config.order = 'random'
14
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jupiter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,25 +10,141 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-07 00:00:00.000000000 Z
14
- dependencies: []
13
+ date: 2013-05-01 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rbvmomi
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.6.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 1.6.0
31
+ - !ruby/object:Gem::Dependency
32
+ name: net-ssh
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 2.6.5
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 2.6.5
47
+ - !ruby/object:Gem::Dependency
48
+ name: net-scp
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.1.0
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 1.1.0
63
+ - !ruby/object:Gem::Dependency
64
+ name: thor
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: 0.17.0
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 0.17.0
79
+ - !ruby/object:Gem::Dependency
80
+ name: pry
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: 0.9.11.4
87
+ type: :runtime
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: 0.9.11.4
95
+ - !ruby/object:Gem::Dependency
96
+ name: rspec
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 2.12.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 2.12.0
15
111
  description: Automated vSphere deployment in ruby
16
112
  email:
17
113
  - marshall.wright.boyce@gmail.com
18
114
  - adamhunter@me.com
19
- executables: []
115
+ executables:
116
+ - jupiter
20
117
  extensions: []
21
118
  extra_rdoc_files: []
22
119
  files:
23
120
  - .gitignore
121
+ - .rspec
24
122
  - .rvmrc
25
123
  - Gemfile
26
124
  - LICENSE.txt
27
125
  - README.md
28
126
  - Rakefile
127
+ - bin/jupiter
128
+ - config.yaml.example
29
129
  - jupiter.gemspec
30
130
  - lib/jupiter.rb
131
+ - lib/jupiter/cli.rb
132
+ - lib/jupiter/cli/colorizer.rb
133
+ - lib/jupiter/cli/output.rb
134
+ - lib/jupiter/configuration.rb
135
+ - lib/jupiter/host.rb
136
+ - lib/jupiter/nagios.rb
137
+ - lib/jupiter/template.rb
138
+ - lib/jupiter/uuid.rb
31
139
  - lib/jupiter/version.rb
140
+ - lib/jupiter/virtualmachine.rb
141
+ - spec/jupiter/cli_spec.rb
142
+ - spec/jupiter/host_spec.rb
143
+ - spec/jupiter/nagios_spec.rb
144
+ - spec/jupiter/uuid_spec.rb
145
+ - spec/jupiter/virtualmachine_spec.rb
146
+ - spec/jupiter_spec.rb
147
+ - spec/spec_helper.rb
32
148
  homepage: https://github.com/tma1/jupiter
33
149
  licenses: []
34
150
  post_install_message:
@@ -49,9 +165,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
165
  version: '0'
50
166
  requirements: []
51
167
  rubyforge_project:
52
- rubygems_version: 1.8.24
168
+ rubygems_version: 1.8.23
53
169
  signing_key:
54
170
  specification_version: 3
55
171
  summary: Deploy vSphere slices and configure them automatically using a combination
56
172
  of tools in ruby.
57
- test_files: []
173
+ test_files:
174
+ - spec/jupiter/cli_spec.rb
175
+ - spec/jupiter/host_spec.rb
176
+ - spec/jupiter/nagios_spec.rb
177
+ - spec/jupiter/uuid_spec.rb
178
+ - spec/jupiter/virtualmachine_spec.rb
179
+ - spec/jupiter_spec.rb
180
+ - spec/spec_helper.rb