vscripts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,91 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+ require 'English'
4
+
5
+ module VScripts
6
+ module Util
7
+ # Local system functions library
8
+ module LocalSystem
9
+ # Hosts file path
10
+ def hosts_path
11
+ '/etc/hosts'
12
+ end
13
+
14
+ # Hostname file path
15
+ def hostname_path
16
+ '/etc/hostname'
17
+ end
18
+
19
+ # Returns the current fully qualified domain
20
+ def local_fqdn
21
+ `hostname -f`.strip
22
+ end
23
+
24
+ # Returns the local host name
25
+ def local_host_name
26
+ `hostname`.strip
27
+ end
28
+
29
+ # Returns the local domain name
30
+ def local_domain_name
31
+ `dnsdomainname`.strip
32
+ end
33
+
34
+ # Tries to get the reverse dns
35
+ def external_dns
36
+ ext_ip = `wget -q -O - checkip.dyndns.org \
37
+ | sed -e 's/[^[:digit:]|.]//g'`
38
+ `dig +short -x #{ext_ip}`.strip
39
+ rescue
40
+ false
41
+ end
42
+
43
+ # Creates the directory for the specified file
44
+ def ensure_file_dir(file)
45
+ path = File.dirname(file)
46
+ `mkdir -p #{path}`
47
+ end
48
+
49
+ # Writes to file
50
+ def write_file(file, body)
51
+ ensure_file_dir(file)
52
+ File.open(file, 'w') do |newfile|
53
+ newfile.write(body)
54
+ end
55
+ rescue Errno::EACCES
56
+ puts "FATAL: You need to be root in order to write to #{file}"
57
+ end
58
+
59
+ # Ensures the specified file has the specified content
60
+ def ensure_file_content(file, body)
61
+ write = write_file(file, body)
62
+ read = IO.read(file)
63
+ read == body || write
64
+ rescue
65
+ write
66
+ end
67
+
68
+ # Gets system checks from environment variables
69
+ def checks
70
+ config['SystemChecks']
71
+ rescue
72
+ {}
73
+ end
74
+
75
+ # Runs each command specified and returns the name and exit status
76
+ def process_checks
77
+ codes = {}
78
+ checks.each do |name, command|
79
+ system("#{command} > /dev/null 2>&1")
80
+ codes[name] = $CHILD_STATUS.exitstatus
81
+ end
82
+ codes
83
+ end
84
+
85
+ # Extract the codes for each check
86
+ def status_codes
87
+ process_checks.values.compact
88
+ end
89
+ end # module LocalSystem
90
+ end # module Util
91
+ end # module VScripts
@@ -0,0 +1,6 @@
1
+ # Version number
2
+ module VScripts
3
+ VERSION = File.read(File.expand_path('../../../VERSION', __FILE__)).strip
4
+ VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH = VERSION.split('.')
5
+ VERSION_C = "VScripts #{VERSION} (c) #{Time.new.year} Vlad Ghinea"
6
+ end
@@ -0,0 +1,2 @@
1
+ class DummyClass
2
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'vscripts/aws/ec2'
3
+ require 'ostruct'
4
+
5
+ describe VScripts::AWS::EC2 do
6
+ before :each do
7
+ ::AWS.config({
8
+ :access_key_id => '1234',
9
+ :secret_access_key => '5678',
10
+ :region => 'us-east-1',
11
+ :logger => nil,
12
+ :stub_requests => true
13
+ })
14
+
15
+ @tags = {'Name' => 'test'}
16
+
17
+ @inst1 = OpenStruct.new(id: '1111', status: :running)
18
+ @inst2 = OpenStruct.new(id: '2222', status: :running, tags: @tags)
19
+ @inst3 = OpenStruct.new(id: '3333', status: :terminated)
20
+
21
+ @ec2 = VScripts::AWS::EC2
22
+ @ec2.any_instance.stub(:check_instance) { true }
23
+ @ec2.any_instance.stub(:instance_id) { @inst1.id }
24
+ end
25
+
26
+ describe '#instance' do
27
+ it 'returns AWS::EC2' do
28
+ expect(subject.ec2).to be_an_instance_of ::AWS::EC2
29
+ end
30
+ end
31
+
32
+ describe '#new' do
33
+ it 'returns AWS::EC2::Instance' do
34
+ expect(subject.instance).to be_an_instance_of ::AWS::EC2::Instance
35
+ expect(subject.instance.id).to eq(@inst1.id)
36
+ end
37
+ end
38
+
39
+ describe '#all_tags' do
40
+ it 'returns AWS::EC2::ResourceTagCollection' do
41
+ expect(subject.all_tags)
42
+ .to be_an_instance_of ::AWS::EC2::ResourceTagCollection
43
+ end
44
+ end
45
+
46
+ describe '#tags_without' do
47
+ it 'returns a Hash' do
48
+ expect(subject.tags_without)
49
+ .to be_an_instance_of ::AWS::EC2::ResourceTagCollection
50
+ end
51
+ end
52
+
53
+ describe '#name' do
54
+ it 'returns Hash value' do
55
+ subject.stub(:all_tags_hash) {@tags}
56
+ expect(subject.name).to eq(@tags['Name'])
57
+ end
58
+ end
59
+
60
+ describe '#named_instances' do
61
+ it 'returns AWS::EC2::InstanceCollection' do
62
+ expect(subject.named_instances)
63
+ .to be_an_instance_of ::AWS::EC2::InstanceCollection
64
+ end
65
+ end
66
+
67
+ describe '#functional_instances' do
68
+ it 'returns an Array' do
69
+ subject.stub(:named_instances) { [@inst1, @inst2, @inst3] }
70
+ expect(subject.functional_instances).to be_an Array
71
+ expect(subject.functional_instances).to include(@inst1, @inst2)
72
+ end
73
+ end
74
+
75
+ describe '#similar_instances' do
76
+ it 'returns an Array' do
77
+ subject.stub(:functional_instances) { [@inst1, @inst2] }
78
+ expect(subject.similar_instances).to include(@tags['Name'])
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'vscripts/aws/metadata'
3
+
4
+ describe VScripts::AWS::Metadata do
5
+ before(:each) do
6
+ @dummy = DummyClass.new
7
+ @dummy.extend VScripts::AWS::Metadata
8
+ @dummy.stub_chain(:open, :read).and_return('Remote server response')
9
+ end
10
+
11
+ describe '#metadata_url' do
12
+ it 'returns metadata url string' do
13
+ expect(@dummy.metadata_url).to be_a String
14
+ end
15
+ end
16
+
17
+ describe '#zone' do
18
+ it 'returns zone string' do
19
+ expect(@dummy.zone).to eq('Remote server response')
20
+ end
21
+ end
22
+
23
+ describe '#region' do
24
+ it 'returns region string' do
25
+ @dummy.stub(:zone).and_return('us-test-1a')
26
+ expect(@dummy.region).to eq('us-test-1')
27
+ end
28
+ end
29
+
30
+ describe '#instance_id' do
31
+ it 'returns instance id string' do
32
+ expect(@dummy.instance_id).to eq('Remote server response')
33
+ end
34
+ end
35
+
36
+ describe '#public_hostname' do
37
+ it 'returns public hostname string' do
38
+ expect(@dummy.public_hostname).to eq('Remote server response')
39
+ end
40
+ end
41
+
42
+ describe '#ec2_instance?' do
43
+ it 'returns true' do
44
+ Net::HTTP.stub(:get_response).and_return(true)
45
+ expect(@dummy.ec2_instance?).to be_true
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ require 'vscripts/aws'
2
+
3
+ describe VScripts::AWS do
4
+ it 'Should load default configuration for AWS SDK' do
5
+ expect(::AWS.config.stub_requests).to be_true
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ require 'vscripts/command_line'
2
+
3
+ describe VScripts::CommandLine do
4
+ before :each do
5
+ @cmd = VScripts::Command.list.first.to_s
6
+ @cli = VScripts::CommandLine.new([@cmd, 'extra_args'])
7
+ end
8
+
9
+ describe '#new' do
10
+ it 'returns the command line arguments' do
11
+ expect(@cli).to be_an_instance_of VScripts::CommandLine
12
+ end
13
+ end
14
+
15
+ describe '#global' do
16
+ it 'returns the global options as a Hash' do
17
+ expect(@cli.global).to be_an_instance_of Hash
18
+ end
19
+ end
20
+
21
+ describe '#command' do
22
+ it 'returns the command name' do
23
+ expect(@cli.command).to be_a Symbol
24
+ expect(@cli.command).to eql @cmd.capitalize.to_sym
25
+ end
26
+ end
27
+
28
+ describe '#extra' do
29
+ it 'returns the rest of the arguments as an Array' do
30
+ expect(@cli.extra).to be_an_instance_of Array
31
+ expect(@cli.extra).to eql ['extra_args']
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ require 'vscripts/command'
2
+
3
+ describe VScripts::Command do
4
+ describe '#list' do
5
+ it 'returns a list of available commands' do
6
+ expect(VScripts::Command.list).to be_an_instance_of Array
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ require 'vscripts/commands/tags2facts'
2
+
3
+ describe VScripts::Commands::Tags2facts do
4
+
5
+ before :each do
6
+ @tags2facts = VScripts::Commands::Tags2facts.new(['extra_args'])
7
+ end
8
+
9
+ describe '#new' do
10
+ it 'returns cli arguments and loads EC2 SDK' do
11
+ expect(@tags2facts.cli).to be_a Hash
12
+ expect(@tags2facts.ec2).to be_an_instance_of VScripts::AWS::EC2
13
+ end
14
+ end
15
+
16
+ describe '#parser' do
17
+ it 'returns parser' do
18
+ expect(@tags2facts.parser).to be_an_instance_of Trollop::Parser
19
+ end
20
+ end
21
+
22
+ describe '#exclude_list' do
23
+ it 'returns exclude list' do
24
+ expect(@tags2facts.exclude_list).to eq(['Name', 'Domain'])
25
+ end
26
+ end
27
+
28
+ describe '#tags_json' do
29
+ it 'returns JSON formatted string' do
30
+ @tags2facts.stub_chain(:tags_hash, :to_h) {{ key: 'value' }}
31
+ expect(@tags2facts.tags_json).to eq("{\n \"key\": \"value\"\n}")
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+ require 'vscripts/util/local_system'
4
+
5
+ describe VScripts::Util::LocalSystem do
6
+ before(:all) do
7
+ @dummy = DummyClass.new
8
+ @dummy.extend VScripts::Util::LocalSystem
9
+ end
10
+
11
+ describe '#hosts_path' do
12
+ it 'returns the path to hosts file' do
13
+ expect(@dummy.hosts_path).to be_a String
14
+ end
15
+ end
16
+ describe '#hostname_path' do
17
+ it 'returns the path to the hostname file' do
18
+ expect(@dummy.hostname_path).to be_a String
19
+ end
20
+ end
21
+ describe '#local_fqdn' do
22
+ it 'returns the local FQDN' do
23
+ expect(@dummy.local_fqdn).to be_a String
24
+ end
25
+ end
26
+ describe '#local_host_name' do
27
+ it 'returns the local host name' do
28
+ expect(@dummy.local_host_name).to be_a String
29
+ end
30
+ end
31
+ describe '#local_domain_name' do
32
+ it 'returns the local domain name' do
33
+ expect(@dummy.local_domain_name).to be_a String
34
+ end
35
+ end
36
+ describe '#ensure_file_dir' do
37
+ it 'create a directory for the specified files' do
38
+ test_dir = Dir::Tmpname.make_tmpname '/tmp/vscripts', nil
39
+ test_file = 'test_file'
40
+ @dummy.ensure_file_dir("#{test_dir}/#{test_file}")
41
+ expect(Dir.exists?(test_dir)).to be_true
42
+ `rm -r #{test_dir}`
43
+ end
44
+ end
45
+ describe '#write_file' do
46
+ it 'should write to a file' do
47
+ test_file = Dir::Tmpname.make_tmpname '/tmp/vscripts', nil
48
+ @dummy.write_file(test_file, 'test')
49
+ expect(IO.read(test_file)).to eq('test')
50
+ `rm #{test_file}`
51
+ end
52
+ end
53
+ describe '#ensure_file_content' do
54
+ it 'should ensure content of file' do
55
+ test_dir = Dir::Tmpname.make_tmpname '/tmp/vscripts', nil
56
+ test_file = 'test_file'
57
+ test = "#{test_dir}/#{test_file}"
58
+ @dummy.ensure_file_content(test, 'test')
59
+ expect(IO.read(test)).to eq('test')
60
+ `rm -r #{test_dir}`
61
+ end
62
+ end
63
+ describe '#checks' do
64
+ it 'returns an array of checks' do
65
+ expect(@dummy.checks).to be_a Hash
66
+ end
67
+ end
68
+ describe '#process_checks' do
69
+ it 'should execute system command and return exit code' do
70
+ @dummy.stub(:checks) {{'test command' => 'exit 5'}}
71
+ expect(@dummy.process_checks).to eq({"test command"=>5})
72
+ end
73
+ end
74
+ describe '#status_codes' do
75
+ it 'should return an Array of exit codes' do
76
+ @dummy.stub(:checks) {{'test command' => 'exit 5'}}
77
+ expect(@dummy.status_codes).to eq([5])
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,7 @@
1
+ require 'vscripts/version'
2
+
3
+ describe 'VScripts::VERSION' do
4
+ it 'Should be a string' do
5
+ expect(VScripts::VERSION).to be_an_instance_of String
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ require 'vscripts'
2
+
3
+ describe VScripts do
4
+ end
data/tasks/deploy.rake ADDED
@@ -0,0 +1,95 @@
1
+ DEV_BRANCH = 'develop'
2
+ LOG_RANGE = "master...#{DEV_BRANCH}"
3
+ VERSION_FILE = 'VERSION'
4
+ CHANGELOG_FILE = 'CHANGELOG.md'
5
+
6
+ desc 'Automated deployment'
7
+ task :deploy do
8
+ check_branch
9
+ commit_changelog
10
+ merge_changes
11
+ push_release
12
+ package_and_push_gem
13
+ end
14
+
15
+ def check_branch
16
+ if ! `git ls-files --others --exclude-standard`.empty?
17
+ abort 'ERROR: There are untracked files!'
18
+ elsif ! system('git diff --quiet && git diff --cached --quiet')
19
+ abort 'ERROR: There are staged but uncommitted files!'
20
+ end
21
+ `git fetch`
22
+ end
23
+
24
+ def bump_version
25
+ @version = File.read(VERSION_FILE).strip
26
+ @version.gsub(/(\d+)\.(\d+)\.(\d+)/) {
27
+ @major, @minor, @patch = $1.to_i, $2.to_i, $3.to_i
28
+ }
29
+ @new_version = "#{@major}.#{@minor}.#{@patch + 1}"
30
+ File.write('VERSION', @new_version)
31
+ end
32
+
33
+ def changelog
34
+ File.read(CHANGELOG_FILE)
35
+ end
36
+
37
+ def changes
38
+ @changes ||= `git log #{LOG_RANGE} --no-merges`
39
+ end
40
+
41
+ def pretty_changes
42
+ `git log #{LOG_RANGE} --reverse --no-merges --pretty=format:' * %s ([%cn - %h](https://github.com/vghn/vscripts/commit/%H))'`
43
+ end
44
+
45
+ def update_changelog
46
+ bump_version
47
+ puts 'Writing new changelog'
48
+ File.write(
49
+ CHANGELOG_FILE,
50
+ "Version #{@new_version}\n---\n" + pretty_changes + "\n\n" + changelog
51
+ )
52
+ end
53
+
54
+ def commit_changelog
55
+ if changes.lines.count > 0
56
+ update_changelog
57
+ puts 'Committing version and changelog'
58
+ `git commit -am \"Bump version.\"`
59
+ else
60
+ puts 'No changes committed. Exiting.'
61
+ exit 0
62
+ end
63
+ end
64
+
65
+ def branch
66
+ @branch ||= `git branch`.match(/^\* (\S+)/)[1]
67
+ end
68
+
69
+ def switch_to_branch(name)
70
+ `git checkout #{name}` unless branch == name
71
+ end
72
+
73
+ def merge
74
+ @merge ||= `git merge --no-ff #{DEV_BRANCH} -m \"v#{@new_version}\"`
75
+ end
76
+
77
+ def merge_changes
78
+ switch_to_branch('master')
79
+ puts "Merging \"#{DEV_BRANCH}\" branch"
80
+ abort 'ERROR: Conflicts found; Stopping!' if merge =~ /conflict/i
81
+ end
82
+
83
+ def push_release
84
+ puts "Tagging v#{@new_version} release."
85
+ `git tag -a v#{@new_version} -m 'Version #{@new_version}'`
86
+ puts 'Pushing all branches and tags'
87
+ `git push --all --follow-tags`
88
+ end
89
+
90
+ def package_and_push_gem
91
+ puts 'Building gem'
92
+ Rake::Task['build'].invoke
93
+ puts 'Pushing gem to Rubygems'
94
+ `gem push pkg/vscripts-#{@new_version}.gem`
95
+ end