Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(app): limit the docker API version supported by the frontend #11855

Merged

Conversation

xAt0mZ
Copy link
Member

@xAt0mZ xAt0mZ commented May 22, 2024

Close EE-6918

Introduced auto versioned calls to the docker API proxy.

  • each call to the docker proxy API will automatically triggers a call to retrieve the max API version supported by the remote environment
    • this call is cached for 5 minutes (per environment) on the frontend to avoid flooding the network
  • when the remote API version if above our max supported version, we inject in the URL the max API version we support
  • when the remote API version if below our max supported version, we don't change the URL (docker API will use its maximum API version)

To avoid payload changes side effects, our defined MAX API VERSION should be the lowest version we decide to officially support.

Right now the latest Docker version is Docker 26 (API v1.45) and we state to officially support latest minus 2 versions (Docker 24 = API v1.43).

As our frontend code is currently using v1.41 types, the MAX API VERSION is currently v1.41 (Docker 20).

Example

  • volumes service generates a request to /endpoints/{id}/docker/volumes
  • request on a Docker 26 environment (API v1.45) will issue to /endpoints/{id}/docker/v1.41/volumes (guarantee to return the proper payload, because we ask for a specific version)
  • request on a Docker 19 environment (API v1.40) will issue to /endpoints/{id}/docker/volumes with no guarantee to work! (call will return with 1.40 format which is below our minimum supported version)

To reduce the overhead of proxying all requests in Axios (used by React) and AngularJS $resources / $http, all AngularJS services emitting requests to the docker API proxy have been migrated to Axios.

@xAt0mZ xAt0mZ force-pushed the feat/EE-6918/CE/develop/limit-docker-api-version-used-frontend branch from b2afc2e to ad883ce Compare May 22, 2024 17:30
@xAt0mZ xAt0mZ force-pushed the feat/EE-6918/CE/develop/limit-docker-api-version-used-frontend branch from ad883ce to e11f9f3 Compare May 23, 2024 14:27
@xAt0mZ
Copy link
Member Author

xAt0mZ commented May 29, 2024

Technical note about fix(app): ensure axios functions are running inside AngularJS digest cycle

Initial issues

  • When an ES6 async function is used in AngularJS, it does not trigger a refresh of the UI.
    All our services written in AngularJS were using $q, which automatically handles the UI updates for us.
    To leverage ES6 Promises / async functions, we introduced $async, that wraps async functions with $q.
  • most of our AngularJS services were relying on the EndpointProvider.endpointId() call in the $resource() definitions to retrieve the environmentId to use to build the API URLs
    React/axios services don't have access to the EndpointProvider and all the functions have the EnvironmentId as their first parameter.

To avoid creating noise by adding the environmentId to all AngularJS services functions signatures (thus changing all the places where the functions are called), and support the fact that axios/react services don't have a reference to EndpointProvider, AngularToReact now has 2 functions:

  • useAxios, which wraps the async axios functions with an $async call to keep them in the AngularJS digest cycle (triggers an UI repaint when $q resolves)
  • injectEnvironmentId (previously useAxios), which injects the EnvironmentId as first param using EndpointProvider.

Illustration
Previously

// the original AngularJS signature doesn't accept an environmentId
// we need to maintain this behaviour
service.volume = function (id) {
  var deferred = $q.defer(); // $q automatically triggers a UI sync when it resolves/rejects
  // Volume is the $resource definition leveraging EndpointProvider
  // to generate the request URL /api/endpoints/{environmentId}/volumes/{id}
  Volume.get({ id: id })
    .$promise.then(function success(data) {
      var volume = new VolumeViewModel(data);
      deferred.resolve(volume);
    })
    .catch(function error(err) {
      deferred.reject({ msg: 'Unable to retrieve volume details', err: err });
    });
  return deferred.promise;
};
---
// usage
VolumeService.volume(volumeId).then(...)

Now

const { useAxios, injectEnvironmentId } = AngularToReact;
return {
  volume: useAxios(injectEnvironmentId(volumeAngularJS)),
};

/**
 * this function is async (1) and receives an environmentId as first parameter (2)
 * (1): the async nature of the function is handled by useAxios to keep AngularJS aware of its execution
 * (2): the environmentId param is injected by injectEnvironmentId
 * 
 * @param {EnvironmentId} environmentId - injected by AngularToReact
 * @param {string} id - provided by the caller
 */
async function volumeAngularJS(environmentId, id) {
  // getVolume is an Axios function and needs an environmentId
  const data = await getVolume(environmentId, id);
  return new VolumeViewModel(data);
}
---
// axios implementation of the previous $resource() definition
export async function getVolume(
  environmentId: EnvironmentId,
  name: Volume['Name']
) {
  try {
    const { data } = await axios.get(
      buildDockerProxyUrl(environmentId, 'volumes', name)
    );
    return data;
  } catch (e) {
    throw parseAxiosError(e, 'Unable to retrieve volume details');
  }
}

---
// usage didn't change on the caller's side
VolumeService.volume(volumeId).then(...)

@xAt0mZ xAt0mZ force-pushed the feat/EE-6918/CE/develop/limit-docker-api-version-used-frontend branch from bb8af42 to a382525 Compare May 30, 2024 15:21
@xAt0mZ xAt0mZ force-pushed the feat/EE-6918/CE/develop/limit-docker-api-version-used-frontend branch from a382525 to 59536ad Compare June 10, 2024 16:13
@xAt0mZ xAt0mZ merged commit 6a8e673 into develop Jun 10, 2024
18 checks passed
@xAt0mZ xAt0mZ deleted the feat/EE-6918/CE/develop/limit-docker-api-version-used-frontend branch June 10, 2024 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants