-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
ci-credentials: update GSM secrets with updated configuration values #20076
Merged
alafanechere
merged 13 commits into
master
from
augustin/ci-credentials/write-updated-secrets-to-gcs
Dec 7, 2022
+530
−304
Merged
Changes from 9 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
f5d10d5
wip
alafanechere 03bb578
cleaner cli
alafanechere 69f2d14
add doc strings
alafanechere bc17f50
update readme
alafanechere bfee38e
bump version
alafanechere 02b812d
update test and publish workflows
alafanechere e2fa85d
test secret manager
alafanechere c34d987
update setup.py
alafanechere 1e75110
test secret manager
alafanechere 7460b6e
fix typo
alafanechere d3b9559
better returns
alafanechere ed8c428
better returns
alafanechere 1656af2
better returns
alafanechere File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# from .main import main | ||
from .secrets_loader import SecretsLoader | ||
# | ||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved. | ||
# | ||
from .secrets_manager import SecretsManager | ||
|
||
__all__ = ( | ||
"SecretsLoader", | ||
) | ||
__all__ = ("SecretsManager",) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,62 @@ | ||
# | ||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved. | ||
# | ||
import json | ||
import os | ||
import sys | ||
from json.decoder import JSONDecodeError | ||
|
||
import click | ||
from ci_common_utils import Logger | ||
from . import SecretsLoader | ||
|
||
from . import SecretsManager | ||
|
||
logger = Logger() | ||
|
||
ENV_GCP_GSM_CREDENTIALS = "GCP_GSM_CREDENTIALS" | ||
|
||
|
||
# credentials of GSM and GitHub secrets should be shared via shell environment | ||
|
||
def main() -> int: | ||
if len(sys.argv) != 2: | ||
return logger.error("uses one script argument only: <unique connector name>") | ||
|
||
@click.group() | ||
@click.argument("connector_name") | ||
@click.option("--gcp-gsm-credentials", envvar="GCP_GSM_CREDENTIALS") | ||
@click.pass_context | ||
def ci_credentials(ctx, connector_name: str, gcp_gsm_credentials): | ||
ctx.ensure_object(dict) | ||
ctx.obj["connector_name"] = connector_name | ||
# parse unique connector name, because it can have the common prefix "connectors/<unique connector name>" | ||
connector_name = sys.argv[1].split("/")[-1] | ||
connector_name = connector_name.split("/")[-1] | ||
if connector_name == "all": | ||
# if needed to load all secrets | ||
connector_name = None | ||
|
||
# parse GCP_GSM_CREDENTIALS | ||
try: | ||
gsm_credentials = json.loads(os.getenv(ENV_GCP_GSM_CREDENTIALS) or "{}") | ||
gsm_credentials = json.loads(gcp_gsm_credentials) if gcp_gsm_credentials else {} | ||
except JSONDecodeError as e: | ||
return logger.error(f"incorrect GCP_GSM_CREDENTIALS value, error: {e}") | ||
|
||
if not gsm_credentials: | ||
return logger.error("GCP_GSM_CREDENTIALS shouldn't be empty!") | ||
|
||
loader = SecretsLoader( | ||
secret_manager = SecretsManager( | ||
connector_name=connector_name, | ||
gsm_credentials=gsm_credentials, | ||
) | ||
return loader.write_to_storage(loader.read_from_gsm()) | ||
ctx.obj["secret_manager"] = secret_manager | ||
ctx.obj["connector_secrets"] = secret_manager.read_from_gsm() | ||
|
||
|
||
@ci_credentials.command(help="Download GSM secrets locally to the connector's secrets directory.") | ||
@click.pass_context | ||
def write_to_storage(ctx): | ||
return ctx.obj["secret_manager"].write_to_storage(ctx.obj["connector_secrets"]) | ||
|
||
|
||
@ci_credentials.command(help="Update GSM secrets according to the content of the secrets/updated_configurations directory.") | ||
@click.pass_context | ||
def update_secrets(ctx): | ||
return ctx.obj["secret_manager"].update_secrets(ctx.obj["connector_secrets"]) | ||
|
||
|
||
if __name__ == '__main__': | ||
sys.exit(main()) | ||
if __name__ == "__main__": | ||
sys.exit(ci_credentials(obj={})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# | ||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved. | ||
# | ||
|
||
from __future__ import ( # Used to evaluate type hints at runtime, a NameError: name 'ConfigObserver' is not defined is thrown otherwise | ||
alafanechere marked this conversation as resolved.
Show resolved
Hide resolved
|
||
annotations, | ||
) | ||
|
||
from dataclasses import dataclass | ||
|
||
DEFAULT_SECRET_FILE = "config" | ||
|
||
|
||
@dataclass | ||
class Secret: | ||
connector_name: str | ||
configuration_file_name: str | ||
value: str | ||
|
||
@property | ||
def name(self) -> str: | ||
return self.generate_secret_name(self.connector_name, self.configuration_file_name) | ||
|
||
@staticmethod | ||
def generate_secret_name(connector_name: str, configuration_file_name: str) -> str: | ||
""" | ||
Generates an unique GSM secret name. | ||
Format of secret name: SECRET_<CAPITAL_CONNECTOR_NAME>_<OPTIONAL_UNIQUE_FILENAME_PART>__CREDS | ||
Examples: | ||
1. connector_name: source-linnworks, filename: dsdssds_a-b---_---_config.json | ||
=> SECRET_SOURCE-LINNWORKS_DSDSSDS_A-B__CREDS | ||
2. connector_name: source-s3, filename: config.json | ||
=> SECRET_SOURCE-LINNWORKS__CREDS | ||
""" | ||
name_parts = ["secret", connector_name] | ||
filename_wo_ext = configuration_file_name.replace(".json", "") | ||
if filename_wo_ext != DEFAULT_SECRET_FILE: | ||
name_parts.append(filename_wo_ext.replace(DEFAULT_SECRET_FILE, "").strip("_-")) | ||
name_parts.append("_creds") | ||
return "_".join(name_parts).upper() | ||
|
||
@property | ||
def directory(self) -> str: | ||
if self.connector_name == "base-normalization": | ||
return f"airbyte-integrations/bases/{self.connector_name}/secrets" | ||
else: | ||
return f"airbyte-integrations/connectors/{self.connector_name}/secrets" | ||
|
||
|
||
@dataclass | ||
class RemoteSecret(Secret): | ||
enabled_version: str | ||
|
||
@classmethod | ||
def from_secret(cls, secret: Secret, enabled_version: str) -> RemoteSecret: | ||
return RemoteSecret(secret.connector_name, secret.configuration_file_name, secret.value, enabled_version) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirming that GCP_GSM_CREDENTIALS has read and write access?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not allowed to check in GitHub which service account is used in this env var in our actions. But according to the service account I see in our IAM console, I'm pretty sure the currently used SA has sufficient permissions to perform all the operations that this CLI can do: read secret values, add a secret version, disable a secret version.