SDDC Import/Export for VMware Cloud on AWS – Part VI – Adding a New Feature – Writing the Import Code

In the previous post, we wrote code to export Service Access configuration. In this post, we will import the configuration.

I explained this in the previous post on exporting, but am writing it here again. Remember this screenshot from the previous post – the Linked VPC API calls. Note that we do not have an API call to create the VPC link – VPC linking is not done here.

For most other export/import operations, we issue a GET API call to retrieve the JSON, then a PUT request to save that exported JSON in a new SDDC. In this case, the VPC linking is typically done when an SDDC is created. With this feature, we are not trying to restore the link between the SDDC and the original VPC. We are only trying to restore the connected services.

What this means for the import is that I need to do some of the same operations as the export. Rather than attempting to restore the linked VPC config, I am assuming that the SDDC was built with a VPC already linked. I will first retrieve the linked VPC ID the same way I did in the export. I will then import each service config.

The first section of this function looks identical to the export function. I retrieve the linked VPC ID from the linked-vpcs API call. In line 28, I search the filesystem for all files in the format of ‘*-service_access.json’, as the export code writes out a JSON file for each service.

Line 29 begins a loop through all of the matching JSON files. I create an empty payload variable in line 30. What I’m doing is building key/value pairs in memory. If you look at the contents of s3-service_access.json below, you will see many entries that I either don’t need or cannot pass through the API. All I really need is the service name and enabled flag. Things like _last_modified_user and _last_modified_time are automatically populated by VMC when the API is invoked.

def importServiceAccess(self):
        """Imports SDDC Service Access config from a JSON file"""
        
        # First, retrieve the linked VPC ID
        myHeader = {'csp-auth-token': self.access_token}
        myURL = (self.proxy_url + '/cloud-service/api/v1/infra/linked-vpcs')
        try:
            response = requests.get(myURL,headers=myHeader)
            if response.status_code != 200:
                self.lastJSONResponse  = f'API Call Status {response.status_code}, text:{response.text}'
                return False
        except:
            self.lastJSONResponse = f'API Call Status {response.status_code}, text:{response.text}'
            return False

        json_response = response.json()       
        linked_vpcs = json_response["results"]
        num_vpcs = len(linked_vpcs)
        if num_vpcs != 1:
            print('Unexpected linked VPC count: ',num_vpcs)
            return False
        else:
            linked_vpc = linked_vpcs[0]
        
        linked_vpc_id = linked_vpc['linked_vpc_id']

        # Looking for *-service_access.json
        files = glob.glob(self.import_folder + '/*-' + self.service_access_filename)
        for f in files:
            payload = {}
            with open(f) as filehandle:
                svcaccess = json.load(filehandle)
                payload['name'] = svcaccess['name']
                payload['enabled'] = svcaccess['enabled']
                if self.import_mode == 'live':
                    myHeader = {"Content-Type": "application/json","Accept": "application/json", 'csp-auth-token': self.access_token }
                    myURL = (self.proxy_url + '/cloud-service/api/v1/infra/linked-vpcs/' + linked_vpc_id + '/connected-services/' + payload['name'])
                    json_data = json.dumps(payload)
                    svcresp = requests.put(myURL,headers=myHeader,data=json_data)
                    if svcresp.status_code == 200:
                        print("Service Access " + payload["name"] + " has been imported.")
                    else:
                        print(f'API Call Status {svcresp.status_code}, text:{svcresp.text}')
                        print(json_data)
                else:
                    print("TEST MODE - Service Access " + payload['name']  + " would have been importeed.")

        return True
{
    "name": "s3",
    "enabled": false,
    "marked_for_delete": false,
    "_create_user": "unknown",
    "_create_time": 0,
    "_last_modified_user": "pkremer@vmware.com",
    "_last_modified_time": 1611353382920,
    "_system_owned": false,
    "_protection": "UNKNOWN",
    "_revision": 5
}

The final bit of code is to invoke the import function if the import flag is enabled.

        if ioObj.service_access_import is True:
            print("Beginning Service Access import...")
            ioObj.importServiceAccess()

After reviewing this code, I realized I’m not actually checking the return value of importServiceAccess(). I then looked at the rest of the import code and realized that none of the import calls are checking for the function return value. This is one of the things that happens when you get brand new developers like me working on a project! Looks like another issue to log and more code to be added. The work on an open source project never ends!

1 comment

Leave a Reply

Your email address will not be published. Required fields are marked *