Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert to aws-sdk and add new commands #546 #587

Merged
merged 43 commits into from
Jul 8, 2019

Conversation

kvivek1115
Copy link
Contributor

Description

Builds on #546

tas50 and others added 15 commits June 13, 2019 17:07
Without this you have to use another CLI or jump in to the UI to get the VPC ID for server create.

Signed-off-by: Tim Smith <[email protected]>
This breaks the existing commands

Signed-off-by: Tim Smith <[email protected]>
Another command to make figuring out what to feed knife ec2 server create a bit easier.

Signed-off-by: Tim Smith <[email protected]>
This lets us find the network interface IDs we need when using knife ec2 server create

Signed-off-by: Tim Smith <[email protected]>
No one should ever rely on these

Signed-off-by: Tim Smith <[email protected]>
Signed-off-by: Tim Smith <[email protected]>
You need to specify the security group ID if you're provisioning into a VPC

Signed-off-by: Tim Smith <[email protected]>
Unless you have a 30" monitor those strings are too long to display things correctly and it makes the output near useless

Signed-off-by: Tim Smith <[email protected]>
We already have a method that does this for us. There's really no reason to do it twice.

Signed-off-by: Tim Smith <[email protected]>
It's not a real api call, but instead a giant hash if fog-aws.

Signed-off-by: Tim Smith <[email protected]>
Signed-off-by: Tim Smith <[email protected]>
 - Add name and tags values.
 - Implement extract_tags from struct.

Signed-off-by: Vivek Singh <[email protected]>
…l-mode

 - Fix server list error when format is json.

Signed-off-by: Vivek Singh <[email protected]>
Vivek Singh added 7 commits June 17, 2019 11:51
Signed-off-by: Vivek Singh <[email protected]>
 - Added dry_run option.
 - Updated the delete method to use AWS client.

Signed-off-by: Vivek Singh <[email protected]>
 - Add spot instances create method support.
 - Replace fog to SDK for getting addresses.
 - Modify the server attribute construction method.
 - Add various helpers methods.

Signed-off-by: Vivek Singh <[email protected]>
 - Update output params and set required params for further actions.
 - Update other fog apis to aws SDK.
 - Update logic to detect platform as a return in response params.

Signed-off-by: Vivek Singh <[email protected]>
 - Update windows check server instance raise message.
 - Minor fixes to print instance details.

Signed-off-by: Vivek Singh <[email protected]>
 - Update get password related code.
 - Attach network interfaces related changes.
 - Minor fixes
 - Chefstyle

Signed-off-by: Vivek Singh <[email protected]>
 - Remove memoization of bucket_obj.
 - Construct s3_connection object.

Signed-off-by: Vivek Singh <[email protected]>
@kvivek1115
Copy link
Contributor Author

Hey, @tas50 thanks for pointing out the typo.

I am near to finish the refactoring only specs parts are remaining.

Any suggestions would be helpful? Thanks

Vivek Singh added 4 commits June 20, 2019 17:58
Signed-off-by: Vivek Singh <[email protected]>
 - Add default source us-east-1

Signed-off-by: Vivek Singh <[email protected]>
 - Minor changes in ec2 ami list specs.

Signed-off-by: Vivek Singh <[email protected]>
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
s.required_ruby_version = ">= 2.5"

s.add_dependency "chef", ">= 15.1"
s.add_dependency "fog-aws", ">= 1", "< 4"
s.add_dependency "aws-sdk", "~> 3.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So one thing we're going to want to do is use the individual aws-sdk gems instead of the main gem. The main gem depends on 182 other gems which we really don't want to do in Chef-DK. A good start would be to see if we can get away with just the ec2 gem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tas50 Yes, we can do that. As per my understaning, we just only need 'aws-sdk-ec2' and aws-sdk-s3. will update and let you know in case of any issue thanks.

 - Minor fixes

Signed-off-by: Vivek Singh <[email protected]>
Vivek Singh added 2 commits June 26, 2019 15:17
 - Minor fix in ec2 server delete to fetch the region.
 - Initial setup for ec2 server create specs.
 - Remove aws related configs vars.

Signed-off-by: Vivek Singh <[email protected]>
 - For non-aws cli need to provide base64 encoded string value for user_data params.

Signed-off-by: Vivek Singh <[email protected]>
Vivek Singh added 6 commits June 27, 2019 15:08
 - Fix issue chef#591.
 - name_args nil issue and fix windows_password not called when winrm_password is nil
 - Remove some of specs related to old bootstrap process.

Signed-off-by: Vivek Singh <[email protected]>
Signed-off-by: Vivek Singh <[email protected]>
Signed-off-by: Vivek Singh <[email protected]>
Signed-off-by: Vivek Singh <[email protected]>
@kvivek1115 kvivek1115 changed the title WIP: Convert to aws-sdk and add new commands #546 Convert to aws-sdk and add new commands #546 Jul 1, 2019
Signed-off-by: Vivek Singh <[email protected]>
vsingh-msys added 3 commits July 3, 2019 14:08
 - Add connection_user and  connection_protocol methods.
 - Fix minor bugs.
 - Rename winrm_user to connection_user.
 - Fix bug related to encode user_data for ssl configuration.

Signed-off-by: vsingh-msys <[email protected]>
 - Minor bugs fix.
 - Ensured chef-style but robocop is failed on Travis.

Signed-off-by: Vivek Singh <[email protected]>
Signed-off-by: Vivek Singh <[email protected]>
Copy link

@Nimesh-Msys Nimesh-Msys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And as we are using a new library now, please include well explained YARD comments and provide references wherever applicable.

