hibernate 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,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1e5b683d653f45c6747b92d58f5bc5258111837bec3eec25945c0e8b58de37f
4
- data.tar.gz: acb1ea6c6401883e116ee44da22f5179ff3009424fc90ff3d5f5db5e650470c3
3
+ metadata.gz: 71a95bed5e00b8b00d0ec93a5f5f3e00faee39b1de4bc2e5f3616c6358a4c98b
4
+ data.tar.gz: ba6cee2ff815f36090f51e802f361079d486bce36f04ba79eee6f719c32a3437
5
5
  SHA512:
6
- metadata.gz: 0b96aa6e000fbe289ea668497918d6352103e398560e112e20898ff9a2b65583340e132e369b308990eaeede6a954c951ea9bf52a1f8947a8307336abe29a18e
7
- data.tar.gz: 92c1af50b90c66fe7ee91101e37ae76ca6abb63e2e5fb1671adc1fbfcf2d9f904b0dced62b999b1bbd3a09c48b43ee02d8cbd625c29ddcd2e8ca25e2935dac54
6
+ metadata.gz: 57e1625b9990bfd59c947a8f894495be4b0d1e5ed9e6601d3e84ee67bc1d8cb760111d917211b8f68b4fa6b4db6d491f621c168679ded265415edf4010ab97cd
7
+ data.tar.gz: 1cbe3c34db01b4235f31544ad87452cd722d165b47bf73a50506ccea0b0b1e083c0adde28a70bf84d1b03564ca2860b8f42a39fecab886c7d0f927635be65a89
data/bin/hibernate CHANGED
@@ -4,26 +4,25 @@ require 'optparse'
4
4
  require_relative '../lib/hibernate/lambda_setup'
5
5
  require_relative '../lib/hibernate/ec2_manager'
6
6
 
7
- # Define the command-line interface
8
7
  class HibernateCLI
9
8
  def self.run
10
9
  command = nil
11
10
  options = {}
12
11
 
12
+ if ARGV.include?('setup')
13
+ command = :setup
14
+ ARGV.delete('setup')
15
+ elsif ARGV.include?('node')
16
+ command = :manage_ec2
17
+ ARGV.delete('node')
18
+ elsif ARGV.include?('remove')
19
+ command = :remove_ec2
20
+ ARGV.delete('remove')
21
+ end
22
+
13
23
  parser = OptionParser.new do |parser|
14
24
  parser.banner = "Usage: hibernate [command] [options]"
15
25
 
16
- # Command for setting up the Lambda function
17
- parser.on('setup', 'Create the Lambda function') do
18
- command = :setup
19
- end
20
-
21
- # Command for managing EC2 instances
22
- parser.on('node', 'Manage EC2 instances') do
23
- command = :manage_ec2
24
- end
25
-
26
- # Options for the EC2 management command
27
26
  parser.on('--in=<INSTANCE_NAME>', 'Specify the EC2 instance name') do |instance_name|
28
27
  options[:instance_name] = instance_name
29
28
  end
@@ -37,9 +36,7 @@ class HibernateCLI
37
36
  end
38
37
  end
39
38
 
40
- # Parse the command-line arguments
41
39
  begin
42
- p ARGV # Debug: Print the command-line arguments
43
40
  parser.parse!(ARGV)
44
41
  rescue OptionParser::ParseError => e
45
42
  puts e.message
@@ -47,7 +44,6 @@ class HibernateCLI
47
44
  exit 1
48
45
  end
49
46
 
50
- # Ensure only one command is processed
51
47
  if command.nil?
52
48
  puts "Please provide a command."
53
49
  puts parser
@@ -58,27 +54,37 @@ class HibernateCLI
58
54
  when :setup
59
55
  create_lambda_function
60
56
  when :manage_ec2
61
- # Validate EC2 management command options
62
- if options[:instance_name].nil? || options[:start_cron].nil? || options[:stop_cron].nil?
63
- puts "Please provide the instance name, start cron expression, and stop cron expression."
64
- puts parser
65
- exit
66
- else
67
- manage_ec2(options[:instance_name], options[:start_cron], options[:stop_cron])
68
- end
57
+ manage_ec2_command(options)
58
+ when :remove_ec2
59
+ remove_ec2_command(options)
69
60
  end
70
61
  end
71
62
 
72
63
  def self.create_lambda_function
73
- p "I am printed here in setup"
74
64
  LambdaSetup.new.run
75
65
  end
76
66
 
