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

Add new resource: network_interfaces_eni #32

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ network_interface
- resolved cookstyle error: recipes/default.rb:8:1 refactor: `ChefStyle/CommentFormat`
- resolved cookstyle error: recipes/default.rb:9:1 refactor: `ChefStyle/CommentFormat`
- resolved cookstyle error: recipes/default.rb:25:6 warning: `ChefDeprecations/NodeSet`
- Add `network_interfaces_eni` resource (#32)


# Unreleased:
Expand Down
2 changes: 2 additions & 0 deletions metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@
supports 'ubuntu', '>= 14.04'
supports 'debian', '>= 8.0'

gem 'aws-sdk', '~> 3.0'

depends 'modules', '>= 0.1.2'
depends 'line', '~> 0.6.1'
121 changes: 121 additions & 0 deletions resources/eni.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
require 'aws-sdk'
require 'net/http'

default_action :create_and_attach

property :description, String
property :subnet_id, String, required: true
property :private_ip_address, String
property :security_groups, Array
property :network_interface_id, String

action :create_and_attach do
nic_id_to_attach = network_interface_id || create

if attached_nic_ids.include? nic_id_to_attach
Chef::Log.debug "NIC with ID #{nic_id_to_attach} is already attached to #{instance_id}"
else
converge_by "Attach NIC #{nic_id_to_attach} to #{instance_id} at index #{next_device_index}" do
ec2.attach_network_interface(
network_interface_id: nic_id_to_attach,
instance_id: instance_id,
device_index: next_device_index
)
end
end
end

action :create do
create
end

action :delete do
if existing_nic
converge_by "Delete the NIC with ID #{existing_nic.network_interface_id}" do
ec2.delete_network_interface network_interface_id: existing_nic.network_interface_id
end
elsif network_interface_id
Chef::Log.debug "NIC with ID #{network_interface_id} does not exist"
else
Chef::Log.debug "NIC with description \"#{description}\" does not exist"
end
end

private

Choose a reason for hiding this comment

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

All these can be added to the action_class block rather than adding them to the 'outer' resource class.

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @bmhughes! I did a big refactor in #44, so once that merges, and I rebase #43 & get it merged, I’ll come back to this one.


def create
if existing_nic_id
Chef::Log.debug("NIC already exists: #{existing_nic.network_interface_id}/#{description}")
return existing_nic.network_interface_id
end

converge_by "Create new NIC in description: #{description}, subnet_id: #{subnet_id}" do
options = {}

%w(subnet_id private_ip_address security_groups).each do |prop|
next unless send prop
options[prop.to_sym] = send(prop)
end

ec2.create_network_interface(options).network_interface.network_interface_id
end
end

def existing_nic
@existing_nic ||= begin
# Use the ID to look up the adapter if we have it
return ec2.describe_network_interfaces(
network_interface_id: network_interface_id
).network_interfaces.first if network_interface_id

# Otherwise use the description
results = ec2.describe_network_interfaces(
filters: [{ name: 'description', values: [description] }]
).network_interfaces

# Multiple NICs with the same description == problems
if results.count > 1
fail "More than one NIC matches the description \"#{description}\": " \
"#{results.map(&:network_interface_id).join ', '}"
end

results.first
end
end

def ec2
@ec2 ||= AWS::EC2::Client.new
end

def instance_id
@instance_id ||= Net::HTTP.get URI 'http://169.254.169.254/2016-09-02/meta-data/instance-id'
end

def next_device_index
@next_device_index ||= begin
device_numbers = macs.map do |mac|
Net::HTTP.get(
URI "http://169.254.169.254/2016-09-02/meta-data/network/interfaces/macs/#{mac}/device-number"
).to_i
end

device_numbers.sort.last + 1
end
end

def macs
@macs ||= Net::HTTP.get(
URI 'http://169.254.169.254/2016-09-02/meta-data/network/interfaces/macs/'
).delete('/').split("\n")
end

def attached_nic_ids
@attached_nic_ids ||= begin
macs.map do |mac|
Net::HTTP.get(
URI "http://169.254.169.254/2016-09-02/meta-data/network/interfaces/macs/#{mac}" \
'/interface-id'
)
end
end
end