jupiter 0.0.1 → 0.8.0

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.
@@ -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