Hi
I have been tasked with creating a Python-script to add new segments to our NSX setup, based on information from our IPAM.
I can log in and access all existing information, but creating a new segment is proving difficult.
Script in its bare form, looks like this:
------
import requests
from com.vmware import nsx_policy_client
from vmware.vapi.bindings.stub import ApiClient
from vmware.vapi.bindings.stub import StubFactory
from vmware.vapi.lib import connect
from vmware.vapi.security.user_password import create_user_password_security_context
from vmware.vapi.stdlib.client.factories import StubConfigurationFactory
BASIC_AUTH = 1
SESSION_AUTH = 2
def create_api_client(stub_factory_class, user, password, nsx_host,tcp_port=443, auth_type=BASIC_AUTH):
if auth_type == BASIC_AUTH:
stub_config = get_basic_auth_stub_config(user, password, nsx_host, tcp_port)
elif auth_type == SESSION_AUTH:
stub_config = get_session_auth_stub_config(user, password, nsx_host, tcp_port)
stub_factory = stub_factory_class.StubFactory(stub_config)
return ApiClient(stub_factory)
def get_session_auth_stub_config(user, password, nsx_host, tcp_port=443):
"""
Create a stub configuration that uses session-based authentication.
Session authentication is more efficient, since the server only
needs to perform authentication of the username/password one time.
"""
session = requests.session()
# Since the NSX manager default certificate self-signed certificate disable
session.verify = False
requests.packages.urllib3.disable_warnings()
nsx_url = 'https://%s:%s' % (nsx_host, tcp_port)
resp = session.post(nsx_url + "/api/session/create",data={"j_username": user, "j_password": password})
if resp.status_code != requests.codes.ok:
resp.raise_for_status()
# Set the Cookie and X-XSRF-TOKEN headers
session.headers["Cookie"] = resp.headers.get("Set-Cookie")
session.headers["X-XSRF-TOKEN"] = resp.headers.get("X-XSRF-TOKEN")
connector = connect.get_requests_connector(session=session, msg_protocol='rest', url=nsx_url)
stub_config = StubConfigurationFactory.new_runtime_configuration(connector)
return stub_config
def create_nsx_policy_api_client(user, password, nsx_host, tcp_port=443,auth_type=BASIC_AUTH):
return create_api_client(nsx_policy_client, user, password, nsx_host,tcp_port, auth_type)
user = "admuser"
password = "admpassword"
nsx_host = "10.10.10.10"
tcp_port = 443
# Policy login
api_client = create_nsx_policy_api_client(user, password, nsx_host, tcp_port,auth_type=SESSION_AUTH)
# Login works fine. I can list existing config fra this point.
segment_dict = {
"display_name": "test_segment",
"transport_zone_path": "overlay-transportzone",
"connectivity_path": "/infra/segments/",
"subnets": [{
"gateway_address": "172.16.10.1/24",
"network": "172.16.10.0/24"
}]
}
api_client.infra.Segments.patch(segment_id="test_segment",segment=segment_dict)
-------
The above command results in:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/adm-t1-iansto/VCF_Deploy/venv/lib/python3.12/site-packages/com/vmware/nsx_policy/infra_client.py", line 19708, in patch
return self._invoke('patch',
^^^^^^^^^^^^^^^^^^^^^
File "/home/adm-t1-iansto/VCF_Deploy/venv/lib/python3.12/site-packages/vmware/vapi/bindings/stub.py", line 345, in _invoke
return self._api_interface.native_invoke(ctx, _method_name, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/adm-t1-iansto/VCF_Deploy/venv/lib/python3.12/site-packages/vmware/vapi/bindings/stub.py", line 295, in native_invoke
raise TypeConverter.convert_to_python(method_result.error, # pylint: disable=E0702
com.vmware.vapi.std.errors_client.InvalidRequest: {messages : [], data : {}, error_type : None}
Can anyone spot what I am doing wrong?
The infra.Segments.patch
call takes a segment_id, which I believe corresponds to the id (or name) of the segment and then a python dictionary for the rest of the settings.