awscli 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODAzMjhiNjZkOWNhMjE3NWM5NjIzYTY3NzAwMWIyNmYxYWRmYWVjZg==
4
+ NjZmMTc3NTYxZjgzYjg3NTg3NTBlOWQ1NDg3Mjk2ODE4NjEyNjIzZg==
5
5
  data.tar.gz: !binary |-
6
- MDk0ZDMyNDhlMjJlOWIwMjMzYThmMGZlZmUxYzhhNDczNDc3N2MyMQ==
6
+ OGQ1YzUwODYxZjZkYmQzYzY0YmE4OTU1MTJlYzk1MGE5MzZiNzk1YQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MTM0MjBiOGJlYzk0ZWY3ZDFiNjNjYzdhMGEzOTE2ZDlkMDRlMzhkZTNhOTg2
10
- YmMyYTc1NDdmZDJiYzdlMDA1NzU2NTUxMjdmNDM2YzYwNDg0MjE2MzRiZTM1
11
- ZWU2M2U0MDBmYWIyYjIzNTc0YmNlYmRlNDY2YTljODg1YjAzMzI=
9
+ ZTEwNDU0NWQ4ZjRmMTI0YmI4ZDU0OThmYTYzZjU0YzE4NWJkZjNiYzJmN2I3
10
+ NWQ5MmJjMmI3YjU2MzlmNGI4ZDYyYjFjY2FhZjVhOTFjYTk2OTMxMjA0Y2Qz
11
+ MWM3NzUxMTZkMGM3MzE5MDk3YjM1YWJiYjczOGEzZjUyYjljY2I=
12
12
  data.tar.gz: !binary |-
13
- N2RiYTAzZmY3YjFhZThlOTdkZmY4ZTk5M2FiYzYyNDRkMTRjMzQxMWM2MmVm
14
- ZmE5ZDgyNWNmMTQ2NDZkMGFhNTk0NTgxNGZmNzA1OGMwOTA2MGVhMjRiNGQy
15
- NGQ3ZTAxMzA0NThjN2Q2ZDhhNjczZmJhYjg4MjA3ZDIwYzMzNTM=
13
+ ZTUxN2ZlOTcyMWQyNzUyMjY4Yjk1MTZiZTViZGFhMTU1ZGI4YTU5YzQ5YTBj
14
+ OGQ3NmZjYWZlZmI2MjNiNzRjZjY5ODQ0NmQwM2EzMWQyNzZlNWQ5YTUwN2E1
15
+ YTY4MTRmZjQwYjQzYzMzMWI0NzliOGVmZGRiMWI0MTU0MTAyY2M=
@@ -4,16 +4,19 @@ module AwsCli
4
4
  require 'awscli/cli/ec2'
5
5
  class Ami < Thor
6
6
 
7
- desc "list", "List Images"
7
+ desc "list [OPTIONS]", "List Images"
8
8
  method_option :filter, :aliases => "-f", :type => :hash, :desc => "filter the images based on filters"
9
9
  method_option :amazon_owned, :aliases => "-a", :type => :boolean, :default => false, :desc => "lists amazon owned images"
10
10
  method_option :show_filters, :aliases => "-s", :type => :boolean, :default => false, :desc => "filters available"
11
+ method_option :self_owned, :aliases => "-o", :type => :boolean, :default => false, :desc => "list self owned images"
11
12
  def list
12
13
  create_ec2_object
13
14
  if options[:amazon_owned]
14
15
  @ec2.list_amazon
15
16
  elsif options[:show_filters]
16
17
  @ec2.show_filters
18
+ elsif options[:self_owned]
19
+ @ec2.list_self
17
20
  else
18
21
  @ec2.list options[:filter]
19
22
  end
@@ -29,6 +32,14 @@ module AwsCli
29
32
  @ec2.create_image_from_instance options
30
33
  end
31
34
 
