Skip to content

Commit 79d2acd

Browse files
eherotjeffbyrnes
authored andcommitted
feat: Add new resource: network_interfaces_eni
Uses the aws-sdk gem, added as a dependency to metadata
1 parent 9f145b1 commit 79d2acd

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ network_interface
1212
- resolved cookstyle error: recipes/default.rb:8:1 refactor: `ChefStyle/CommentFormat`
1313
- resolved cookstyle error: recipes/default.rb:9:1 refactor: `ChefStyle/CommentFormat`
1414
- resolved cookstyle error: recipes/default.rb:25:6 warning: `ChefDeprecations/NodeSet`
15+
- Add `network_interfaces_eni` resource (#32)
1516

1617

1718
# Unreleased:

metadata.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@
1212
supports 'ubuntu', '>= 14.04'
1313
supports 'debian', '>= 8.0'
1414

15+
gem 'aws-sdk', '~> 3.0'
16+
1517
depends 'modules', '>= 0.1.2'
1618
depends 'line', '~> 0.6.1'

resources/eni.rb

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
require 'aws-sdk'
2+
require 'net/http'
3+
4+
default_action :create_and_attach
5+
6+
property :description, String
7+
property :subnet_id, String, required: true
8+
property :private_ip_address, String
9+
property :security_groups, Array
10+
property :network_interface_id, String
11+
12+
action :create_and_attach do
13+
nic_id_to_attach = network_interface_id || create
14+
15+
if attached_nic_ids.include? nic_id_to_attach
16+
Chef::Log.debug "NIC with ID #{nic_id_to_attach} is already attached to #{instance_id}"
17+
else
18+
converge_by "Attach NIC #{nic_id_to_attach} to #{instance_id} at index #{next_device_index}" do
19+
ec2.attach_network_interface(
20+
network_interface_id: nic_id_to_attach,
21+
instance_id: instance_id,
22+
device_index: next_device_index
23+
)
24+
end
25+
end
26+
end
27+
28+
action :create do
29+
create
30+
end
31+
32+
action :delete do
33+
if existing_nic
34+
converge_by "Delete the NIC with ID #{existing_nic.network_interface_id}" do
35+
ec2.delete_network_interface network_interface_id: existing_nic.network_interface_id
36+
end
37+
elsif network_interface_id
38+
Chef::Log.debug "NIC with ID #{network_interface_id} does not exist"
39+
else
40+
Chef::Log.debug "NIC with description \"#{description}\" does not exist"
41+
end
42+
end
43+
44+
private
45+
46+
def create
47+
if existing_nic_id
48+
Chef::Log.debug("NIC already exists: #{existing_nic.network_interface_id}/#{description}")
49+
return existing_nic.network_interface_id
50+
end
51+
52+
converge_by "Create new NIC in description: #{description}, subnet_id: #{subnet_id}" do
53+
options = {}
54+
55+
%w(subnet_id private_ip_address security_groups).each do |prop|
56+
next unless send prop
57+
options[prop.to_sym] = send(prop)
58+
end
59+
60+
ec2.create_network_interface(options).network_interface.network_interface_id
61+
end
62+
end
63+
64+
def existing_nic
65+
@existing_nic ||= begin
66+
# Use the ID to look up the adapter if we have it
67+
return ec2.describe_network_interfaces(
68+
network_interface_id: network_interface_id
69+
).network_interfaces.first if network_interface_id
70+
71+
# Otherwise use the description
72+
results = ec2.describe_network_interfaces(
73+
filters: [{ name: 'description', values: [description] }]
74+
).network_interfaces
75+
76+
# Multiple NICs with the same description == problems
77+
if results.count > 1
78+
fail "More than one NIC matches the description \"#{description}\": " \
79+
"#{results.map(&:network_interface_id).join ', '}"
80+
end
81+
82+
results.first
83+
end
84+
end
85+
86+
def ec2
87+
@ec2 ||= AWS::EC2::Client.new
88+
end
89+
90+
def instance_id
91+
@instance_id ||= Net::HTTP.get URI 'http://169.254.169.254/2016-09-02/meta-data/instance-id'
92+
end
93+
94+
def next_device_index
95+
@next_device_index ||= begin
96+
device_numbers = macs.map do |mac|
97+
Net::HTTP.get(
98+
URI "http://169.254.169.254/2016-09-02/meta-data/network/interfaces/macs/#{mac}/device-number"
99+
).to_i
100+
end
101+
102+
device_numbers.sort.last + 1
103+
end
104+
end
105+
106+
def macs
107+
@macs ||= Net::HTTP.get(
108+
URI 'http://169.254.169.254/2016-09-02/meta-data/network/interfaces/macs/'
109+
).delete('/').split("\n")
110+
end
111+
112+
def attached_nic_ids
113+
@attached_nic_ids ||= begin
114+
macs.map do |mac|
115+
Net::HTTP.get(
116+
URI "http://169.254.169.254/2016-09-02/meta-data/network/interfaces/macs/#{mac}" \
117+
'/interface-id'
118+
)
119+
end
120+
end
121+
end

0 commit comments

Comments
 (0)