Closed dmgeurts closed 8 months ago
Managed to get the foreman-proxy setup to load and detect the service. But am getting the following when trying to use it when adding a subnet to Foreman:
ERF12-3215 [ProxyAPI::ProxyException]: Unable to obtain subnet 10.0.0.0/24 from External IPAM. ([RestClient::InternalServerError]: 500 Internal Server Error) for proxy https://foreman.domain.com:9090/ipam
foreman-proxy log entries:
2022-08-12T02:12:35 566d16d6 [I] Started GET /ipam/subnet/10.0.0.0/24 group=
2022-08-12T02:12:35 566d16d6 [W] Error processing request '566d16d6-e163-4b64-b398-3ad48b7c7c80: <NoMethodError>: undefined method `zero?' for nil:NilClass
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib/smart_proxy_ipam/netbox/netbox_client.rb:49:in `get_ipam_subnet_by_cidr'
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib/smart_proxy_ipam/netbox/netbox_client.rb:29:in `get_ipam_subnet'
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib/smart_proxy_ipam/ipam_api.rb:100:in `block in <class:Api>'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1675:in `call'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1675:in `block in compile!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1013:in `block (3 levels) in route!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1032:in `route_eval'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1013:in `block (2 levels) in route!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1061:in `block in process_route'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1059:in `catch'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1059:in `process_route'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1011:in `block in route!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1008:in `each'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1008:in `route!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1129:in `block in dispatch!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `block in invoke'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `catch'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `invoke'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1124:in `dispatch!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:939:in `block in call!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `block in invoke'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `catch'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `invoke'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:939:in `call!'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:929:in `call'
/usr/share/foreman-proxy/lib/proxy/log.rb:105:in `call'
/usr/share/foreman-proxy/lib/proxy/request_id_middleware.rb:11:in `call'
/usr/share/gems/gems/rack-protection-2.1.0/lib/rack/protection/xss_header.rb:18:in `call'
/usr/share/gems/gems/rack-protection-2.1.0/lib/rack/protection/path_traversal.rb:16:in `call'
/usr/share/gems/gems/rack-protection-2.1.0/lib/rack/protection/json_csrf.rb:26:in `call'
/usr/share/gems/gems/rack-protection-2.1.0/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.1.0/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.1.0/lib/rack/protection/frame_options.rb:31:in `call'
/usr/share/gems/gems/rack-2.2.3/lib/rack/null_logger.rb:11:in `call'
/usr/share/gems/gems/rack-2.2.3/lib/rack/head.rb:12:in `call'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/show_exceptions.rb:22:in `call'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:216:in `call'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1991:in `call'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1542:in `block in call'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1769:in `synchronize'
/usr/share/gems/gems/sinatra-2.1.0/lib/sinatra/base.rb:1542:in `call'
/usr/share/gems/gems/rack-2.2.3/lib/rack/urlmap.rb:74:in `block in call'
/usr/share/gems/gems/rack-2.2.3/lib/rack/urlmap.rb:58:in `each'
/usr/share/gems/gems/rack-2.2.3/lib/rack/urlmap.rb:58:in `call'
/usr/share/gems/gems/rack-2.2.3/lib/rack/builder.rb:244:in `call'
/usr/share/gems/gems/rack-2.2.3/lib/rack/handler/webrick.rb:95:in `service'
/usr/share/ruby/webrick/httpserver.rb:140:in `service'
/usr/share/ruby/webrick/httpserver.rb:96:in `run'
/usr/share/ruby/webrick/server.rb:307:in `block in start_thread'
/usr/share/gems/gems/logging-2.3.0/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context'
2022-08-12T02:12:35 566d16d6 [I] Finished GET /ipam/subnet/10.0.0.0/24 with 500 (28.65 ms)
I think the issue may well be that subnets are now called prefixes as I don't see the term subnets in the Netbox API documentation. https://docs.netbox.dev/en/stable/rest-api/overview/
A query that used to be GET /ipam/subnet/10.0.0.0/24
, I think should now be: GET /api/ipam/ip-addresses/?q=&parent=10.0.0.0/24
On a Netbox installation the API can be inspected as follows: https://netbox.domain.com/api/ipam/?format=api
GET /api/ipam/?format=api
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"aggregates": "https://netbox.domain.com/api/ipam/aggregates/?format=api",
"asns": "https://netbox.domain.com/api/ipam/asns/?format=api",
"fhrp-group-assignments": "https://netbox.domain.com/api/ipam/fhrp-group-assignments/?format=api",
"fhrp-groups": "https://netbox.domain.com/api/ipam/fhrp-groups/?format=api",
"ip-addresses": "https://netbox.domain.com/api/ipam/ip-addresses/?format=api",
"ip-ranges": "https://netbox.domain.com/api/ipam/ip-ranges/?format=api",
"prefixes": "https://netbox.domain.com/api/ipam/prefixes/?format=api",
"rirs": "https://netbox.domain.com/api/ipam/rirs/?format=api",
"roles": "https://netbox.domain.com/api/ipam/roles/?format=api",
"route-targets": "https://netbox.domain.com/api/ipam/route-targets/?format=api",
"service-templates": "https://netbox.domain.com/api/ipam/service-templates/?format=api",
"services": "https://netbox.domain.com/api/ipam/services/?format=api",
"vlan-groups": "https://netbox.domain.com/api/ipam/vlan-groups/?format=api",
"vlans": "https://netbox.domain.com/api/ipam/vlans/?format=api",
"vrfs": "https://netbox.domain.com/api/ipam/vrfs/?format=api"
}
Or, could it be that my config files aren't read?
user@foreman:/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib$ grep /subnet . -R
./smart_proxy_ipam/ipam_api.rb: get '/subnet/:address/:prefix/next_ip' do
./smart_proxy_ipam/ipam_api.rb: get '/subnet/:address/:prefix' do
./smart_proxy_ipam/ipam_api.rb: get '/groups/:group/subnets' do
./smart_proxy_ipam/ipam_api.rb: get '/subnet/:address/:prefix/:ip' do
./smart_proxy_ipam/ipam_api.rb: post '/subnet/:address/:prefix/:ip' do
./smart_proxy_ipam/ipam_api.rb: delete '/subnet/:address/:prefix/:ip' do
./smart_proxy_ipam/phpipam/phpipam_client.rb: subnets = @api_resource.get("sections/#{group[:id]}/subnets/")
user@foreman:/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib$ grep /ip-addresses . -R
./smart_proxy_ipam/netbox/netbox_client.rb: url = "ipam/ip-addresses/?#{URI.encode_www_form({ address: ip })}"
./smart_proxy_ipam/netbox/netbox_client.rb: response = @api_resource.post('ipam/ip-addresses/', data.to_json)
./smart_proxy_ipam/netbox/netbox_client.rb: response = @api_resource.get("ipam/ip-addresses/?#{params}")
./smart_proxy_ipam/netbox/netbox_client.rb: response = @api_resource.delete("ipam/ip-addresses/#{address_id}/")
I'm confused. The request sent to my IPAM is incompatible with Netbox, but the interpreter calls the netbox_client.rb code for the reply from Netbox. So what is going wrong?
See the log in the 2nd comment. netbox_client.rb errors are thrown, yet the last line shows that a call is made for phpipam (according to ipam_api.rb) instead of Netbox (netbox_client.rb)
Thanks @dmgeurts - A few questions:
config/externalipam.yml
and config/externalipam_netbox.yml
files?
- What version of Netbox are you running?
We were on v3.2.0, but I've just upgraded to v3.3.2.
- Can you post the contents for your
config/externalipam.yml
andconfig/externalipam_netbox.yml
files?
~$ locate externalipam.yml
/etc/foreman-proxy/settings.d/externalipam.yml
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam.yml
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam.yml.example
~$ sudo diff /etc/foreman-proxy/settings.d/externalipam.yml /usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam.yml
~$ sudo cat /etc/foreman-proxy/settings.d/externalipam.yml
---
:enabled: true
:use_provider: externalipam_netbox
And externalipam_netbox.yml
:
~$ locate externalipam_netbox.yml
/etc/foreman-proxy/settings.d/externalipam_netbox.yml
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam_netbox.yml
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam_netbox.yml.example
~$ sudo diff /etc/foreman-proxy/settings.d/externalipam_netbox.yml /usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam_netbox.yml
~$ sudo cat /etc/foreman-proxy/settings.d/externalipam_netbox.yml
---
:url: 'https://netbox.domain.com/'
:token: '********'
- When you create the Netbox subnet in the Foreman UI, are you associating the subnet with the External IPAM enabled proxy?
Yes indeed. I believe that without it the ipam proxy plugin code won't fire and will just create a local entry not tied to the subnet recorded in Netbox. We get syslog entries as posted when trying to associate the subnet to an external IPAM enabled proxy. The IPAM enabled proxy and the Foreman server are currently one and the same machine.
Thank you for looking into this.
Thanks @dmgeurts - The configs look fine. Let me see if I can replicate the issue using Netbox 3.3.2.
@grizzthedj Any luck replicating things?
I'm now on Foreman 3.4.0 and Netbox 3.3.6. The API calls still fail for me with the same error.
Foreman is installed on CentOS Stream 8.
Just verified the correct API call URL using curl from Foreman and it works, so I have the right API token and permissions set on Netbox.
How I installed the plugin:
sudo gem install smart_proxy_ipam
sudo cp /usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam_netbox.yml.example /etc/foreman-proxy/settings.d/externalipam_netbox.yml
sudo vi /etc/foreman-proxy/settings.d/externalipam_netbox.yml
---
:url: 'https://netbox.domain.com'
:token: ******
sudo cp /usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/settings.d/externalipam.yml.example /etc/foreman-proxy/settings.d/externalipam.yml
sudo vi /etc/foreman-proxy/settings.d/externalipam.yml
---
:enabled: true
:use_provider: externalipam_netbox
sudo vi /usr/share/foreman-proxy/bundler.d/Gemfile.local.rb
gem 'smart_proxy_ipam'
sudo systemctl restart foreman-proxy
Am I missing something obvious?
One other thing I've noticed under Infrastructure >> Smart Proxies >> Services is a spinning wheel for External IPAM
:
Hi @dmgeurts - My apologies for the delay here. It has been difficult to find any time. I have some issues in my local env to work though before I can try to replicate, but the call from Foreman to the Proxy would be GET /ipam/subnet/10.0.0.0/24
. The "real" call to Netbox, from the Proxy, would be: GET /api/ipam/ip-addresses/?q=&parent=10.0.0.0/24
.
@grizzthedj So how do I start troubleshooting this? I've run a tcpdump but after the initial hits when I didn't have the right filters set so didn't see the HTTP header defaults (URL etc). I'm not seeing much. These are the foreman-proxy logs when trying to add a subnet:
2022-11-29T14:49:37 9a4f8085 [I] Started GET /ipam/subnet/10.255.12.0/24 group=
2022-11-29T14:49:37 9a4f8085 [W] Error processing request '9a4f8085-7386-4d25-be6a-6ddbdb9101ff: <JSON::ParserError>: 783: unexpected token at ''
/usr/share/ruby/json/common.rb:156:in `parse'
/usr/share/ruby/json/common.rb:156:in `parse'
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib/smart_proxy_ipam/netbox/netbox_client.rb:48:in `get_ipam_subnet_by_cidr'
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib/smart_proxy_ipam/netbox/netbox_client.rb:29:in `get_ipam_subnet'
/usr/local/share/gems/gems/smart_proxy_ipam-0.1.4/lib/smart_proxy_ipam/ipam_api.rb:100:in `block in <class:Api>'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1686:in `call'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1686:in `block in compile!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1023:in `block (3 levels) in route!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1042:in `route_eval'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1023:in `block (2 levels) in route!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1071:in `block in process_route'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1069:in `catch'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1069:in `process_route'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1021:in `block in route!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1018:in `each'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1018:in `route!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1140:in `block in dispatch!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `block in invoke'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `catch'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `invoke'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1135:in `dispatch!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:949:in `block in call!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `block in invoke'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `catch'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `invoke'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:949:in `call!'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:938:in `call'
/usr/share/foreman-proxy/lib/proxy/log.rb:105:in `call'
/usr/share/foreman-proxy/lib/proxy/request_id_middleware.rb:11:in `call'
/usr/share/gems/gems/rack-protection-2.2.2/lib/rack/protection/xss_header.rb:18:in `call'
/usr/share/gems/gems/rack-protection-2.2.2/lib/rack/protection/path_traversal.rb:16:in `call'
/usr/share/gems/gems/rack-protection-2.2.2/lib/rack/protection/json_csrf.rb:26:in `call'
/usr/share/gems/gems/rack-protection-2.2.2/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.2.2/lib/rack/protection/base.rb:50:in `call'
/usr/share/gems/gems/rack-protection-2.2.2/lib/rack/protection/frame_options.rb:31:in `call'
/usr/share/gems/gems/rack-2.2.4/lib/rack/null_logger.rb:11:in `call'
/usr/share/gems/gems/rack-2.2.4/lib/rack/head.rb:12:in `call'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/show_exceptions.rb:22:in `call'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:218:in `call'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1993:in `call'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1553:in `block in call'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1769:in `synchronize'
/usr/share/gems/gems/sinatra-2.2.2/lib/sinatra/base.rb:1553:in `call'
/usr/share/gems/gems/rack-2.2.4/lib/rack/urlmap.rb:74:in `block in call'
/usr/share/gems/gems/rack-2.2.4/lib/rack/urlmap.rb:58:in `each'
/usr/share/gems/gems/rack-2.2.4/lib/rack/urlmap.rb:58:in `call'
/usr/share/gems/gems/rack-2.2.4/lib/rack/builder.rb:244:in `call'
/usr/share/gems/gems/rack-2.2.4/lib/rack/handler/webrick.rb:95:in `service'
/usr/share/ruby/webrick/httpserver.rb:140:in `service'
/usr/share/ruby/webrick/httpserver.rb:96:in `run'
/usr/share/ruby/webrick/server.rb:307:in `block in start_thread'
/usr/share/gems/gems/logging-2.3.1/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context'
2022-11-29T14:49:37 9a4f8085 [I] Finished GET /ipam/subnet/10.255.12.0/24 with 500 (8.82 ms)
If I do a netcat to the Foreman proxy hostname on port 9090 it succeeds. Yet this is the error it throws in the GUI:
I've also noticed the following in proxy.log
when I try to do a curl to http(s)://foreman.domain.com:9090/ipam
:
2022-11-29T14:22:54 [E] <OpenSSL::SSL::SSLError> SSL_accept returned=1 errno=0 state=error: http request
/usr/share/ruby/webrick/server.rb:299:in `accept'
/usr/share/ruby/webrick/server.rb:299:in `block (2 levels) in start_thread'
/usr/share/ruby/webrick/utils.rb:263:in `timeout'
/usr/share/ruby/webrick/server.rb:297:in `block in start_thread'
/usr/share/gems/gems/logging-2.3.1/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context'
2022-11-29T14:23:05 393359c8 [I] Started GET /ipam
2022-11-29T14:23:05 393359c8 [I] Finished GET /ipam with 404 (0.42 ms)
2022-11-29T14:23:20 0599f96e [I] Started GET /ipam
2022-11-29T14:23:20 0599f96e [I] Finished GET /ipam with 404 (0.33 ms)
Doing a TCP dump I don't see any requests being made, so this looks like a local issue to the Smart Proxy.
@dmgeurts any luck getting this plugin working? I followed the same installation steps that you laid out earlier in this thread. Though when I do a curl https://foreman.domain.com:9090/ipam
it just says Requested url not found
I was hoping to add a provider to this for Bluecat, but am seeing the same issue. I am getting Requested url not found
as well. I know there is an active pull request to get this plugin merged into the main project. Is this still being planned?
I've not had this plugin working successfully yet. In all honestly, I need to check things after updating Foreman and Katello. As the plugin is no longer listed under the foreman-proxy last time I checked.
Hi @dmgeurts - My apologies for the delay here. It has been difficult to find any time. I have some issues in my local env to work though before I can try to replicate, but the call from Foreman to the Proxy would be
GET /ipam/subnet/10.0.0.0/24
. The "real" call to Netbox, from the Proxy, would be:GET /api/ipam/ip-addresses/?q=&parent=10.0.0.0/24
.
Has this plugin been integrated into Foreman? I've seen references alluding to this, but I'm still unable to get this plugin working. On Foreman 3.5.2 I'm still seeing this:
I'd be happy to troubleshoot the issue, if only I knew how...
Smart-proxy logs show the successful initialisation of both elements:
Right, I've finally worked out why the plugin didn't work for me. I'm embarrassed to admit the simplicity of it and how long it took me to work it out. But, maybe it will save some other poor soul time if I explain what happened.
The Netbox access logs showed:
user@netbox:~$ sudo tail /var/log/nginx/access.log
10.2.0.12 - - [12/Feb/2024:16:48:12 +0100] "GET //api/ipam/prefixes/?status=active&prefix=10.2.3.0%2F24 HTTP/1.1" 302 0 "-" "Ruby"
10.2.0.12 - - [12/Feb/2024:17:08:35 +0100] "GET //api/ipam/prefixes/?status=active&prefix=10.2.3.0%2F24 HTTP/1.1" 302 0 "-" "Ruby"
10.2.0.12 - - [12/Feb/2024:17:15:15 +0100] "GET //api/ipam/prefixes/?status=active&prefix=10.1.0.0%2F24 HTTP/1.1" 302 0 "-" "Ruby"
Foreman showed a 500 error in the UI and Netbox gives a 302 error. Checking the API key from terminal on the Foreman server works fine and the request is correct. However, I failed to notice the significance of the double slashes //api/...
!
The reason I ended up with the double slashes is the following config in /etc/foreman-proxy/settings.d/externalipam_netbox.yml
:
---
# url is the hostname and path of the Netbox instance
:url: 'https://netbox.domain.com/'
Note the trailing slash. After removing it everything works perfectly. Meanwhile, I'm now on Foreman 3.9, so yes this plugin works fine on Foreman 3.9 and probably everything in between 3.3 and 3.9 too, if you don't make my mistake that is!
Hi,
I see 2 years ago this plugin needed a fair bit of work to get working and some things were pending Foreman updates. What's the current status, or should I not bother as Foreman has moved along too far since?