35
+ desc "deregister", "Deregisters the specified AMI. Once deregistered, the AMI cannot be used to launch new instances"
36
+ method_option :image_id, :aliases => "-i", :type => :string, :required => true, :desc => "ID of the AMI to deregister"
37
+ def deregister
38
+ create_ec2_object
39
+ @ec2.deregister options[:image_id]
40
+ end
41
+
42
+
32
43
  private
33
44
 
34
45
  def create_ec2_object
@@ -4,7 +4,7 @@ module AwsCli
4
4
  require 'awscli/cli/ec2'
5
5
  class Ebs < Thor
6
6
 
7
- desc "list", "List ELastic Block Storages"
7
+ desc "list [OPTIONS]", "List ELastic Block Storages"
8
8
  method_option :snapshots, :aliases => "-s", :type => :boolean, :default => false, :desc => "list snapshots"
9
9
  def list
10
10
  create_ec2_object
@@ -48,18 +48,15 @@ module AwsCli
48
48
 
49
49
  desc "delete_detached", "Delete all the volumes that are not in use"
50
50
  def delete_detached
51
- if agree("Are you sure want to delete all the all volumes that are not in use ? ")
52
- puts
53
- create_ec2_object
54
- @ec2.delete_detached
55
- end
51
+ create_ec2_object
52
+ @ec2.delete_detached
56
53
  end
57
54
 
58
55
  desc "create_snapshot", "Create a snapshot from volume"
59
56
  method_option :volume_id, :aliases => "-v", :banner => "VID", :required => true, :type => :string, :desc => "volume to make a snapshot from"
60
57
  def create_snapshot
61
58
  create_ec2_object
62
- @ec2.create_snapshot
59
+ @ec2.create_snapshot options
63
60
  end
64
61
 
65
62
  desc "copy_snapshot", "Copy a snapshot to a different region"
@@ -67,7 +64,7 @@ module AwsCli
67
64
  method_option :snapshot_id, :aliases => "-i", :banner => "ID", :required => true, :type => :string, :desc => "Id of the snapshot"
68
65
  def copy_snapshot
69
66
  create_ec2_object
70
- @ec2.copy_snapshot
67
+ @ec2.copy_snapshot options
71
68
  end
72
69
 
73
70
  desc "delete_snapshot", "Delete SnapShot"
@@ -11,52 +11,52 @@ module AwsCli
11
11
  end
12
12
 
13
13
  desc "create", "Create an new S3 bucket"
14
- method_option :key, :aliases => "-k", :type => :string, :required => true, :desc => "name of the bucket to create(name should be globally unique)"
14
+ method_option :bucket, :aliases => "-b", :type => :string, :required => true, :desc => "name of the bucket to create(name should be globally unique)"
15
15
  method_option :public, :aliases => "-p", :type => :boolean, :default => false, :desc => "makes the bucket publicly availble"
16
16
  # method_option :x_amz_acl, :aliases => "-x", :type => :string, :desc => "Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read']"
17
17
  def create
18
18
  create_s3_object
19
- @s3.create options
19
+ @s3.create options[:bucket], options[:public]
20
20
  end
21
21
 
22
22
  desc "delete", "Delete existing S3 bucket"
23
- method_option :key, :aliases => "-k", :type => :string, :required => true, :desc => "name of the bucket to delete"
23
+ method_option :bucket, :aliases => "-b", :type => :string, :required => true, :desc => "name of the bucket to delete"
24
24
  def delete
25
25
  create_s3_object
26
- @s3.delete options[:key]
26
+ @s3.delete options[:bucket]
27
27
  end
28
28
 
29
29
  desc "delete_rec", "Delete the bucket and all its contents"
30
- method_option :key, :aliases => "-k", :type => :string, :required => true, :desc => "name of the bucket to delete"
30
+ method_option :bucket, :aliases => "-b", :type => :string, :required => true, :desc => "name of the bucket to delete"
31
31
  def delete_rec
32
32
  create_s3_object
33
- @s3.delete_rec options[:key]
33
+ @s3.delete_rec options[:bucket]
34
34
  end
35
35
 
36
36
  desc "set_acl", "Change access control list for an S3 bucket"