77
- def self.manage_ec2(instance_name, start_cron, stop_cron)
78
- p "I am printed here inside node"
79
- ec2_manager = EC2Manager.new(instance_name, start_cron, stop_cron)
80
- ec2_manager.create_event_rule
67
+ def self.manage_ec2_command(options)
68
+ if options[:instance_name].nil? || (options[:start_cron].nil? && options[:stop_cron].nil?)
69
+ puts "Please provide the instance name, and at least one cron expression (start or stop)."
70
+ puts "Usage: hibernate node --in=<INSTANCE_NAME> --start_instance=<START_CRON> --stop_instance=<STOP_CRON>"
71
+ exit
72
+ else
73
+ ec2_manager = EC2Manager.new(options[:instance_name], options[:start_cron], options[:stop_cron])
74
+ ec2_manager.create_event_rule
75
+ end
76
+ end
77
+
78
+ def self.remove_ec2_command(options)
79
+ if options[:instance_name].nil? || (options[:start_cron].nil? && options[:stop_cron].nil?)
80
+ puts "Please provide the instance name, and at least one cron expression (start or stop) to remove."
81
+ puts "Usage: hibernate remove --in=<INSTANCE_NAME> --start_instance=<START_CRON> --stop_instance=<STOP_CRON>"
82
+ exit
83
+ else
84
+ ec2_manager = EC2Manager.new(options[:instance_name], options[:start_cron], options[:stop_cron])
85
+ ec2_manager.remove_event_rule
86
+ end
81
87
  end
82
88
  end
83
89
 
84
- HibernateCLI.run
90
+ HibernateCLI.run
@@ -0,0 +1,111 @@
1
+ require 'aws-sdk-cloudwatchevents'
2
+ require 'json'
3
+ require 'dotenv/load'
4
+
5
+ class CloudWatchEventManager
6
+ def initialize(events_client, instance_id, instance_name, lambda_function_arn)
7
+ @events_client = events_client
8
+ @instance_id = instance_id
9
+ @instance_name = instance_name
10
+ @lambda_function_arn = lambda_function_arn
11
+ @aws_region = ENV['AWS_REGION']
12
+ @account_id = ENV['ACCOUNT_ID']
13
+ @lambda_client = Aws::Lambda::Client.new(region: @aws_region)
14
+ end
15
+
16
+ def create_start_rule(cron_expression)
17
+ create_rule(
18
+ "StartInstanceRule-#{@instance_id}",
19
+ cron_expression,
20
+ { instance_id: @instance_id, action: 'start' },
21
+ "start"
22
+ )
23
+ end
24
+
25
+ def create_stop_rule(cron_expression)
26
+ create_rule(
27
+ "StopInstanceRule-#{@instance_id}",
28
+ cron_expression,
29
+ { instance_id: @instance_id, action: 'stop' },
30
+ "stop"
31
+ )
32
+ end
33
+
34
+ def remove_start_rule
35
+ rule_name = "StartInstanceRule-#{@instance_id}"
36
+ remove_rule(rule_name)
37
+ remove_lambda_permission(rule_name)
38
+ end
39
+
40
+ def remove_stop_rule
41
+ rule_name = "StopInstanceRule-#{@instance_id}"
42
+ remove_rule(rule_name)
43
+ remove_lambda_permission(rule_name)
44
+ end
45
+
46
+ private
47
+
48
+ def create_rule(rule_name, cron_expression, input_data, action)
49
+ @events_client.put_rule({
50
+ name: rule_name,
51
+ schedule_expression: "cron(#{cron_expression})",
52
+ state: 'ENABLED',
53
+ description: "Rule to #{action} EC2 instance #{@instance_id} (Name: #{@instance_name}) at specified time: cron(#{cron_expression})",
54
+ })
55
+
56
+ add_lambda_permission(rule_name)
57
+
58
+ @events_client.put_targets({
59
+ rule: rule_name,
60
+ targets: [
61
+ {
62
+ id: '1',
63
+ arn: @lambda_function_arn,
64
+ input: input_data.to_json,
65
+ },
66
+ ],
67
+ })
68
+
69
+ puts "#{action.capitalize} rule created for instance '#{@instance_name}' (ID: #{@instance_id})."
70
+ end
71
+
72
+ def add_lambda_permission(rule_name)
73
+ begin
74
+ @lambda_client.add_permission({
75
+ function_name: @lambda_function_arn,
76
+ statement_id: "#{rule_name}-Permission",
77
+ action: "lambda:InvokeFunction",
78
+ principal: "events.amazonaws.com",
79
+ source_arn: "arn:aws:events:#{@aws_region}:#{@account_id}:rule/#{rule_name}"
80
+ })
81
+
82
+ puts "Permission added for rule #{rule_name} to invoke Lambda #{@lambda_function_arn}."
83
+ rescue Aws::Lambda::Errors::ResourceConflictException => e
84
+ puts "Permission already exists: #{e.message}"
85
+ end
86
+ end
87
+
88
+ def remove_rule(rule_name)
89
+ @events_client.remove_targets({
90
+ rule: rule_name,
91
+ ids: ['1']
92
+ })
93
+ @events_client.delete_rule({
94
+ name: rule_name
95
+ })
96
+
97
+ puts "Removed rule '#{rule_name}' for instance '#{@instance_name}' (ID: #{@instance_id})."
98
+ end
99
+
100
+ def remove_lambda_permission(rule_name)
101
+ begin
102
+ @lambda_client.remove_permission({
103
+ function_name: @lambda_function_arn,
104
+ statement_id: "#{rule_name}-Permission"
105
+ })
106
+ puts "Removed Lambda permission for rule '#{rule_name}' to invoke Lambda #{@lambda_function_arn}."
107
+ rescue Aws::Lambda::Errors::ResourceNotFoundException => e
108
+ puts "Permission not found: #{e.message}"
109
+ end
110
+ end
111
+ end
@@ -1,7 +1,7 @@
1
1
  require 'aws-sdk-ec2'
