lib/cloudstack-cli/helper.rb in cloudstack-cli-1.5.3 vs lib/cloudstack-cli/helper.rb in cloudstack-cli-1.5.4
- old
+ new
@@ -164,41 +164,67 @@
end
server
end
def create_port_rules(server, port_rules, async = true)
- frontendip = nil
+ frontendip_id = nil
jobs = []
client.verbose = async
project_id = server['projectid'] || nil
port_rules.each do |pf_rule|
- ip = pf_rule.split(":")[0]
- if ip != ''
- ip_addr = client.get_public_ip_address(ip, project_id)
- unless ip_addr
- say "Error: IP #{ip} not found.", :red
+ pf_rule = pf_rule_to_object(pf_rule)
+ if pf_rule[:ipaddress]
+ pub_ip = client.list_public_ip_addresses(
+ network_id: get_server_default_nic(server)["networkid"],
+ project_id: project_id,
+ ipaddress: pf_rule[:ipaddress]
+ )
+ ip_addr = pub_ip.find { |addr| addr['ipaddress'] == pf_rule[:ipaddress]} if pub_ip
+ if ip_addr
+ frontendip = ip_addr['id']
+ else
+ say "Error: IP #{pf_rule[:ipaddress]} not found.", :red
next
end
- else
- ip_addr = frontendip ||= client.associate_ip_address(
- network_id: server["nic"].first["networkid"]
- )["ipaddress"]
end
- port = pf_rule.split(":")[1]
- args = {
- ipaddressid: ip_addr["id"],
- publicport: port,
- privateport: port,
- protocol: 'TCP',
- virtualmachineid: server["id"]
- }
- if async
- say "Create port forwarding rule #{ip_addr['ipaddress']}:#{port} for server #{server["name"]}.", :yellow
- client.create_port_forwarding_rule(args)
- return
+
+ # check if there is already an existing rule
+ rules = client.list_port_forwarding_rules(
+ networkid: get_server_default_nic(server)["networkid"],
+ ipaddressid: frontendip_id,
+ projectid: project_id
+ )
+ existing_pf_rules = rules.find do |rule|
+ # remember matching address for additional rules
+ frontendip_id = rule['ipaddressid'] if rule['virtualmachineid'] == server['id']
+
+ rule['virtualmachineid'] == server['id'] &&
+ rule['publicport'] == pf_rule[:publicport] &&
+ rule['privateport'] == pf_rule[:privateport] &&
+ rule['protocol'] == pf_rule[:protocol]
+ end
+
+ if existing_pf_rules
+ say "Port forwarding rule on port #{pf_rule[:privateport]} for VM #{server["name"]} already exists.", :yellow
else
- jobs << client.create_port_forwarding_rule(args, {sync: true})['jobid']
+ unless frontendip_id
+ frontendip_id = client.associate_ip_address(
+ network_id: get_server_default_nic(server)["networkid"],
+ project_id: project_id
+ )['ipaddress']['id']
+ end
+ args = pf_rule.merge({
+ ipaddressid: frontendip_id,
+ virtualmachineid: server["id"]
+ })
+ if async
+ say "Create port forwarding rule #{pf_rule[:ipaddress]}:#{port} for VM #{server["name"]}.", :yellow
+ client.create_port_forwarding_rule(args)
+ return
+ else
+ jobs << client.create_port_forwarding_rule(args, {sync: true})['jobid']
+ end
end
end
jobs
end
@@ -265,59 +291,23 @@
project_id: project_id
)
end
end
- ##
- # Finds the public ip for a server
-
- def get_server_public_ip(server, cached_rules=nil)
- return nil unless server
-
- # find the public ip
- nic = get_server_default_nic(server) || {}
- if nic['type'] == 'Virtual'
- ssh_rule = get_ssh_port_forwarding_rule(server, cached_rules)
- ssh_rule ? ssh_rule['ipaddress'] : nil
- else
- nic['ipaddress']
- end
- end
-
- ##
- # Gets the SSH port forwarding rule for the specified server.
-
- def get_ssh_port_forwarding_rule(server, cached_rules=nil)
- rules = cached_rules || client.list_port_forwarding_rules(project_id: server["projectid"]) || []
- rules.find_all { |r|
- r['virtualmachineid'] == server['id'] &&
- r['privateport'] == '22'&&
- r['publicport'] == '22'
- }.first
- end
-
- ##
- # Returns the fully qualified domain name for a server.
-
- def get_server_fqdn(server)
- return nil unless server
-
- nic = get_server_default_nic(server) || {}
- networks = client.list_networks(project_id: server['projectid']) || {}
-
- id = nic['networkid']
- network = networks.select { |net|
- net['id'] == id
- }.first
- return nil unless network
-
- "#{server['name']}.#{network['networkdomain']}"
- end
-
def get_server_default_nic(server)
server['nic'].each do |nic|
return nic if nic['isdefault']
end
+ end
+
+ def pf_rule_to_object(pf_rule)
+ pf_rule = pf_rule.split(":")
+ {
+ ipaddress: (pf_rule[0] == '' ? nil : pf_rule[0]),
+ privateport: pf_rule[1],
+ publicport: (pf_rule[2] || pf_rule[1]),
+ protocol: (pf_rule[3] || 'tcp').downcase
+ }
end
end
end