37
- method_option :key, :aliases => "-k", :type => :string, :required => true, :desc => "name of the bucket to change acl"
37
+ method_option :bucket, :aliases => "-b", :type => :string, :required => true, :desc => "name of the bucket to change acl"
38
38
  method_option :acl, :aliases => "-a", :type => :string, :required => true, :desc => "Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read']"
39
39
  def set_acl
40
40
  create_s3_object
41
- @s3.set_acl options[:key], options[:acl]
41
+ @s3.set_acl options[:bucket], options[:acl]
42
42
  end
43
43
 
44
44
  desc "get_acl", "Get access control list for an S3 bucket"
45
- method_option :key, :aliases => "-k", :type => :string, :required => true, :desc => "name of the bucket to get acl"
45
+ method_option :bucket, :aliases => "-b", :type => :string, :required => true, :desc => "name of the bucket to get acl"
46
46
  def get_acl
47
47
  create_s3_object
48
- @s3.get_acl options[:key]
48
+ @s3.get_acl options[:bucket]
49
49
  end
50
50
 
51
51
  desc "get_logging_status", "Get logging status for an S3 bucket"
52
- method_option :key, :aliases => "-k", :type => :string, :required => true, :desc => "name of the bucket"
52
+ method_option :bucket, :aliases => "-b", :type => :string, :required => true, :desc => "name of the bucket"
53
53
  def get_logging_status
54
54
  create_s3_object
55
- @s3.get_logging_status options[:key]
55
+ @s3.get_logging_status options[:bucket]
56
56
  end
57
57
 
58
58
  # desc "set_logging_status", "Change logging status for an S3 bucket"
59
- # method_option :key, :aliases => "-k", :type => :string, :required => true, :desc => "name of the bucket"
59
+ # method_option :bucket, :aliases => "-b", :type => :string, :required => true, :desc => "name of the bucket"
60
60
  # method_option :owner, :aliases => "-o", :type => :hash, :banner => "ID:NAME", :desc => "set id and displayname of the owner"
61
61
  # method_option :grantee, :aliases => "-g", :type => :hash, :banner => "NAME:ID|EMAIL|URI", :desc => "Grantee hash containing, <Display name of the grantee>: <ID of the grantee (or) Email of the grantee (or) Uri of the group to grant access>"
62
62
  # method_option :permission, :aliases => "-p", :type => :string, :desc => "Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]"
@@ -69,7 +69,7 @@ module AwsCli
69
69
  # logging_status['AccessControlList'] = acl if acl
70
70
  # puts "Empty logging_status will disable logging" if logging_status.nil?
71
71
  # puts "#{logging_status}"
72
- # @s3.set_logging_status options[:key], logging_status
72
+ # @s3.set_logging_status options[:bucket], logging_status
73
73
  # end
74
74
 
75
75
  private
@@ -19,6 +19,31 @@ module AwsCli
19
19
  @s3.upload_file options[:bucket_name], options[:file_path]
20
20
  end
21
21
 
22
+ desc "put_rec", "put a directory recusively into a specified bucket using multiple threads"
23
+ method_option :bucket_name, :aliases => "-b", :required => true, :desc => "name of the bucket to upload the dir to"
24
+ method_option :dir_path, :aliases => "-p", :required => true, :desc => "path of the dir to upload"
25
+ method_option :dest_path, :aliases => "-d", :desc => "optionally specify destination directory path to create"
26
+ method_option :thread_count, :aliases => "-t", :type => :numeric, :default => 5, :desc => "number of threads to use to upload files"
27
+ method_option :public, :type => :boolean, :default => false, :desc => "set ACL of files to public"
28
+ def put_rec
29
+ create_s3_object
30
+ @s3.upload_file_rec options
31
+ end
32
+
33
+ desc "put_big", "uploads a larger file (> 100 MB) using multipart uploads"
34
+ long_desc <<-DESC
35
+ Takes in a larger file, split the file into chunks and uploads the parts using amazon multipart uploads and the parts are aggregated at the amazons end.
36
+ DESC
37
+ method_option :bucket_name, :aliases => "-b", :required => true, :desc => "name of the bucket to upload the parts to"
38
+ method_option :file_path, :aliases => "-p", :required => true, :desc => "path of the file to upload"
39
+ method_option :tmp_dir, :aliases => "-t", :default => "/tmp", :desc => "path to a temperory location where file will be split into chunks"
40
+ method_option :acl, :aliases => "-a", :default => "private", :desc => "ACL to apply, to the object that is created after completing multipart upload, valid options in private | public-read | public-read-write | authenticated-read | bucket-owner-read | bucket-owner-full-control"
41
+ method_option :dest_path, :aliases => "-d", :desc => "optionally specify destination directory path to create"
42
+ def put_big
43
+ create_s3_object
44
+ @s3.multipart_upload options
45
+ end
46
+
22
47
  desc "get", "get a file from a bucket"
