]> Frank Brehm's Git Trees - pixelpark/create-terraform.git/commitdiff
Input of failing information
authorFrank Brehm <frank.brehm@pixelpark.com>
Fri, 3 Sep 2021 15:30:35 +0000 (17:30 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Fri, 3 Sep 2021 15:30:35 +0000 (17:30 +0200)
* New functions password_input_getch() and password_input()
* Asking for VSphere user and password and for PowerDNS API key,
  if not configured
* Don't write those information into terraform variables,
  if they are not configured

lib/cr_tf/handler.py

index d656820507dff7be3462da6803cdc01921196f5a..8f465b7d94c1b17471bc364cfa26bb36d68b73ac 100644 (file)
@@ -28,6 +28,13 @@ from distutils.version import LooseVersion
 
 from operator import attrgetter
 
+HAS_GETCH = False
+try:
+    import getch
+    HAS_GETCH = True
+except ImportError:
+    pass
+
 # Third party modules
 import pytz
 import yaml
@@ -60,13 +67,54 @@ from .terraform.disk import TerraformDisk
 
 from .xlate import XLATOR
 
-__version__ = '3.4.8'
+__version__ = '3.5.0'
 LOG = logging.getLogger(__name__)
 
 _ = XLATOR.gettext
 ngettext = XLATOR.ngettext
 
 
+# =============================================================================
+def password_input_getch(prompt='', fill_char='*', max_len=64):
+    p_s = ''
+    proxy_string = ' ' * 64
+
+    fch = ' '
+    if len(fill_char) >= 1:
+        fch = fill_char[0]
+
+    while True:
+
+        print('\r' + proxy_string, end='', flush=True)
+        print('\r' + prompt, end='', flush=True)
+
+        c = getch.getch()
+        if c == b'\r' or c == b'\n':
+            break
+        elif c == b'\x08':
+            if len(p_s):
+                p_s = p_s[:-1]
+            continue
+
+       p_s += to_str(c)
+       if len(p_s) >= max_len:
+           break
+
+    print('', flush=True)
+    return p_s
+
+
+# =============================================================================
+def password_input(prompt='', fill_char='*', max_len=64):
+
+    if HAS_GETCH:
+        return password_input_getch(prompt=prompt, fill_char=fill_char, max_len=max_len)
+
+    import getpass
+
+    return getpass.getpass(prompt=prompt)
+
+
 # =============================================================================
 class AbortExecution(ExpectedHandlerError):
     """Indicating an abort of the execution."""
@@ -367,10 +415,20 @@ class CreateTerraformHandler(BaseHandler):
             raise CommandNotFoundError('terraform')
         self.check_terraform_version()
 
+        pdns_api_key = self.config.pdns_api_key
+        if not pdns_api_key:
+            msg = '\n' + _("Please input the {}:").format(self.colored(
+                'PowerDNS API key', 'AQUA'))
+            print(msg)
+            pdns_api_key = password_input(prompt='Key: ')
+            if pdns_api_key == '':
+                msg = _("No {} given.").format('PowerDNS API key')
+                raise ExpectedHandlerError(msg)
+
         self.pdns = PowerDNSServer(
             appname=self.appname, verbose=self.verbose, base_dir=self.base_dir,
             master_server=self.config.pdns_master_server,
-            port=self.config.pdns_api_port, key=self.config.pdns_api_key,
+            port=self.config.pdns_api_port, key=pdns_api_key,
             use_https=self.config.pdns_api_use_https, path_prefix=self.config.pdns_api_path_prefix,
             simulate=self.simulate, force=self.force, initialized=True,
         )
@@ -689,6 +747,27 @@ class CreateTerraformHandler(BaseHandler):
                 msg = _("VSPhere {!r} not defined in configuration.").format(vname)
                 raise ExpectedHandlerError(msg)
 
+            vsphere_user = self.config.vsphere[vname].user
+            vsphere_password = self.config.vsphere[vname].password
+
+            if not vsphere_user:
+                msg = '\n' + _("Please input the {}:").format(self.colored(
+                        _('vSphere user name'), 'AQUA'))
+                print(msg)
+                vsphere_user = input(_('vSphere user name') + ': ')
+                if vsphere_user == '':
+                    msg = _("No {} given.").format(_('vSphere user name'))
+                    raise ExpectedHandlerError(msg)
+
+            if not vsphere_password:
+                msg = '\n' + _("Please input the {}:").format(self.colored(
+                        _('vSphere user password'), 'AQUA'))
+                print(msg)
+                vsphere_password = password_input(prompt=(_('vSphere user name') + ': '))
+                if vsphere_password == '':
+                    msg = _("No {} given.").format(_('vSphere user password'))
+                    raise ExpectedHandlerError(msg)
+
             try:
                 params = {
                     'appname': self.appname,
@@ -696,8 +775,8 @@ class CreateTerraformHandler(BaseHandler):
                     'base_dir': self.base_dir,
                     'host': self.config.vsphere[vname].host,
                     'port': self.config.vsphere[vname].port,
-                    'user': self.config.vsphere[vname].user,
-                    'password': self.config.vsphere[vname].password,
+                    'user': vsphere_user,
+                    'password': vsphere_password,
                     'dc': self.config.vsphere[vname].dc,
                     'simulate': self.simulate,
                     'force': self.force,
@@ -2150,26 +2229,25 @@ class CreateTerraformHandler(BaseHandler):
                 fh.write(content)
             os.chmod('terraform.tfvars', self.std_file_permissions)
 
-        tpl = textwrap.dedent('''\
-        # Private sensible information. Please keep this file secret.
-
-        vsphere_user     = "{u}"
-        vsphere_password = "{p}"
-        pdns_api_key     = "{a}"
-
-        ''')
-
-        content = tpl.format(u=vs_user, p=vs_pwd, a=self.config.pdns_api_key)
+        # Sensible stuff
+        if vs_user or vs_pwd:
+            content = '# Private sensible information. Please keep this file secret.\n\n'
+            if vs_user:
+                content += 'vsphere_user     = "{}"\n.'.format(vs_user)
+            if vs_pwd:
+                content += 'vsphere_password = "{}""\n.'.format(vs_pwd)
+            content += '\n'
 
-        LOG.debug(_("Creating {!r} ...").format('private.auto.tfvars'))
-        if self.simulate:
-            if self.verbose:
-                print(content)
-        else:
-            with open('private.auto.tfvars', 'w', **self.open_opts) as fh:
-                fh.write(content)
-            os.chmod('private.auto.tfvars', self.std_secure_file_permissions)
+            LOG.debug(_("Creating {!r} ...").format('private.auto.tfvars'))
+            if self.simulate:
+                if self.verbose:
+                    print(content)
+            else:
+                with open('private.auto.tfvars', 'w', **self.open_opts) as fh:
+                    fh.write(content)
+                os.chmod('private.auto.tfvars', self.std_secure_file_permissions)
 
+        # File with variable declarations
         content = textwrap.dedent('''\
         # filename: variables.tf
         # definition of the variables to be used in the play
@@ -2854,19 +2932,19 @@ class CreateTerraformHandler(BaseHandler):
 
                 LOG.debug(_("Completed process:") + "\n" + str(result))
 
-        print()
-        LOG.info(_("Executing {!r} ...").format('terraform plan'))
-        cmd = [str(self.terraform_cmd), 'plan']
-        try:
-            result = self.run(
-                cmd, may_simulate=True, timeout=tf_timeout, stdout=PIPE, stderr=PIPE, check=True)
-        except CalledProcessError as e:
-            if e.stdout:
-                print(self.colored("Output", 'AQUA') + ':\n' + to_str(e.stdout))
-            if e.stderr:
-                print(self.colored("Error message", ('BOLD', 'RED')) + ':\n' + to_str(e.stderr))
-            raise ExpectedHandlerError(str(e))
-        LOG.debug(_("Completed process:") + "\n" + str(result))
+#        print()
+#        LOG.info(_("Executing {!r} ...").format('terraform plan'))
+#        cmd = [str(self.terraform_cmd), 'plan']
+#        try:
+#            result = self.run(
+#                cmd, may_simulate=True, timeout=tf_timeout, stdout=PIPE, stderr=PIPE, check=True)
+#        except CalledProcessError as e:
+#            if e.stdout:
+#                print(self.colored("Output", 'AQUA') + ':\n' + to_str(e.stdout))
+#            if e.stderr:
+#                print(self.colored("Error message", ('BOLD', 'RED')) + ':\n' + to_str(e.stderr))
+#            raise ExpectedHandlerError(str(e))
+#        LOG.debug(_("Completed process:") + "\n" + str(result))
 
         goto = Path(os.path.relpath(self.project_dir, self.start_dir))