Skip to content

Commit

Permalink
change dependencies management
Browse files Browse the repository at this point in the history
  • Loading branch information
Mayfly277 committed Oct 9, 2024
1 parent c782e2f commit 44919d8
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 47 deletions.
60 changes: 59 additions & 1 deletion docs/mkdocs/docs/installation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The goad management script is now written in :simple-python: python to permit mo

## TLDR - quick install

??? info "TLDR : ubuntu 22.04 quick install"
??? info "TLDR : :material-ubuntu: ubuntu 22.04 quick install"

```bash
# Install vbox
Expand Down Expand Up @@ -46,6 +46,64 @@ The goad management script is now written in :simple-python: python to permit mo
./goad.sh
```

## Dependencies

- Goad in :simple-python: python come with a lot of dependencies as you can see in the `requirements.yml` file on the root of the project.
- If you don't want to run the provisioning from your python venv but only from docker you can use `goad_docker.sh` script instead of `goad.sh`. This will run the ansible with the docker method instead of local or runner.

This are the python dependencies used by goad :

- Mandatory for :simple-python: goad.py:
```
rich
psutil
Jinja2
pyyaml
```

- Mandatory for :material-ansible: ansible inside goad (for provisioning method local or runner) :
```
# Ansible
ansible_runner
ansible-core==2.12.6
pywinrm
```

- Mandatory for :material-microsoft-azure: azure provider :
```
# AZURE
azure-identity
azure-mgmt-compute
azure-mgmt-network
```

- Mandatory for :simple-amazon: aws provider :
```
# AWS
boto3
```

- Mandatory for :simple-proxmox: proxmox provider:
```
# Proxmox
proxmoxer
requests
```

- You can launch goad without installing all the pip package but for that you will have to disable some dependencies with the `-d` arguments:
```
-d vmware : disable vmware provider
-d virtualbox : disable virtualbox provider
-d azure : disable azure provider
-d aws : disable azure provider
-d proxmox : disable proxmox provider
-d ludus : disable ludus provider
-d local : disable local provisioning method (if you use docker only)
-d runner : disable ansible runner provisioning method (if you use docker only)
-d remote : disable remote provisioning method
-d docker : disable docker provisioning method
```

## Installation

- Installation is in three parts :
Expand Down
27 changes: 25 additions & 2 deletions docs/mkdocs/docs/installation/linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- First you will prepare your host for an hypervisor
- Second you will prepare your python environment

## Prepare your hypervisor
## Prepare your Provider

=== ":simple-virtualbox: Virtualbox"

Expand Down Expand Up @@ -117,7 +117,7 @@
...>install
```

## Prepare your python environment
## Prepare your python environment for goad.py

- [x] To run the Goad installation/management script you will need :
- Python (version between 3.8 and 3.11) with venv module installed
Expand All @@ -136,3 +136,26 @@ sudo apt install python3.10-venv

!!! bug "Python version"
Be sure to use a python version between **python3.8** and python **3.11**. Others python versions are not supported by now due to incompatibility with the fixed version in the requirements.

## Prepare your python environment for goad.py and provisioning with docker

!!! info
With this method ansible-core will not be installed locally on your venv

- [x] be sure you have docker installed on your os for the provisioning part (ansible will be run from the container)
- [x] To run the Goad installation/management script you will need :
- Python (version >= 3.8) with venv module installed

- Install the python3-venv corresponding to your python version

```bash
sudo apt install python<version>-venv
```

- Example:

```bash
sudo apt install python3.10-venv
```

- Run goad with `./goad_docker.sh` instead of `./goad.sh` to install the dependencies without the ansible part (local and runner provisioning method will not be available)
2 changes: 1 addition & 1 deletion docs/mkdocs/docs/provisioning.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 🛠️ provisioning
# :material-ansible: provisioning

This page describe how the provisioning is done with goad.
The provisioning of the LABS is done with Ansible for all providers.
Expand Down
5 changes: 3 additions & 2 deletions goad.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import sys
import time
from goad.config import Config
from goad.lab_manager import LabManager
from goad.menu import print_menu, print_logo
from goad.labs import *
from goad.infos import *


Expand All @@ -19,6 +17,8 @@ def __init__(self, args):
config = Config()
config.merge_config(args)
# prepare lab controller to manage labs
# import lab manager after the loading of the dependencies to allow disabling some provider and provisioning method
from goad.lab_manager import LabManager
self.lab_manager = LabManager().init(config, args)

if args.task == '' or args.task is None:
Expand Down Expand Up @@ -452,6 +452,7 @@ def parse_args():
parser.add_argument("-e", "--extensions", help="extensions to use", action='append', required=False)
parser.add_argument("-a", "--ansible_only", help="run only provisioning (ansible) on instance (-i) (for task install only)", required=False)
parser.add_argument("-r", "--run_playbook", help="run only one ansible playbook on instance (-i) (for task install only)", required=False)
parser.add_argument("-d", "--disable_dependencies", help="disable_dependencies", action='append', required=False)
args = parser.parse_args()
return args

Expand Down
25 changes: 20 additions & 5 deletions goad.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
#!/usr/bin/env bash

py=python3
if [ ! -d "$HOME/.goad/.venv" ]
py=python3.8
venv="$HOME/.goad/.venv"

# Get the Python version (removes 'Python' from output)
version=$($py --version 2>&1 | awk '{print $2}')
# Convert the version to comparable format (removes the dot and treats it as an integer)
version_numeric=$(echo $version | awk -F. '{printf "%d%02d%02d\n", $1, $2, $3}')
# Check if the version is >= 3.8.0 and < 3.12.0
if [ "$version_numeric" -ge 30800 ] && [ "$version_numeric" -lt 31200 ]; then
# echo "Python version is >= 3.8.0 and < 3.12.0"
echo 'python version ok'
else
echo "Python version is outside the range 3.8.0 to 3.12.0"
exit
fi

if [ ! -d "$venv" ]
then
if $py -m venv --help > /dev/null 2>&1; then
echo "venv module is installed. continue"
Expand All @@ -13,8 +28,8 @@ then
fi
echo '[+] venv not found, start python venv creation'
mkdir ~/.goad
$py -m venv $HOME/.goad/.venv
source $HOME/.goad/.venv/bin/activate
$py -m venv $venv
source $venv/bin/activate
$py -m pip install --upgrade pip
export SETUPTOOLS_USE_DISTUTILS=stdlib
$py -m pip install -r requirements.yml
Expand All @@ -24,6 +39,6 @@ then
fi

# launch the app
source $HOME/.goad/.venv/bin/activate
source $venv/bin/activate
$py goad.py $@
deactivate
5 changes: 4 additions & 1 deletion goad/command/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
from goad.log import Log
from goad.utils import Utils

from goad.dependencies import Dependencies

class Command:

Expand Down Expand Up @@ -66,6 +66,9 @@ def check_rsync(self):
return self.is_in_path('rsync')

def check_ansible(self):
if not Dependencies.provisioner_local_enabled and not Dependencies.provisioner_runner_enabled:
Log.info('skip ansible check as no local and runner provisionner enabled')
return True
checks = [
self.is_in_path('ansible-playbook'),
self.check_ansible_galaxy('ansible.windows'),
Expand Down
23 changes: 23 additions & 0 deletions goad/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from goad.goadpath import GoadPath
from goad.utils import *
from goad.log import Log
from goad.dependencies import Dependencies


class Config:
Expand Down Expand Up @@ -83,6 +84,28 @@ def merge_config(self, args):
self.set_value('default', PROVISIONER, args.method)
if args.ip_range:
self.set_value('default', IP_RANGE, args.ip_range)
if args.disable_dependencies:
for disable_dependence in args.disable_dependencies:
if disable_dependence == 'vmware':
Dependencies.vmware_enabled = False
elif disable_dependence == 'virtualbox':
Dependencies.virtualbox_enabled = False
elif disable_dependence == 'azure':
Dependencies.azure_enabled = False
elif disable_dependence == 'aws':
Dependencies.aws_enabled = False
elif disable_dependence == 'ludus':
Dependencies.ludus_enabled = False
elif disable_dependence == 'proxmox':
Dependencies.proxmox_enabled_enabled = False
elif disable_dependence == 'local':
Dependencies.provisioner_local_enabled = False
elif disable_dependence == 'runner':
Dependencies.provisioner_runner_enabled = False
elif disable_dependence == 'remote':
Dependencies.provisioner_remote_enabled = False
elif disable_dependence == 'docker':
Dependencies.provisioner_docker_enabled = False
return self

def get_value(self, section, key, fallback=None):
Expand Down
24 changes: 14 additions & 10 deletions goad/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from goad.utils import Utils

# Can change enabled providers (useful if you don't want some dependencies)
vmware_enabled = True
virtualbox_enabled = True
azure_enabled = True
aws_enabled = True
proxmox_enabled = True
ludus_enabled = True
# Can change enabled provisioners (useful if you don't want some dependencies)
provisioner_runner_enabled = False
provisioner_docker_enabled = False if Utils.is_wsl() else True

class Dependencies:
# Can change enabled providers (useful if you don't want some dependencies)
vmware_enabled = True
virtualbox_enabled = True
azure_enabled = True
aws_enabled = True
proxmox_enabled = True
ludus_enabled = True
# Can change enabled provisioners (useful if you don't want some dependencies)
provisioner_local_enabled = True
provisioner_runner_enabled = True
provisioner_remote_enabled = True
provisioner_docker_enabled = False if Utils.is_wsl() else True
20 changes: 11 additions & 9 deletions goad/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
from goad.jumpbox import JumpBox
from goad.log import Log
from goad.exceptions import ProviderPathNotFound, JumpBoxInitFailed
from goad.provisioner.ansible.local import LocalAnsibleProvisionerCmd
from goad.provisioner.ansible.remote import RemoteAnsibleProvisioner
from goad.utils import *
from goad.dependencies import *
from goad.dependencies import Dependencies

if provisioner_runner_enabled:
if Dependencies.provisioner_local_enabled:
from goad.provisioner.ansible.local import LocalAnsibleProvisionerCmd
if Dependencies.provisioner_runner_enabled:
from goad.provisioner.ansible.runner import LocalAnsibleProvisionerEmbed
if provisioner_docker_enabled:
if Dependencies.provisioner_remote_enabled:
from goad.provisioner.ansible.remote import RemoteAnsibleProvisioner
if Dependencies.provisioner_docker_enabled:
from goad.provisioner.ansible.docker import DockerAnsibleProvisionerCmd


Expand Down Expand Up @@ -75,14 +77,14 @@ def load(self, labs, creation=False):

self.provider.set_instance_path(self.instance_provider_path)

if self.provisioner_name == PROVISIONING_LOCAL:
if self.provisioner_name == PROVISIONING_LOCAL and Dependencies.provisioner_local_enabled:
self.provisioner = LocalAnsibleProvisionerCmd(self.lab_name, self.provider)
elif self.provisioner_name == PROVISIONING_REMOTE:
elif self.provisioner_name == PROVISIONING_REMOTE and Dependencies.provisioner_remote_enabled:
self.provisioner = RemoteAnsibleProvisioner(self.lab_name, self.provider)
self.provisioner.jumpbox = JumpBox(self, creation)
elif self.provisioner_name == PROVISIONING_RUNNER and provisioner_runner_enabled:
elif self.provisioner_name == PROVISIONING_RUNNER and Dependencies.provisioner_runner_enabled:
self.provisioner = LocalAnsibleProvisionerEmbed(self.lab_name, self.provider)
elif self.provisioner_name == PROVISIONING_DOCKER and provisioner_docker_enabled:
elif self.provisioner_name == PROVISIONING_DOCKER and Dependencies.provisioner_docker_enabled:
self.provisioner = DockerAnsibleProvisionerCmd(self.lab_name, self.provider)

if self.provisioner is None:
Expand Down
26 changes: 13 additions & 13 deletions goad/labs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
from goad.goadpath import GoadPath
from goad.log import Log
from goad.exceptions import *
from goad.dependencies import *
from goad.dependencies import Dependencies

if vmware_enabled:
if Dependencies.vmware_enabled:
from goad.provider.vagrant.vmware import VmwareProvider
if virtualbox_enabled:
if Dependencies.virtualbox_enabled:
from goad.provider.vagrant.virtualbox import VirtualboxProvider
if azure_enabled:
if Dependencies.azure_enabled:
from goad.provider.terraform.azure import AzureProvider
if aws_enabled:
if Dependencies.aws_enabled:
from goad.provider.terraform.aws import AwsProvider
if proxmox_enabled:
if Dependencies.proxmox_enabled:
from goad.provider.terraform.proxmox import ProxmoxProvider
if ludus_enabled:
if Dependencies.ludus_enabled:
from goad.provider.ludus.ludus import LudusProvider


Expand Down Expand Up @@ -59,17 +59,17 @@ def __init__(self, lab_name, config):
def _load_providers(self, lab_name, config):
for provider_name in Utils.list_folders(GoadPath.get_lab_providers_path(lab_name)):
provider = None
if provider_name == VIRTUALBOX and virtualbox_enabled:
if provider_name == VIRTUALBOX and Dependencies.virtualbox_enabled:
provider = VirtualboxProvider(lab_name)
elif provider_name == VMWARE and vmware_enabled:
elif provider_name == VMWARE and Dependencies.vmware_enabled:
provider = VmwareProvider(lab_name)
elif provider_name == PROXMOX and proxmox_enabled:
elif provider_name == PROXMOX and Dependencies.proxmox_enabled:
provider = ProxmoxProvider(lab_name, config)
elif provider_name == AZURE and azure_enabled:
elif provider_name == AZURE and Dependencies.azure_enabled:
provider = AzureProvider(lab_name)
elif provider_name == AWS and aws_enabled:
elif provider_name == AWS and Dependencies.aws_enabled:
provider = AwsProvider(lab_name, config)
elif provider_name == LUDUS and ludus_enabled:
elif provider_name == LUDUS and Dependencies.ludus_enabled:
provider = LudusProvider(lab_name, config)
if provider is not None:
self.providers[provider_name] = provider
Expand Down
Loading

0 comments on commit 44919d8

Please sign in to comment.