PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/utils/vault/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/utils/vault/api.py |
import salt.utils.json import salt.utils.vault.leases as vleases from salt.utils.vault.exceptions import VaultInvocationError, VaultNotFoundError class AppRoleApi: """ Wraps the Vault AppRole API. .. note:: All durations can be specified either as an integer time in seconds or a time string like ``1h``. https://developer.hashicorp.com/vault/api-docs/auth/approle """ def __init__(self, client): self.client = client def list_approles(self, mount="approle"): """ List all AppRoles present on the specified mount. mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ endpoint = f"auth/{mount}/role" return self.client.list(endpoint)["data"]["keys"] def read_approle(self, name, mount="approle"): """ Read the properties of an existing AppRole. Raises VaultNotFound if the AppRole does not exist on the mount. name Name of the AppRole to read the properties of. mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ endpoint = f"auth/{mount}/role/{name}" return self.client.get(endpoint)["data"] def write_approle( self, name, bind_secret_id=None, secret_id_bound_cidrs=None, secret_id_num_uses=None, secret_id_ttl=None, local_secret_ids=None, token_ttl=None, token_max_ttl=None, token_policies=None, token_bound_cidrs=None, token_explicit_max_ttl=None, token_no_default_policy=None, token_num_uses=None, token_period=None, token_type=None, mount="approle", ): """ Create or update an AppRole. name Name of the AppRole to read the properties of. bind_secret_id Require a SecretID when authenticating with this AppRole. Defaults to true. secret_id_bound_cidrs List of blocks of IP addresses in CIDR notation that can perform the login operation. secret_id_num_uses Number of times a generated SecretID can be used to authenticate with this AppRole by default. ``0`` means unlimited. secret_id_ttl Duration after which a generated SecretID for this AppRole expires by default. local_secret_ids If set, the secret IDs generated using this role will be cluster-local. This can only be set during role creation and once set, it can't be reset later. Defaults to false. token_ttl The incremental lifetime for tokens generated by authenticating with this AppRole. This value will be referenced at renewal time. token_max_ttl The maximum lifetime for tokens generated by authenticating with this AppRole. This value will be referenced at renewal time. token_policies List of token policies to encode onto generated tokens. This list may be supplemented by user/group/other values. token_bound_cidrs List of blocks of IP addresses in CIDR notation that can perform the login operation. The resulting token will be tied to these blocks as well. token_explicit_max_ttl Place a hard cap on the maximum lifetime of tokens issued by authenticating with this AppRole. token_no_default_policy Do not add the ``default`` policy to tokens generated by authenticating with this AppRole. Defaults to false. token_num_uses Number of times a token generated by authenticating with this AppRole may be used to issue requests. ``0`` means unlimited. token_period The maximum allowed period value when a periodic token is requested from this role. token_type The type of token that should be generated (``service``, ``batch`` or ``default``). mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ endpoint = f"auth/{mount}/role/{name}" payload = _filter_none( { "bind_secret_id": bind_secret_id, "secret_id_bound_cidrs": secret_id_bound_cidrs, "secret_id_num_uses": secret_id_num_uses, "secret_id_ttl": secret_id_ttl, "local_secret_ids": local_secret_ids, "token_ttl": token_ttl, "token_max_ttl": token_max_ttl, "token_policies": token_policies, "token_bound_cidrs": token_bound_cidrs, "token_explicit_max_ttl": token_explicit_max_ttl, "token_no_default_policy": token_no_default_policy, "token_num_uses": token_num_uses, "token_period": token_period, "token_type": token_type, } ) return self.client.post(endpoint, payload=payload) def delete_approle(self, name, mount="approle"): """ Delete an existing AppRole. Raises VaultNotFound if the AppRole does not exist on the mount. name Name of the AppRole to delete. mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ endpoint = f"auth/{mount}/role/{name}" return self.client.delete(endpoint) def read_role_id(self, name, wrap=False, mount="approle"): """ Read the associated RoleID of an existing AppRole. Raises VaultNotFound if the AppRole does not exist on the mount. name Name of the AppRole. wrap If set, specifies the duration the resulting wrapping token should be valid for. This token can be used once to access the query result. Defaults to false (=> returns the RoleID as a string). mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ endpoint = f"auth/{mount}/role/{name}/role-id" role_id = self.client.get(endpoint, wrap=wrap) if wrap: return role_id return role_id["data"]["role_id"] def generate_secret_id( self, name, metadata=None, cidr_list=None, token_bound_cidrs=None, num_uses=None, ttl=None, wrap=False, mount="approle", ): """ Generate a SecretID for an existing AppRole. Raises VaultNotFound if the AppRole does not exist on the mount. name Name of the AppRole. metadata Mapping of string keys to string values that specifies metadata to be set on the token generated by authenticating with this specific SecretID. It will be logged to audit logs in plaintext. cidr_list List of blocks of IP addresses in CIDR notation that can perform the login operation with this specific SecretID. If ``secret_id_bound_cidrs`` is set on the AppRole, this list must be a subset of the ones specified there. token_bound_cidrs List of blocks of IP addresses in CIDR notation that can perform the login operation. The resulting token will be tied to these blocks as well. If ``token_bound_cidrs`` is set on the AppRole, this list must be a subset of the ones specified there. num_uses Number of times this specific SecretID can be used to authenticate by default. ``0`` means unlimited. Must be equal to or lower than ``secret_id_num_uses`` set on the AppRole. ttl Duration after which this SecretID should expire. Must be equal to or lower than ``secret_id_ttl`` set on the AppRole. wrap If set, specifies the duration the resulting wrapping token should be valid for. This token can be used once to access the query result. Defaults to false (=> returns the SecretID as a string). mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ endpoint = f"auth/{mount}/role/{name}/secret-id" if metadata is not None: metadata = salt.utils.json.dumps(metadata) payload = _filter_none( { "metadata": metadata, "cidr_list": cidr_list, "token_bound_cidrs": token_bound_cidrs, "num_uses": num_uses, "ttl": ttl, } ) response = self.client.post(endpoint, payload=payload, wrap=wrap) if wrap: return response # Sadly, secret_id_num_uses is not part of the information returned, but # it can be read with `read_secret_id` using the accessor. return vleases.VaultSecretId(**response["data"]) def read_secret_id(self, name, secret_id=None, accessor=None, mount="approle"): """ Read properties of an existing SecretID. Raises VaultNotFound if the AppRole and/or SecretID does not exist on the mount. name Name of the AppRole the SecretID belongs to. secret_id The SecretID to look up. Specify either this or ``accessor``. accessor The accessor of the SecretID to look up. Specify either this or ``secret_id``. mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ if not secret_id and not accessor: raise VaultInvocationError( "Need either secret_id or accessor to read secret ID." ) if secret_id: endpoint = f"auth/{mount}/role/{name}/secret-id/lookup" payload = {"secret_id": str(secret_id)} else: endpoint = f"auth/{mount}/role/{name}/secret-id-accessor/lookup" payload = {"secret_id_accessor": accessor} try: return self.client.post(endpoint, payload=payload)["data"] except TypeError: # lookup does not raise exceptions, only returns True raise VaultNotFoundError() def destroy_secret_id(self, name, secret_id=None, accessor=None, mount="approle"): """ Destroy an existing SecretID. Raises VaultNotFound if the AppRole and/or SecretID does not exist on the mount. name Name of the AppRole the SecretID belongs to. secret_id The SecretID to destroy. Specify either this or ``accessor``. accessor The accessor of the SecretID to destroy. Specify either this or ``secret_id``. mount Name of the AppRole auth backend mount. Defaults to ``approle``. """ if not secret_id and not accessor: raise VaultInvocationError( "Need either secret_id or accessor to destroy secret ID." ) if secret_id: endpoint = f"auth/{mount}/role/{name}/secret-id/destroy" payload = {"secret_id": str(secret_id)} else: endpoint = f"auth/{mount}/role/{name}/secret-id-accessor/destroy" payload = {"secret_id_accessor": accessor} return self.client.post(endpoint, payload=payload) class IdentityApi: """ Wraps the Vault ``Identity`` secret engine API. https://developer.hashicorp.com/vault/api-docs/secret/identity """ def __init__(self, client): self.client = client def list_entities(self): """ Return a list of the names of all entities known by Vault. """ endpoint = "identity/entity/name" return self.client.list(endpoint)["data"]["keys"] def read_entity(self, name): """ Read the properties of an entity by its name. Raises VaultNotFound if the entity does not exist. name Name of the entity to read the properties of. """ endpoint = f"identity/entity/name/{name}" return self.client.get(endpoint)["data"] def read_entity_by_alias(self, alias, mount): """ Lookup the properties of an entity by its alias name and mount. Raises VaultNotFound if the entity does not exist. alias The name of the entity's alias on the specified ``mount``. For AppRole backends, this is the RoleID. mount The name of the mount the given alias is associated with. For example, if the backend is mounted at ``auth/approle``, this should be ``approle``. """ endpoint = "identity/lookup/entity" payload = { "alias_name": alias, "alias_mount_accessor": self._lookup_mount_accessor(mount), } entity = self.client.post(endpoint, payload=payload) if isinstance(entity, dict): return entity["data"] raise VaultNotFoundError() def write_entity(self, name, metadata=None, policies=None, disabled=None): """ Create or update an entity by name. name The name of the entity. metadata Mapping of string keys to string values that specifies metadata to be set on the entity. This can be used to template policies. policies List of policies to be tied to the entity. These policies will be active in addition to auth method-specific policies. disabled Whether this entity should be disabled. Disabled entities' associated tokens cannot be used, but are not revoked. Defaults to false. """ endpoint = f"identity/entity/name/{name}" payload = _filter_none( { "metadata": metadata, "policies": policies, "disabled": disabled, } ) return self.client.post(endpoint, payload=payload) def delete_entity(self, name): """ Delete an entity by name. Raises VaultNotFound if the entity does not exist. name The name of the entity. """ endpoint = f"identity/entity/name/{name}" return self.client.delete(endpoint) def write_entity_alias(self, name, alias_name, mount, custom_metadata=None): """ Create/update the association between an entity and a specific alias of an auth mount. name Name of the entity to associate with the alias. alias_name Name of the alias to associate with the entity. The specifics are dependent on the type of the auth backend. For AppRoles, this is the RoleID. mount The name of the mount the given alias is associated with. For example, if the backend is mounted at ``auth/approle``, this should be ``approle``. custom_metadata A map of arbitrary string to string valued user-provided metadata meant to describe the alias. """ entity = self.read_entity(name) mount_accessor = self._lookup_mount_accessor(mount) payload = { "canonical_id": entity["id"], "mount_accessor": mount_accessor, "name": alias_name, } if custom_metadata is not None: payload["custom_metadata"] = custom_metadata for alias in entity["aliases"]: # Ensure an existing alias is updated if alias["mount_accessor"] == mount_accessor: payload["id"] = alias["id"] break return self.client.post("identity/entity-alias", payload=payload) def _lookup_mount_accessor(self, mount): endpoint = f"sys/auth/{mount}" return self.client.get(endpoint)["data"]["accessor"] def _filter_none(data): return {k: v for k, v in data.items() if v is not None}