Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
add export/import doc
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-stokes committed Apr 6, 2022
1 parent a2f9c3c commit 00fcbc5
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 15 deletions.
Binary file added docs/user-guide/assets/export-complete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user-guide/assets/import-complete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user-guide/assets/import-copy-ls.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions docs/user-guide/sharing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Sharing Environment

OGC provides a way to share an environment with another user, they are facilitated through the `ogc export-env` and `ogc import-env` commands.
This document will walk through how to accomplish this plus any caveats to be aware of.

## Exporting

First, we need to export the current environment. This will dump the database of node information,
the environment variables used in the deployment, and will include the public ssh key of the shared user on all nodes.

The person you are sharing with should provide you with a passwordless public ssh key. This can either be the
contents of the public ssh key or a GitHub username that has public ssh keys associated with their profile.

``` sh
$ ogc export-env

How would you like to import the users public ssh key [github/manual] (github):
Please enter your Github username: adam-stokes
```

Once the export is complete it will print out the results including some instructions on what to do next

![Export Complete](./assets/export-complete.png)

## Importing

Once the user has both the database `ogc-dump.sql` and the environment `ogc-env.json` they will need to import that on their machine.

!!! caution
If the user already has `ogc` installed and a deployment created, they may want to keep that information intact. To avoid overwriting
the users database during import make sure to prefix the command with `POSTGRES_DB`:

``` sh
$ POSTGRES_DB="ogcopydb" ogc import-env
```

Also, the import command will automatically write to files `ogc.yml` and `.env`. If those files already exist in the directory where the import command is run
then you will want to do one of two things:

* Create a backup of those files
* Run `ogc import-env` from a different directory, perhaps creating a temporary directory for working with the shared environment.

To do the import run the following:

``` sh
$ POSTGRES_DB="ogcopydb" ogc import-env --env-file ../ogc-env.json \
--db-file ../ogc-dump.sql \
--private-ssh-key ~/.ssh/id_rsa \
--public-ssh-key ~/.ssh/id_rsa.pub
```

The `private-ssh-key` and `public-ssh-key` should be the locations of the keys associated with the one shared during export.

![Import complete](./assets/import-complete.png)

Once import is complete, you can access this environment:

``` sh
$ POSTGRES_DB="ogccopydb" ogc ls
```

![Import copy](./assets/import-copy-ls.png)

!!! Warning
The cloud credentials are not copied over, you will need to setup your credentials again in the newly created `.env`. You will need to make sure that the correct project/region is set and accessible by your cloud account.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ nav:
- 'Scripting': 'user-guide/scripting.md'
- 'Providers': 'user-guide/providers.md'
- 'Upgrading': 'user-guide/upgrading.md'
- 'Sharing': 'user-guide/sharing.md'
- 'Cookbook':
- 'Access node info': 'user-guide/cookbook/template-access-node-info.md'
- 'Developer Guide':
Expand Down
2 changes: 1 addition & 1 deletion ogc/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def exec_async(name: str, tag: str, cmd: str) -> list[bool]:
rows = session.query(db.Node).all()
count = len(rows)

log.info(f"Executing '{cmd}' across [green]{count}[/] nodes.")
log.info(f"Executing '{cmd}' across {count} nodes.")
with ProcessPoolExecutor(max_workers=MAX_WORKERS) as executor:
func = partial(exec, cmd=cmd)
results = executor.map(
Expand Down
45 changes: 32 additions & 13 deletions ogc/commands/share.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from rich.padding import Padding
from rich.prompt import Prompt

from ogc import actions, db, state
from ogc import actions, db, enums, state
from ogc.log import Logger as log
from ogc.spec import SpecLoader

Expand Down Expand Up @@ -40,12 +40,7 @@
default="ogc-env.json",
help="Filename of where to store the OGC environment to be shared",
)
@click.option(
"--public-ssh-key",
required=False,
help="The public ssh key contents from the shared user",
)
def export_env(spec, db_file, env_file, public_ssh_key):
def export_env(spec, db_file, env_file):
"""Exports the deployment to be shared with other users
This exports the current database and imports the public ssh key of the
Expand All @@ -59,13 +54,31 @@ def export_env(spec, db_file, env_file, public_ssh_key):
sys.exit(1)

# begin setup
if not public_ssh_key:
ssh_key_type = Prompt.ask(
"How would you like to import the users public ssh key",
choices=["github", "manual"],
default="github",
)

cmd = None
if ssh_key_type.lower() == "manual":
public_ssh_key = Prompt.ask(
"Paste the public ssh key of the user you are sharing with"
)
cmd = f"echo '{public_ssh_key}' >> ~/.ssh/authorized_keys"
elif ssh_key_type.lower() == "github":
public_ssh_key = Prompt.ask("Please enter your Github username")
cmd = (
f"wget -O get-pip.py https://bootstrap.pypa.io/get-pip.py && "
"sudo python3 get-pip.py && "
"sudo pip install ssh-import-id && "
f"ssh-import-id gh:{public_ssh_key}"
)
else:
log.error("Could not import a public ssh key")
sys.exit(1)

log.info("Importing public key to all nodes")
cmd = f"echo '{public_ssh_key}' >> ~/.ssh/authorized_keys"
results = actions.exec_async(None, None, cmd)
passed = all(result == True for result in results)
if passed:
Expand All @@ -75,7 +88,6 @@ def export_env(spec, db_file, env_file, public_ssh_key):

log.info("Exporting database")
sh.pg_dump(
"-Fc",
"-h",
db.DB_HOST,
"-p",
Expand All @@ -88,7 +100,14 @@ def export_env(spec, db_file, env_file, public_ssh_key):
)

specs = SpecLoader.load(list(spec))
ogc_env_out = {"env": {**dotenv_values(".env")}, "spec": {**specs.as_dict()}}
ogc_env_out = {
"env": {
k: v
for k, v in dotenv_values(".env").items()
if not any(k.startswith(s) for s in enums.SUPPORTED_PROVIDERS)
},
"spec": {**specs.as_dict()},
}
Path(env_file).write_text(json.dumps(ogc_env_out))

console = Console()
Expand Down Expand Up @@ -180,12 +199,12 @@ def import_env(db_file, env_file, private_ssh_key, public_ssh_key):
env_file_out = Path(".env")
with open(env_file_out, "w") as env_f:
for k, v in env_data["env"].items():
env_f.write(f"{k.upper()}={v}")
env_f.write(f"{k.upper()}={v}\n")

spec_file_out = Path("ogc.yml")

with open(spec_file_out, "w") as spec_f:
spec_f.write(yaml.dumps(env_data["spec"]))
spec_f.write(yaml.dump(env_data["spec"]))

private_ssh_key = Path(private_ssh_key)
public_ssh_key = Path(public_ssh_key)
Expand Down
2 changes: 2 additions & 0 deletions ogc/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
PID_FILE = "ogc-server.pid"
LOCAL_ARTIFACT_PATH = "artifacts"

SUPPORTED_PROVIDERS = ["AWS", "GOOGLE"]


class SpecCore:
NAME = "name"
Expand Down
2 changes: 1 addition & 1 deletion ogc/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def __repr__(self):
def as_dict(self):
return {
"name": self.name,
"layouts": [layout.as_dict() for layout in self.layouts],
"layouts": {layout.name: layout.as_dict() for layout in self.layouts},
}

def _sighandler(self, sig, frame):
Expand Down

0 comments on commit 00fcbc5

Please sign in to comment.