2
- require 'aws-sdk-cloudwatchevents'
3
2
  require 'dotenv/load'
4
3
  require 'json'
4
+ require_relative 'cloud_watch_event_manager' # Adjust the path to where the new class is located
5
5
 
6
6
  class EC2Manager
7
7
  def initialize(instance_name, start_cron, stop_cron)
@@ -10,12 +10,15 @@ class EC2Manager
10
10
  @stop_cron = stop_cron
11
11
  @aws_region = ENV['AWS_REGION']
12
12
  @account_id = ENV['ACCOUNT_ID']
13
-
13
+
14
14
  @ec2_client = Aws::EC2::Client.new(region: @aws_region)
15
15
  @events_client = Aws::CloudWatchEvents::Client.new(region: @aws_region)
16
-
16
+
17
17
  @lambda_function_name = "ec2_auto_shutdown_start_function"
18
+ @lambda_function_arn = construct_lambda_function_arn
18
19
  @instance_id = get_instance_id_by_name
20
+
21
+ @cloudwatch_event_manager = CloudWatchEventManager.new(@events_client, @instance_id, @instance_name, @lambda_function_arn)
19
22
  end
20
23
 
21
24
  def get_instance_id_by_name
@@ -37,58 +40,20 @@ class EC2Manager
37
40
  end
38
41
 
39
42
  def create_event_rule
40
- create_start_rule
41
- create_stop_rule
43
+ @cloudwatch_event_manager.create_start_rule(@start_cron) unless @start_cron.nil?
44
+ @cloudwatch_event_manager.create_stop_rule(@stop_cron) unless @stop_cron.nil?
42
45
  puts "CloudWatch Events created for instance '#{@instance_name}' (ID: #{@instance_id})."
43
46
  end
44
47
 
45
- private
46
-
47
- def create_start_rule
48
- lambda_function_arn = construct_lambda_function_arn
49
-
50
- @events_client.put_rule({
51
- name: "StartInstanceRule-#{@instance_id}",
52
- schedule_expression: "cron(#{@start_cron})",
53
- state: 'ENABLED',
54
- description: "Rule to start EC2 instance #{@instance_id} (Name: #{@instance_name}) at specified time",
55
- })
56
-
57
- @events_client.put_targets({
58
- rule: "StartInstanceRule-#{@instance_id}",
59
- targets: [
60
- {
61
- id: '1',
62
- arn: lambda_function_arn,
63
- input: { instance_id: @instance_id, action: 'start' }.to_json,
64
- },
65
- ],
66
- })
48
+ def remove_event_rule
49
+ @cloudwatch_event_manager.remove_start_rule unless @start_cron.nil?
50
+ @cloudwatch_event_manager.remove_stop_rule unless @stop_cron.nil?
51
+ puts "CloudWatch Events removed for instance '#{@instance_name}' (ID: #{@instance_id})."
67
52
  end
68
53
 
