diff --git a/.github/workflows/distribute.yaml b/.github/workflows/distribute.yaml index de31a12..6639efd 100644 --- a/.github/workflows/distribute.yaml +++ b/.github/workflows/distribute.yaml @@ -1,47 +1,21 @@ --- name: Deploy Collection +# Trigger the workflow however you prefer on: - push: - tags: - - "*.*.*" + release: + types: + - published jobs: - release-galaxy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Build and Deploy Collection - uses: artis3n/ansible_galaxy_collection@v2 - with: - api_key: "${{ secrets.GALAXY_API_KEY }}" - galaxy_version: "${{ github.ref_name }}" - - release-docker: - needs: release-galaxy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: 🔧 Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: 🔧 Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: 🐋 Login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - build-args: VERSION=${{ github.ref_name }} - context: docker - push: true - platforms: linux/amd64,linux/arm64 - tags: | - infisical/ansible-collection:latest - infisical/ansible-collection:${{ github.ref_name }} + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Get the version name from the tags + run: echo "RELEASE_VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV + - name: Build and Deploy Collection + uses: artis3n/ansible_galaxy_collection@v2 + with: + api_key: "${{ secrets.GALAXY_API_KEY }}" + galaxy_version: "${{ env.RELEASE_VERSION }}" diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2d2b4a1..0000000 --- a/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.venv/**/* -ansible.cfg -inventory -test.yml -__pycache__ -infisical-vault-1.0.0.tar.gz diff --git a/README.md b/README.md index aec7583..0a0520d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Infisical Collection This Ansible Infisical collection includes a variety of Ansible content to help automate the management of Infisical services. This collection is maintained by the Infisical team. -[View full documentation](https://galaxy.ansible.com/ui/repo/published/infisical/vault/) - ## Ansible version compatibility Tested with the Ansible Core >= 2.12.0 versions, and the current development version of Ansible. Ansible Core versions prior to 2.12.0 have not been tested. @@ -17,12 +15,12 @@ Requires Python 3.7 or greater. You can install the Infisical collection with the Ansible Galaxy CLI: - ansible-galaxy collection install infisical.vault + ansible-galaxy collection install maidul98.infisical_vault The python module dependencies are not installed by `ansible-galaxy`. They can be manually installed using pip: - pip install infisical-python + pip install infisical ## Using this collection @@ -31,10 +29,10 @@ You can either call modules by their Fully Qualified Collection Name (FQCN), suc ```yaml --- vars: - read_all_secrets_within_scope: "{{ lookup('infisical.vault.read_secrets', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}" + read_all_secrets_within_scope: "{{ lookup('infisical.vault.read_secrets', token='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}" # [{ "key": "HOST", "value": "google.com" }, { "key": "SMTP", "value": "gmail.smtp.edu" }] - read_secret_by_name_within_scope: "{{ lookup('infisical.vault.read_secrets', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', secret_name='HOST', url='https://spotify.infisical.com') }}" + read_secret_by_name_within_scope: "{{ lookup('infisical.vault.read_secrets', token='<>', path='/', env_slug='dev', name='HOST', url='https://spotify.infisical.com') }}" # [{ "key": "HOST", "value": "google.com" }] ``` diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 2b81984..0000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM python:3.11-slim - -ENV PYTHONUNBUFFERED=1 -ENV ANSIBLE_HOST_KEY_CHECKING=false -ENV ANSIBLE_STDOUT_CALLBACK=yaml -ENV ANSIBLE_CALLBACKS_ENABLED=profile_tasks - -ARG VERSION - -RUN apt-get update && apt-get install -y \ - git \ - openssh-client \ - sshpass \ - && rm -rf /var/lib/apt/lists/* - -RUN pip install --no-cache-dir ansible infisicalsdk - -RUN ansible-galaxy collection install infisical.vault==${VERSION} - -WORKDIR /ansible - -RUN mkdir -p /root/.ansible - -# Set default command -CMD ["/bin/bash"] \ No newline at end of file diff --git a/galaxy.yml b/galaxy.yml index f912dc9..b7a6e2d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -2,7 +2,7 @@ # The namespace of the collection. This can be a company/brand/organization or product namespace under which all # content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with # underscores or numbers and cannot contain consecutive underscores -namespace: infisical +namespace: infisical_inc # The name of the collection. Has the same character restrictions as 'namespace' name: vault @@ -62,7 +62,7 @@ issues: https://github.com/Infisical/ansible-collection/issues # artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This # uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', # and '.git' are always filtered. Mutually exclusive with 'manifest' -build_ignore: ["/docker/*"] +build_ignore: [] # A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a # list of MANIFEST.in style # L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key diff --git a/plugins/lookup/read_secrets.py b/plugins/lookup/read_secrets.py index e843530..3e30077 100644 --- a/plugins/lookup/read_secrets.py +++ b/plugins/lookup/read_secrets.py @@ -3,9 +3,9 @@ from ansible.plugins.lookup import LookupBase HAS_INFISICAL = False try: - from infisical_sdk import InfisicalSDKClient + from infisical import InfisicalClient HAS_INFISICAL = True -except ImportError as e: +except ImportError: HAS_INFISICAL = False DOCUMENTATION = r""" @@ -19,17 +19,10 @@ description: - Secrets can be located either by their name for individual secret loopups or by environment/folder path to return all secrets within the given scope. options: - universal_auth_client_id: - description: The Machine Identity Client ID used to authenticate + token: + description: The Infisical token used to authenticate env: - - name: UNIVERSAL_AUTH_MACHINE_IDENTITY_CLIENT_ID - required: True - type: string - version_added: 1.0.0 - universal_auth_client_secret: - description: The Machine Identity Client Secret used to authenticate - env: - - name: UNIVERSAL_AUTH_MACHINE_IDENTITY_CLIENT_SECRET + - name: INFISICAL_TOKEN required: True type: string version_added: 1.0.0 @@ -51,11 +44,6 @@ options: required: True type: string version_added: 1.0.0 - project_id: - description: "The ID of the project where the secrets are stored" - required: True - type: string - version_added: 1.0.0 secret_name: description: The name of the secret that should be fetched. The name should be exactly as it appears in Infisical required: False @@ -65,81 +53,51 @@ options: EXAMPLES = r""" vars: - read_all_secrets_within_scope: "{{ lookup('infisical_vault', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}" + read_all_secrets_within_scope: "{{ lookup('infisical_vault', token='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}" # [{ "key": "HOST", "value": "google.com" }, { "key": "SMTP", "value": "gmail.smtp.edu" }] - read_secret_by_name_within_scope: "{{ lookup('infisical_vault', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', secret_name='HOST', url='https://spotify.infisical.com') }}" + read_secret_by_name_within_scope: "{{ lookup('infisical_vault', token='<>', path='/', env_slug='dev', name='HOST', url='https://spotify.infisical.com') }}" # [{ "key": "HOST", "value": "google.com" }] """ - class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): self.set_options(var_options=variables, direct=kwargs) - if not HAS_INFISICAL: - raise AnsibleError("Please pip install infisicalsdk to use the infisical_vault lookup module.") - machine_identity_client_id = self.get_option("universal_auth_client_id") - machine_identity_client_secret = self.get_option("universal_auth_client_secret") + if not HAS_INFISICAL: + raise AnsibleError("Please pip install infisical to use the infisical_vault lookup module.") + + infisical_token = self.get_option("token") url = self.get_option("url") - # Check if the required environment variables are set - if not machine_identity_client_id or not machine_identity_client_secret: - raise AnsibleError("Please provide the universal_auth_client_id and universal_auth_client_secret") + if not infisical_token: + raise AnsibleError("Infisical token is required") - client = InfisicalSDKClient(host=url) - - client.auth.universal_auth.login( - machine_identity_client_id, - machine_identity_client_secret - ) + # Initialize the Infisical client + client = InfisicalClient(token=infisical_token, site_url=url) secretName = kwargs.get('secret_name') envSlug = kwargs.get('env_slug') path = kwargs.get('path') - project_id = kwargs.get('project_id') if secretName: - return self.get_single_secret( - client, - project_id, - secretName, - envSlug, - path - ) + return self.get_single_secret(client, secretName, envSlug, path) else: - return self.get_all_secrets(client, project_id, envSlug, path) + return self.get_all_secrets(client, envSlug, path) - def get_single_secret( - self, - client, - project_id, - secret_name, - environment, - path - ): + def get_single_secret(self, client, secret_name, environment, path): try: - secret = client.secrets.get_secret_by_name( - secret_name=secret_name, - project_id=project_id, - environment_slug=environment, - secret_path=path - ) - - return [{"value": secret.secretValue, "key": secret.secretKey}] + print(secret_name, environment, path) + secret = client.get_secret(secret_name=secret_name, environment=environment, path=path) + return [{"value": s.secret_value, "key": s.secret_name}] except Exception as e: print(e) - raise AnsibleError(f"Error fetching single secret {e}") + raise AnsibleError(f"Error fetching all secrets {e}") - def get_all_secrets(self, client, project_id, environment="dev", path="/"): + def get_all_secrets(self, client, environment="dev", path="/"): try: - secrets = client.secrets.list_secrets( - project_id=project_id, - environment_slug=environment, - secret_path=path - ) - - return [{"value": s.secretValue, "key": s.secretKey} for s in secrets.secrets] + secrets = client.get_all_secrets(environment=environment, path=path) + return [{"value": s.secret_value, "key": s.secret_name} for s in secrets] except Exception as e: raise AnsibleError(f"Error fetching all secrets {e}")