VMware {code}

 View Only
  • 1.  Adding NSX Segment via API

    Posted Feb 20, 2025 10:32 AM

    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.



  • 2.  RE: Adding NSX Segment via API

    Posted Feb 24, 2025 04:45 AM

    Simply getting the segment_dict correct helped. 

    I had success with this

    segment_dict = {
          'display_name': "test_segment01",
          'transport_zone_path': '/infra/sites/default/enforcement-points/default/transport-zones/overlay-transportzone',
          'subnets': [{'gateway_address': '172.16.10.1/24','network': '172.16.10.0/24'}]
        }
     



    ------------------------------
    Life Goal: Rule the world with Python
    ------------------------------