69
- def create_stop_rule
70
- lambda_function_arn = construct_lambda_function_arn
71
-
72
- @events_client.put_rule({
73
- name: "StopInstanceRule-#{@instance_id}",
74
- schedule_expression: "cron(#{@stop_cron})",
75
- state: 'ENABLED',
76
- description: "Rule to stop EC2 instance #{@instance_id} (Name: #{@instance_name}) at specified time",
77
- })
78
-
79
- @events_client.put_targets({
80
- rule: "StopInstanceRule-#{@instance_id}",
81
- targets: [
82
- {
83
- id: '1',
84
- arn: lambda_function_arn,
85
- input: { instance_id: @instance_id, action: 'stop' }.to_json,
86
- },
87
- ],
88
- })
89
- end
54
+ private
90
55
 
91
56
  def construct_lambda_function_arn
92
57
  "arn:aws:lambda:#{@aws_region}:#{@account_id}:function:#{@lambda_function_name}"
93
58
  end
94
- end
59
+ end
@@ -1,12 +1,13 @@
1
1
  require 'aws-sdk-lambda'
2
- require 'aws-sdk-iam' # For creating the IAM role and policy
2
+ require 'aws-sdk-iam'
3
3
  require 'zip'
4
- require 'dotenv/load' # Automatically loads environment variables from .env
4
+ require 'dotenv/load'
5
5
  require 'fileutils'
6
+ require 'pry'
6
7
 
7
8
  class LambdaSetup
8
9
  def initialize
9
- @lambda_role_name = "ec2-auto-shutdown-start" # Define a unique role name
10
+ @lambda_role_name = "ec2-auto-shutdown-start"
10
11
  @lambda_handler = "ec2_auto_shutdown_start_function"
11
12
  @lambda_zip = "lambda_function.zip"
12
13
  @aws_region = ENV['AWS_REGION']
@@ -18,33 +19,34 @@ class LambdaSetup
18
19
  )
19
20
  end
20
21
 
21
- # Function to zip the Lambda function code
22
22
  def create_zip_file(dir)
23
- FileUtils.rm_f(@lambda_zip) # Remove any existing zip file
23
+ FileUtils.rm_f(@lambda_zip)
24
24
 
25
25
  Zip::File.open(@lambda_zip, Zip::File::CREATE) do |zip|
26
- Dir[File.join(dir, '**', '**')].each do |file|
27
- zip.add(file.sub(dir + '/', ''), file)
26
+ Dir.glob(File.join('lib', 'hibernate',dir, '**', '*')).each do |file|
27
+ next if File.directory?(file)
28
+ zip_path = File.basename(file)
29
+ puts "Adding #{file} as #{zip_path}"
30
+ File.open(file, 'rb') do |io|
31
+ zip.add(zip_path, io)
32
+ end
28
33
  end
29
34
  end
30
35
 
31
36
  puts "ZIP file created: #{@lambda_zip}"
32
37
  end
33
38
 
34
- # Function to check if an IAM role exists
35
39
  def iam_role_exists?(role_name)
36
40
  begin
37
41
  @iam_client.get_role(role_name: role_name)
38
- true # Role exists
42
+ true
39
43
  rescue Aws::IAM::Errors::NoSuchEntity
40
- false # Role does not exist
44
+ false
41
45
  end
42
46
  end
43
47
 
44
- # Function to create the IAM role and policy
45
48
  def create_lambda_role
46
49
  unless iam_role_exists?(@lambda_role_name)
47
- # Trust policy for Lambda service to assume this role
48
50
  trust_policy = {
49
51
  Version: "2012-10-17",
50
52
  Statement: [
@@ -58,14 +60,12 @@ class LambdaSetup
58
60
  ]
59
61
  }.to_json
60
62
 
61
- # Create the IAM role
62
63
  puts "Creating IAM role..."
63
64
  @iam_client.create_role({
64
65
  role_name: @lambda_role_name,
65
66
  assume_role_policy_document: trust_policy
66
67
  })
67
68
 
68
- # Define the custom policy for EC2 actions
69
69
  policy_document = {
70
70
  Version: "2012-10-17",
71
71
  Statement: [
@@ -81,7 +81,6 @@ class LambdaSetup
81
81
  ]
82
82
  }.to_json
83
83
 
84
- # Attach custom policy to the IAM role
85
84
  puts "Attaching custom EC2 policy to IAM role..."
86
85
  @iam_client.put_role_policy({
87
86
  role_name: @lambda_role_name,
@@ -89,7 +88,6 @@ class LambdaSetup
89
88
  policy_document: policy_document
90
89
  })
91
90
 