23
48
  method_option :bucket_name, :aliases => "-b", :required => true, :desc => "name of the bucket to download the file from"
24
49
  method_option :file_name, :aliases => "-f", :required => true, :desc => "name of file to download"
data/lib/awscli/ec2.rb CHANGED
@@ -381,7 +381,8 @@ module Awscli
381
381
  if filter.nil?
382
382
  @@conn.images.all.table([:architecture, :id, :is_public, :platform, :root_device_type, :state])
383
383
  else
384
- @@conn.images.all(filter).table([:architecture, :id, :is_public, :platform, :root_device_type, :state])
384
+ data = @@conn.images.all(filter)
385
+ data.empty? ? puts("No AMI's found for provided filters") : data.table([:architecture, :id, :is_public, :platform, :root_device_type, :state])
385
386
  end
386
387
  end
387
388
 
@@ -422,6 +423,11 @@ module Awscli
422
423
  @@conn.images.all('owner-alias' => 'amazon').table([:architecture, :id, :is_public, :platform, :root_device_type, :state])
423
424
  end
424
425
 
426
+ def list_self
427
+ response = @@conn.describe_images({'Owner' => 'self'}).body['imagesSet']
428
+ Formatador.display_table(response, ['architecture', 'imageId', 'isPublic', 'name', 'imageState', 'rootDeviceType', 'imageType'])
429
+ end
430
+
425
431
  def create_image_from_instance options
426
432
  abort "Invalid Instace: #{options[:instance_id]}" unless @@conn.servers.get(options[:instance_id])
427
433
  @@conn.create_image(
@@ -433,6 +439,13 @@ module Awscli
433
439
  puts "Created image from instance: #{options[:instance_id]}"
434
440
  end
435
441
 
442
+ def deregister image_id
443
+ image = @@conn.images.get(image_id)
444
+ abort "Cannot find image with id: #{image_id}" unless image
445
+ @@conn.deregister_image(image_id)
446
+ say "De-registerd image: <%= color('#{image_id}', :green) %>"
447
+ end
448
+
436
449
  end # => AMI
437
450
 
438
451
  class Ebs
@@ -485,12 +498,14 @@ module Awscli
485
498
  def delete_detached
486
499
  vols = @@conn.volumes.all('status' => 'available')
487
500
  unless vols.empty?
488
- puts "Deleting all volumes which are not in use ..."
489
- vols.each do |vol|
490
- vol.destroy
501
+ if agree("Are you sure want to delete all the all volumes that are not in use ? ")
502
+ puts "Deleting all volumes which are not in use ..."
503
+ vols.each do |vol|
504
+ vol.destroy
505
+ end
491
506
  end
492
507
  else
493
- puts "No volumes found, that are not in use found"
508
+ puts "No volumes found, that are 'not in use'"
494
509
  end
495
510
  end
496
511
 
@@ -501,7 +516,7 @@ module Awscli
501
516
  end
502
517
 
503
518
  def copy_snapshot options
504
- abort "Cannot find snapshot: #{options[:snapshot_id]}" unless @@conn.snapshots.get(options[:snapshot_id])
519
+ # abort "Cannot find snapshot: #{options[:snapshot_id]}" unless @@conn.snapshots.get(options[:snapshot_id])
505
520
  @@conn.copy_snapshot(options[:snapshot_id], options[:source_region])
506
521
  puts "Copied snapshot"
507
522
  end
@@ -510,7 +525,7 @@ module Awscli
510
525
  snap = @@conn.snapshots.get(options[:snapshot_id])
511
526
  abort "Cannot find snapshot: #{options[:snapshot_id]}" unless snap
512
527
  snap.destroy
513
- puts "Destroyed snapshot"
528
+ puts "Deleted snapshot"
514
529
  end
515
530
  end # => EBS
516
531
 
data/lib/awscli/s3.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  module Awscli
2
2
  module S3
3
3
  require 'thread'
4
+ require 'digest/md5'
5
+ require 'base64'
6
+ require 'fileutils'
4
7
 
5
8
  class Files
6
9
  def initialize connection, options = {}
@@ -30,6 +33,140 @@ module Awscli
30
33
  puts "Uploaded file: #{file_name} to bucket: #{dir_name}"
31
34
  end
32
35
 
36
+ def upload_file_rec options
37
+ dir_name, dir_path, threads_count, is_public = options[:bucket_name], options[:dir_path], options[:thread_count], options[:public]
38
+ dest_path = options[:dest_path] if options[:dest_path]
39
+ #check if bucket exists
40
+ bucket = @@conn.directories.get(dir_name)
41
+ abort "cannot find bucket: #{dir_name}" unless bucket
42
+ #check if passed path is a dir
43
+ dir = File.expand_path(dir_path)
44
+ abort "dir_path must be a dir" unless File.directory?(dir)
45
+ #add trailing slash to detination dir if is not passed
46
+ if dest_path && !dest_path.end_with?('/')
47
+ dest_path = "#{dest_path}/"
48
+ end
49
+ #remove trailing / from dir_path
50
+ dir = dir.chop if dir.end_with?('/')
51
+ #initializations
52
+ total_size = 0
53
+ files = Queue.new
54
+ threads = Array.new
55
+ semaphore = Mutex.new
56
+ file_number = 0
57
+
58
+ Dir.glob("#{dir}/**/*").select { |f| !File.directory?(f) }.each do |file|
59
+ files << file
60
+ total_size += File.size(file)
61
+ end
62
+
63
+ total_files = files.size
64
+ puts "Starting Upload using #{threads_count} threads"
65
+ threads_count.times do |count|
66
+ threads << Thread.new do
67
+ # Thread.current[:name] = "upload files #{count}"
68
+ # puts "...started thread '#{Thread.current[:name]}'...\n"
69
+ while not files.empty?
70
+ semaphore.synchronize do
71
+ file_number += 1
72
+ end
73
+ file = files.pop
74
+ key = file.gsub(dir, '')[1..-1]
75
+ dest = "#{dest_path}#{key}"
76
+ puts "[#{file_number}/#{total_files}] Uploading #{key} to s3://#{dir_name}/#{dest}"
77
+ bucket.files.create(
78
+ :key => dest,
79
+ :body => File.open(file),
80
+ :public => is_public
81
+ )
82
+ end
83
+ end
84
+ end
85
+ # Wait for the threads to finish.
86
+ threads.each do |t|
87
+ begin
88
+ t.join
89
+ rescue RuntimeError => e
90
+ puts "Failure on thread #{t[:name]}: #{e.message}"
91
+ end
92
+ end
93
+ puts "Uploaded #{total_files} (#{total_size / 1024} KB)"
94
+ end
95
+
96
+ def multipart_upload options
97
+ bucket_name, file_path, tmp_loc, acl = options[:bucket_name], options[:file_path], options[:tmp_dir], options[:acl]
98
+ dir = @@conn.directories.get(bucket_name)
99
+ abort "cannot find bucket: #{bucket_name}" unless dir
100
+ file = File.expand_path(file_path)
101
+ abort "Invalid file path: #{file_path}" unless File.exist?(file)
102
+ dest_path = options[:dest_path] if options[:dest_path]
103
+ if dest_path
104
+ if !dest_path.end_with?('/')
105
+ #add trailing slash to detination dir if is not passed
106
+ dest_path = "#{dest_path}/"
107
+ elsif
108
+ #remove leading slash from destination dir path if exists
109
+ dest_path = dest_path[1..-1]
110
+ end
111
+ end
112
+
113
+ remote_file = if dest_path
114
+ "#{dest_path}#{File.basename(file_path)}"
115
+ else
116
+ "#{File.basename(file_path)}"
117
+ end
118
+
119
+ #get the file and split it
120
+ tmp_dir = "#{tmp_loc}/#{File.basename(file_path)}"
121
+ FileUtils.mkdir_p(tmp_dir)
122
+ #split the file into chunks => use smaller chunk sizes to minimize memory
123
+ puts "Spliting the file into 10M chunks ..."
124
+ `split -a3 -b10m #{file} #{tmp_dir}/#{File.basename(file_path)}`
125
+ abort "Cannot perform split on the file" unless $?.to_i == 0
126
+
127
+ parts = Dir.glob("#{tmp_loc}/#{File.basename(file_path)}/*").sort
128
+
129
+ #initiate the mulitpart upload & store the returned upload_id
130
+ puts "Initializing multipart upload"
131
+ multi_part_up = @@conn.initiate_multipart_upload(
132
+ bucket_name, # name of the bucket to create object in
133
+ remote_file, # name of the object to create
134
+ { 'x-amz-acl' => acl }
135
+ )
136
+ upload_id = multi_part_up.body["UploadId"]
137
+ puts "Upload ID: #{upload_id}"
138
+
139
+ part_ids = []
140
+
141
+ parts.each_with_index do |part, position|
142
+ part_number = (position + 1).to_s
143
+ puts "Uploading #{part} ..."
144
+ File.open part do |part_file|
145
+ response = @@conn.upload_part(
146
+ bucket_name,
147
+ # file[1..-1],
148
+ remote_file,
149
+ upload_id,
150
+ part_number,
151
+ part_file
152
+ )
153
+ part_ids << response.headers['ETag']
154
+ end
155
+ end
156
+
157
+ puts "Completing multipart upload ..."
158
+ response = @@conn.complete_multipart_upload(
159
+ bucket_name,
160
+ # file[1..-1],
161
+ remote_file,
162
+ upload_id,
163
+ part_ids
164
+ )
165
+ puts "Cleaning tmp_dir ..."
166
+ FileUtils.rm_rf(tmp_dir)
167
+ puts "Successfully completed multipart upload"
168
+ end
169
+
33
170
  def download_file dir_name, file_name, path
34
171
  dir = @@conn.directories.get(dir_name)
35
172
  abort "cannot find bucket: #{dir_name}" unless dir
@@ -44,6 +181,7 @@ module Awscli
44
181
  end
45
182
 
46
183
  def delete_file dir_name, file_name
184
+ #TODO: Handle globs for deletions
47
185
  dir = @@conn.directories.get(dir_name)
48
186
  abort "cannot find bucket: #{dir_name}" unless dir
49
187
  remote_file = dir.files.get(file_name)
@@ -71,9 +209,12 @@ module Awscli
71
209
  @@conn.directories.table
72
210
  end
73
211
 
74
- def create options
75
- dir = @@conn.directories.create(options)
76
- puts "Create bucket: #{dir.key}"
212
+ def create bucket_name, is_public
213
+ dir = @@conn.directories.create(
214
+ :key => bucket_name,
215
+ :public => is_public
216
+ )
217
+ puts "Created bucket: #{dir.key}"
77
218
  end
78
219
 
79
220
  def delete dir_name
@@ -1,3 +1,3 @@
1
1
  module Awscli
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awscli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ashrith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-29 00:00:00.000000000 Z
11
+ date: 2013-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake