Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ad/GOAD/data/inventory
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ domain_name=GOAD
admin_user=administrator

; global settings inventory default value
keyboard_layouts=["en-US", "da-DK", "fr-FR"]
;keyboard_layouts=["en-US", "da-DK", "fr-FR"] ; Now set in the inventory file of the workspace

; modify this to add a default route
add_route=no
Expand Down
2 changes: 1 addition & 1 deletion ad/TEMPLATE/data/inventory
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
domain_name=TEMPLATE

; global settings inventory default value
keyboard_layouts=["en-US", "da-DK", "fr-FR"]
;keyboard_layouts=["en-US", "da-DK", "fr-FR"] ; Now set in the inventory file of the workspace

; modify this to add a default route
add_route=no
Expand Down
4 changes: 2 additions & 2 deletions docs/mkdocs/docs/questions.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Frequent asked questions


!!! question "How can i change the default keyboard layout ?"
edit globalsettings.ini files and change the variable `keyboard_layouts`
!!! question "How can i change the default keyboard layout?"
Either use the `--keyboard-layout` option or configure it via the goad cli. Alternatively, you can set a default in the `~/.goad/goad.ini` config file.

!!! question "How can i change the folder where vagrant download the boxes ?"
vagrant download the boxes by default on ~/.vagrant.d/ folder. Set up the VAGRANT_HOME environment variable to change this location.
Expand Down
2 changes: 1 addition & 1 deletion globalsettings.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
; German : 00000407
; Spanish : 0000040A
; the first in the list will be the default layout (here: FR | US)
keyboard_layouts=["0000040C", "00000409"]
;keyboard_layouts=["00000407", "00000407"] ; Now set in the inventory file of the workspace

; Uncoment to not use SSL in ansible (usefull if you get Digest initialization failed: initialization error with vagrant)
# ansible_winrm_transport=basic
Expand Down
9 changes: 9 additions & 0 deletions goad.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ def do_set_ip_range(self, arg):
self.lab_manager.set_ip_range(arg)
self.refresh_prompt()

def do_set_keyboard_layout(self, arg):
if arg == '':
Log.error('missing keyboard layout argument')
Log.info(f'set_keyboard_layout <keyboard_layout1>,<keyboard_layout2>,...')
else:
self.lab_manager.set_keyboard_layout(arg)
self.refresh_prompt()

def do_set_extensions(self, arg):
if arg == '':
Log.error('missing extensions arguments')
Expand Down Expand Up @@ -462,6 +470,7 @@ def parse_args():
parser.add_argument("-l", "--lab", help="lab to use (default: GOAD)", default='GOAD', required=False)
parser.add_argument("-p", "--provider", help="provider to use (default: vmware)", default='vmware', required=False)
parser.add_argument("-ip", "--ip_range", help="ip range to use (default: 192.168.56)", default='', required=False)
parser.add_argument("-k", "--keyboard-layout", help="keyboard layout(s) to use (default: fr-FR,en-US)", required=False)
parser.add_argument("-m", "--method", help="deploy method to use (default: local)", default='local', required=False)
parser.add_argument("-i", "--instance", help="use a specific instance (use default if not selected)", required=False)
parser.add_argument("-e", "--extensions", help="extensions to use", action='append', required=False)
Expand Down
5 changes: 5 additions & 0 deletions goad/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def create_config_file(self):
config.set('default', '; ip_range (3 first ip digits)')
config.set('default', 'ip_range', '192.168.56')

config.set('default', '; keyboard layouts codes')
config.set('default', 'keyboard_layout', 'fr-FR,en-US')

config.add_section('aws')
config.set('aws', 'aws_region', 'eu-west-3')
config.set('aws', 'aws_zone', 'eu-west-3c')
Expand Down Expand Up @@ -92,6 +95,8 @@ 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.keyboard_layout:
self.set_value('default', KEYBOARD_LAYOUT, args.keyboard_layout)
if args.disable_dependencies:
for disable_dependence in args.disable_dependencies:
if disable_dependence == 'vmware':
Expand Down
29 changes: 27 additions & 2 deletions goad/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class LabInstance:

def __init__(self, instance_id, lab_name, config, provider_name, provisioner_name, ip_range, extensions=None, status='', default=False):
def __init__(self, instance_id, lab_name, config, provider_name, provisioner_name, ip_range, keyboard_layout, extensions=None, status='', default=False):
if instance_id is None:
random_id = ''.join(random.choices(string.hexdigits, k=6))
self.instance_id = f'{random_id}-{lab_name}-{provider_name}'.lower()
Expand All @@ -22,6 +22,7 @@ def __init__(self, instance_id, lab_name, config, provider_name, provisioner_nam
self.provider_name = provider_name
self.provisioner_name = provisioner_name
self.ip_range = ip_range
self.keyboard_layout = keyboard_layout
self.status = status
if extensions is None:
extensions = []
Expand Down Expand Up @@ -106,6 +107,7 @@ def save_json_instance(self):
"provider": self.provider_name,
"provisioner": self.provisioner_name,
"ip_range": self.ip_range,
"keyboard_layout": self.keyboard_layout,
"extensions": self.extensions,
"status": self.status,
"is_default": self.is_default
Expand Down Expand Up @@ -302,7 +304,8 @@ def _create_provisioning_lab_inventory(self, inventory_file):
instance_inventory_content = inventory_template.render(
lab_name=self.lab_name,
ip_range=self.ip_range,
provider_name=self.provider_name
provider_name=self.provider_name,
keyboard_layout=self.keyboard_layout,
)
# create instance inventory file
instance_inventory_file = self.instance_path + sep + inventory_file
Expand All @@ -328,6 +331,17 @@ def _create_provisioning_provider_inventory(self):
inventory_file.write(instance_inventory_content)
Log.success(f'Instance inventory file created : {Utils.get_relative_path(instance_inventory_file)}')

# Very hacky to add the keyboard layout to the inventory file, but works for now
import configparser
config = configparser.ConfigParser(allow_no_value=True)
config.read(instance_inventory_file)
if not config.has_section('all:vars'):
config.add_section('all:vars')
config.set('all:vars', 'keyboard_layouts', str(self.keyboard_layout))
with open(instance_inventory_file, 'w') as configfile:
config.write(configfile)
Log.success(f'Instance inventory file updated: keyboard layout(s)')

def _create_extensions_inventory(self):
Log.info('Create instance extensions inventory files')

Expand All @@ -347,6 +361,17 @@ def _create_extensions_inventory(self):
inventory_file.write(instance_extension_inventory_content)
Log.success(f'Instance inventory file created : {Utils.get_relative_path(instance_extension_inventory_file)}')

# Very hacky to add the keyboard layout to the inventory file, but works for now
import configparser
config = configparser.ConfigParser(allow_no_value=True)
config.read(instance_extension_inventory_file)
if not config.has_section('all:vars'):
config.add_section('all:vars')
config.set('all:vars', 'keyboard_layouts', str(self.keyboard_layout))
with open(instance_extension_inventory_file, 'w') as configfile:
config.write(configfile)
Log.success(f'Instance inventory file updated: keyboard layout(s)')

def update_instance_folder(self):
self.create_instance_folder(True)

Expand Down
5 changes: 4 additions & 1 deletion goad/instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ def _init_instances(self, config):
provider_name = instance_info['provider']
provisioning_method = instance_info['provisioner']
ip_range = instance_info['ip_range']
keyboard_layout = instance_info['keyboard_layout']
extensions = instance_info['extensions']
status = instance_info['status']
is_default = instance_info['is_default']
self.instances[instance] = LabInstance(instance, lab_name, config, provider_name, provisioning_method, ip_range, extensions, status, is_default)
self.instances[instance] = LabInstance(instance, lab_name, config, provider_name, provisioning_method, ip_range, keyboard_layout, extensions, status, is_default)

def nb_instances(self):
return len(self.instances)
Expand Down Expand Up @@ -78,6 +79,7 @@ def show_instances(self, lab_name='', provider_name='', current_instance_id='',
table.add_column('Lab')
table.add_column('Provider')
table.add_column('IP Range')
table.add_column('Keyboard Layout')
table.add_column('Status')
table.add_column('Is Default')
table.add_column('Extensions')
Expand All @@ -96,6 +98,7 @@ def show_instances(self, lab_name='', provider_name='', current_instance_id='',
instance.lab_name,
self.color_provider(instance.provider_name),
instance.ip_range + '.0/24',
",".join(instance.keyboard_layout),
self.color_status(instance.status),
'Yes' if instance.is_default else 'No',
", ".join(instance.extensions)
Expand Down
7 changes: 6 additions & 1 deletion goad/lab_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def __init__(self):
self.current_provisioner = None
self.current_extensions = []
self.current_ip_range = None
self.current_keyboard_layout = []

self.config = None
self.lab_instances = None
Expand All @@ -33,6 +34,7 @@ def init(self, config, args):
self.current_settings.set_provider_name(self.config.get_value('default', PROVIDER), False)
self.current_settings.set_provisioner_name(self.config.get_value('default', PROVISIONER))
self.current_settings.set_ip_range(self.config.get_value('default', IP_RANGE))
self.current_settings.set_keyboard_layout(self.config.get_value('default', KEYBOARD_LAYOUT))
if args.extensions:
self.current_settings.set_extensions(args.extensions)
return self
Expand Down Expand Up @@ -60,7 +62,7 @@ def update_instance_files(self, arg=''):

def create_instance(self):
instance = LabInstance(None, self.current_settings.lab_name, self.config, self.current_settings.provider_name, self.current_settings.provisioner_name,
self.current_settings.ip_range, extensions=self.current_settings.extensions_name)
self.current_settings.ip_range, self.current_settings.keyboard_layout, extensions=self.current_settings.extensions_name)
result = instance.create_instance_folder()
if result:
self.lab_instances.add_instance(instance)
Expand Down Expand Up @@ -137,6 +139,9 @@ def set_ip_range(self, ip_range):
def get_ip_range(self):
return self.current_settings.ip_range

def set_keyboard_layout(self, keyboard_layout):
self.current_settings.set_keyboard_layout(keyboard_layout)

def set_extensions(self, extensions_name):
self.current_settings.set_extensions(extensions_name)

Expand Down
1 change: 1 addition & 0 deletions goad/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def print_menu(lab_manager, advanced=True, debug=False):
print_menu_entry('set_provider <provider>', 'set the provider to use')
print_menu_entry('set_provisioning_method <method>', 'set the provisioning method')
print_menu_entry('set_ip_range <range>', 'set the 3 first digit of the ip to use (ex: 192.168.56)')
print_menu_entry('set_keyboard_layout <layout>', 'set the keyboard layout(s) to use (ex: fr-FR,en-US)')

if lab_manager.get_current_instance() is not None:
print_menu_entry('unload', 'unload current instance')
Expand Down
28 changes: 28 additions & 0 deletions goad/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def __init__(self, lab_manager):
self.provisioner_name = None
self.extensions_name = []
self.ip_range = None
self.keyboard_layout = []

def update(self, instance):
"""
Expand All @@ -26,13 +27,15 @@ def update(self, instance):
self.provisioner_name = instance.provisioner_name
self.ip_range = instance.ip_range
self.extensions_name = instance.extensions
self.keyboard_layout = instance.keyboard_layout

def show(self):
Log.info(f'Current Lab : {self.lab_name}')
Log.info(f'Current Provider : {self.provider_name}')
Log.info(f'Current Provisioner : {self.provisioner_name}')
if self.provider_name != LUDUS:
Log.info(f'Current IP range : {self.ip_range}.X')
Log.info(f'Current Keyboard layout(s) : {self.keyboard_layout}')
Log.info(f'Extension(s) :')
for extension in self.extensions_name:
Log.info(f' - {extension}')
Expand Down Expand Up @@ -161,3 +164,28 @@ def set_extensions(self, extensions_name):
else:
raise ValueError(f"can't set extension because lab_name is not set")
return self.extensions_name

def set_keyboard_layout(self, keyboard_layout):
"""
Set the keyboard layouts
:param keyboard_layout: list of keyboard layouts
:return: list of keyboard layouts
"""
self.keyboard_layout = []
try:
if ',' in keyboard_layout:
for keyboard_layout in keyboard_layout.split(','):
if keyboard_layout in keyboard_layout_dict.keys():
self.keyboard_layout.append(keyboard_layout)
else:
Log.error(f'Keyboard layout {keyboard_layout} is not available.')
else:
if keyboard_layout in keyboard_layout_dict.keys():
self.keyboard_layout.append(keyboard_layout)
else:
Log.error(f'Keyboard layout {keyboard_layout} is not available.')
except Exception as e:
Log.error(f'Error parsing keyboard layout: {e}')
Log.info(f'fallback to default keyboard layout: "fr-FR,en-US"')
self.keyboard_layout = ['fr-FR', 'en-US']
return self.keyboard_layout
10 changes: 10 additions & 0 deletions goad/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
PROVIDER = 'provider'
PROVISIONER = 'provisioner'
IP_RANGE = 'ip_range'
KEYBOARD_LAYOUT = 'keyboard_layout'

# log level
INFO = 5
Expand Down Expand Up @@ -61,6 +62,15 @@
TASK_RESET = 'reset'


# keyboard layout codes
keyboard_layout_dict = {
'fr-FR': '00000407',
'en-US': '00000409',
'de-DE': '00000407',
'es-ES': '0000040A',
'it-IT': '00000410',
}

class SingletonMeta(type):
_instances = {}

Expand Down