92
- # Attach basic execution role to allow CloudWatch logging
93
91
  @iam_client.attach_role_policy({
94
92
  role_name: @lambda_role_name,
95
93
  policy_arn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
@@ -101,39 +99,35 @@ class LambdaSetup
101
99
  end
102
100
  end
103
101
 
104
- # Function to check if the Lambda function exists
105
102
  def lambda_function_exists?(function_name)
106
103
  begin
107
104
  @lambda_client.get_function(function_name: function_name)
108
- true # Lambda function exists
105
+ true
109
106
  rescue Aws::Lambda::Errors::ResourceNotFoundException
110
- false # Lambda function does not exist
107
+ false
111
108
  end
112
109
  end
113
110
 
114
- # Function to create the Lambda function
115
111
  def create_lambda_function
116
112
  role_arn = @iam_client.get_role(role_name: @lambda_role_name).role.arn
117
113
 
118
114
  if lambda_function_exists?(@lambda_handler)
119
115
  puts "Lambda function '#{@lambda_handler}' already exists. Skipping creation."
120
116
  else
121
- # Read the ZIP file as binary content
122
117
  zip_content = File.read(@lambda_zip)
123
118
 
124
- # Create Lambda function
125
119
  begin
126
120
  puts "Creating Lambda function..."
127
121
  @lambda_client.create_function({
128
122
  function_name: @lambda_handler,
129
- runtime: 'ruby3.2', # Specify your desired runtime
130
- role: role_arn, # Use the ARN of the newly created role
123
+ runtime: 'ruby3.2',
124
+ role: role_arn,
131
125
  handler: "#{@lambda_handler}.lambda_handler",
132
126
  code: {
133
127
  zip_file: zip_content,
134
128
  },
135
129
  description: 'Lambda function to start and stop EC2 instances',
136
- timeout: 30,
130
+ timeout: 30
137
131
  })
138
132
  puts "Lambda function created."
139
133
  rescue Aws::Lambda::Errors::ServiceError => e
@@ -142,10 +136,9 @@ class LambdaSetup
142
136
  end
143
137
  end
144
138
 
145
- # Main method to execute the setup
146
139
  def run
147
- create_zip_file('lambda_function') # Pass the directory containing your Lambda function code
140
+ create_zip_file('lambda_function')
148
141
  create_lambda_role
149
142
  create_lambda_function
150
143
  end
151
- end
144
+ end
@@ -1,3 +1,3 @@
1
1
  module Hibernate
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/hibernate.rb CHANGED
@@ -3,4 +3,8 @@ require 'aws-sdk-cloudwatch'
3
3
  require 'dotenv'
4
4
  require 'json'
5
5
 
6
- Dotenv.load
6
+ Dotenv.load
7
+
8
+ module Hibernate
9
+ require_relative 'hibernate/version'
10
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hibernate
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
- - Your Name
7
+ - Manish Sharma
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-29 00:00:00.000000000 Z
11
+ date: 2024-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-ec2
@@ -108,25 +108,28 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description: A Ruby gem to automate the management of EC2 instances using AWS Lambda.
111
+ description: A Ruby gem to automate the shutdown and start of our EC2 instances
112
112
  email:
113
- - youremail@example.com
113
+ - sharma.manish7575@gmail.com
114
114
  executables:
115
115
  - hibernate
116
116
  extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
- - Readme.md
120
119
  - bin/hibernate
121
120
  - lib/hibernate.rb
121
+ - lib/hibernate/cloud_watch_event_manager.rb
122
122
  - lib/hibernate/ec2_manager.rb
123
- - lib/hibernate/lambda_function/function.rb
123
+ - lib/hibernate/lambda_function/ec2_auto_shutdown_start_function.rb
124
124
  - lib/hibernate/lambda_setup.rb
125
125
  - lib/hibernate/version.rb
126
- homepage: https://github.com/yourusername/ec2_manager
126
+ homepage: https://github.com/maniSHarma7575/hibernate
127
127
  licenses:
128
128
  - MIT
129
- metadata: {}
129
+ metadata:
130
+ source_code_uri: https://github.com/maniSHarma7575/hibernate
131
+ homepage_uri: https://github.com/maniSHarma7575/hibernate
132
+ bug_tracker_uri: https://github.com/maniSHarma7575/hibernate/issues
130
133
  post_install_message:
131
134
  rdoc_options: []
132
135
  require_paths:
@@ -145,5 +148,5 @@ requirements: []
145
148
  rubygems_version: 3.5.1
146
149
  signing_key:
147
150
  specification_version: 4
148
- summary: Manage EC2 instances with Lambda functions
151
+ summary: Automating the shutdown and start of our EC2 instances
149
152
  test_files: []
data/Readme.md DELETED
File without changes