else
server_list += get_server_list(server)
if config[:format] == "summary"
ami_hashes.each_pair do |_k, v|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. servers_list is not explanatory. If possible can we use a better defined variable name here.
  2. We could also use push to insert multiple values in one go !
servers = []
h.each do |k, v|
  servers.push v["image_id]",
               v["platform"]
end

Or a one liner:
servers = h.inject([]){|arr, (_, v)| arr.push(v["image_id"],v["platform"])}

}
def connection_string
conn = {}
conn[:region] = locate_config_value(:region) || "us-east-1" # Default region us-east-1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use this as a default in option.

conn[:region] = locate_config_value(:region) || "us-east-1" # Default region us-east-1
conn[:credentials] = if locate_config_value(:use_iam_profile)
Aws::InstanceProfileCredentials.new
elsif locate_config_value(:aws_session_token)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The third argument of the constructor is anyway default, we can skip this check. Also can DRY-up last else block then.

connection_settings[:aws_session_token] = locate_config_value(:aws_session_token)
# @return [Aws::EC2::Client]
def ec2_connection
@ec2_connection ||= begin

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block wouldn't be required for one liner codes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay sure thanks

# @return [Hash]
def server_hashes(server_obj)
server_data = {}
%w{ebs_optimized image_id instance_id instance_type key_name platform public_dns_name public_ip_address private_dns_name private_ip_address root_device_type}.each do |id|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. The sorted array of strings would be more readable.
  2. If we could store server_obj.instances[0] in an object, method would look clean.
  3. map(&:code) could be used at multiple places in this method
  4. Safe navigation could be used in iam_instance_profile the way it is used for volume_id

ui.error "The following network interfaces are invalid: " \
"#{invalid_nic_ids.join(', ')}"
exit 1
end

def vpc_id
@vpc_id ||= begin
ec2_connection.subnets.get(locate_config_value(:subnet_id)).vpc_id
subnet = fetch_subnet(locate_config_value(:subnet_id))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of splitting it in two lines, we can use method chaining. & also can avoid using a block here.

end
response.body["passwordData"]
response = fetch_password_data(server_id)
return false unless response.password_data

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can simply use !response.password_data.nil? That would return the required Boolean arguments.

# Set default port 5986 if winrm_ssl return true otherwise set it to 5985
# Set default port 22 for ssh protocol
# @return [Integer]
def assign_default_port

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using such elements by a constant.

DEFAULT_PORT = winrm? ? config_value(:winrm_ssl) ? 5985 : 5986 : 22

Copy link
Contributor Author

@kvivek1115 kvivek1115 Jul 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, As we required these value at the instance level so not recommended.
Also, Ternary operators must not be nested. Prefer if or else constructs instead. Thanks

# url values override CLI flags, if you provide both
# we'll use the one that you gave in the URL.
def connection_protocol
return @connection_protocol if @connection_protocol

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using @connection_protocol ||= would be nice and symmetrical to connection_user

ui.warn("Deleted server #{instance_id}")

if config[:purge]
if config[:chef_node_name]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. thing_to_delete = config[:chef_node_name] || fetch_node_name(instance_id)
  2. can we replace this variable name as just delete

 - Revert AWS key proc to get the value in s3_source.
 - Fix style at some places.

Signed-off-by: Vivek Singh <[email protected]>
@kvivek1115
Copy link
Contributor Author

@Nimesh-Msys thanks for the review comments. Updated the code accordingly.

Signed-off-by: Vivek Singh <[email protected]>

def image_params
params = {}
owner = locate_config_value(:owner) || "aws-marketplace" # aws-marketplace, microsoft
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following what this comment means

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are the values that we can use. Will move in options for better understanding.

filters = []
filters << { platform: locate_config_value(:platform) } if locate_config_value(:platform)

# TODO: Need to find substring to match in the description
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we get an issue cut for this todo item so we don't forget it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted @tas50 thanks

state: state,
security_groups: security_groups,
tags: tags
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So as a general pattern this concerns me because OpenStruct is pretty terrible and instance_double would be better. So please never copy this a general way to mock objects. But if all the aws gem is passing back is an OpenStruct then you have to do this...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay sure @lamont-granquist thanks!

# @return [Struct]
def normalize_server_data(server_hashes)
require "ostruct"
OpenStruct.new(server_hashes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also makes me a bit worried, but it looks like the blast zone of this is relatively contained and probably necessary due to aws-sdk using OpenStruct everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lamont-granquist to make data consistent same as aws-sdk response OpenStruct used here. will look into it what we can do. Thanks

@tas50 tas50 merged commit 22d4f55 into chef:master Jul 8, 2019
@tas50
Copy link
Contributor

tas50 commented Jul 8, 2019

@vsingh-msys I'm going to merge this as-is since we need to ship this gem, but can you followup with the feedback that @Nimesh-Msys gave in another PR? Thanks for wrapping this all up. It's a huge amount of tech debt that we just paid down and it'll make this project usable for years to come.

@kvivek1115
Copy link
Contributor Author

@vsingh-msys I'm going to merge this as-is since we need to ship this gem, but can you follow up with the feedback that @Nimesh-Msys gave in another PR?

@tas50 I have almost completed the @Nimesh-Msys feedback already and some of them are not required such as

  1. Rename variable servers_list,
  2. Use one liner servers = h.inject([]){|arr, (_, v)| arr.push(v["image_id"],v["platform"])}
  3. Use of push for mutiple variable.
    etc.

As of now, we are fine. Thanks

@kvivek1115
Copy link
Contributor Author

Fixes for issue #529

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants