+ await self._connector.disconnect()
+
+ async def add_credential(self, name=None, credential=None, cloud=None,
+ owner=None, force=False):
+ """Add or update a credential to the controller.
+
+ :param str name: Name of new credential. If None, the default
+ local credential is used. Name must be provided if a credential
+ is given.
+ :param CloudCredential credential: Credential to add. If not given,
+ it will attempt to read from local data, if available.
+ :param str cloud: Name of cloud to associate the credential with.
+ Defaults to the same cloud as the controller.
+ :param str owner: Username that will own the credential. Defaults to
+ the current user.
+ :param bool force: Force indicates whether the update should be forced.
+ It's only supported for facade v3 or later.
+ Defaults to false.
+ :returns: Name of credential that was uploaded.
+ """
+ if not cloud:
+ cloud = await self.get_cloud()
+
+ if not owner:
+ owner = self.connection().info['user-info']['identity']
+
+ if credential and not name:
+ raise errors.JujuError('Name must be provided for credential')
+
+ if not credential:
+ name, credential = self._connector.jujudata.load_credential(cloud,
+ name)
+ if credential is None:
+ raise errors.JujuError(
+ 'Unable to find credential: {}'.format(name))
+
+ if credential.auth_type == 'jsonfile' and 'file' in credential.attrs:
+ # file creds have to be loaded before being sent to the controller
+ try:
+ # it might already be JSON
+ json.loads(credential.attrs['file'])
+ except json.JSONDecodeError:
+ # not valid JSON, so maybe it's a file
+ cred_path = Path(credential.attrs['file'])
+ if cred_path.exists():
+ # make a copy
+ cred_json = credential.to_json()
+ credential = client.CloudCredential.from_json(cred_json)
+ # inline the cred
+ credential.attrs['file'] = cred_path.read_text()
+
+ log.debug('Uploading credential %s', name)
+ cloud_facade = client.CloudFacade.from_connection(self.connection())
+ tagged_credentials = [
+ client.UpdateCloudCredential(
+ tag=tag.credential(cloud, tag.untag('user-', owner), name),
+ credential=credential,
+ )]
+ if cloud_facade.version >= 3:
+ # UpdateCredentials was renamed to UpdateCredentialsCheckModels
+ # in facade version 3.
+ await cloud_facade.UpdateCredentialsCheckModels(
+ credentials=tagged_credentials, force=force,
+ )
+ else:
+ await cloud_facade.UpdateCredentials(tagged_credentials)
+ return name