vscripts 0.0.1

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,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