On Tue, Feb 04, 2014 at 05:00:30PM +0100, Santi Raffa wrote:
> Signed-off-by: Santi Raffa <[email protected]>
> ---
>  lib/backend.py                      |  4 +++
>  lib/cli.py                          |  3 +++
>  lib/client/gnt_instance.py          |  4 ++-
>  lib/cmdlib/instance.py              | 31 ++++++++++++++++++++---
>  man/gnt-instance.rst                | 14 +++++++++++
>  src/Ganeti/Constants.hs             |  3 +++
>  src/Ganeti/OpCodes.hs               |  2 ++
>  src/Ganeti/OpParams.hs              | 22 ++++++++++++++++
>  test/hs/Test/Ganeti/OpCodes.hs      | 50 
> +++++++++++++++++++++++++++++--------
>  test/py/cmdlib/instance_unittest.py |  1 +
>  10 files changed, 118 insertions(+), 16 deletions(-)
> 
> diff --git a/lib/backend.py b/lib/backend.py
> index 3d51704..dfc8690 100644
> --- a/lib/backend.py
> +++ b/lib/backend.py
> @@ -3266,6 +3266,10 @@ def FinalizeExport(instance, snap_disks):
>    for name, value in instance.osparams.items():
>      config.set(constants.INISECT_OSP, name, str(value))
>  
> +  config.add_section(constants.INISECT_OSP_PRIVATE)
> +  for name, value in instance.osparams_private.items():
> +    config.set(constants.INISECT_OSP_PRIVATE, name, str(value.Get()))
> +
>    utils.WriteFile(utils.PathJoin(destdir, constants.EXPORT_CONF_FILE),
>                    data=config.Dumps())
>    shutil.rmtree(finaldestdir, ignore_errors=True)
> diff --git a/lib/cli.py b/lib/cli.py
> index 5a99da6..e7f1755 100644
> --- a/lib/cli.py
> +++ b/lib/cli.py
> @@ -2764,6 +2764,7 @@ def GenericInstanceCreate(mode, opts, args):
>      no_install = None
>      identify_defaults = opts.identify_defaults
>      compress = opts.compress
> +    opts.osparams_secret = None

Please follow the structure of the current code, namely,

  if mode == constants.INSTANCE_CREATE:
    ...
    osparams_secret = opts.osparams_secret
  else:
    ...
    osparams_secret = None

>    else:
>      raise errors.ProgrammerError("Invalid creation mode %s" % mode)
>  
> @@ -2783,6 +2784,8 @@ def GenericInstanceCreate(mode, opts, args):
>                                  hvparams=hvparams,
>                                  beparams=opts.beparams,
>                                  osparams=opts.osparams,
> +                                osparams_private=opts.osparams_private,
> +                                osparams_secret=opts.osparams_secret,
>                                  mode=mode,
>                                  start=start,
>                                  os_type=os_type,
> diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py
> index 980368f..b4deaa7 100644
> --- a/lib/client/gnt_instance.py
> +++ b/lib/client/gnt_instance.py
> @@ -1484,7 +1484,9 @@ add_opts = [
>  
>  commands = {
>    "add": (
> -    AddInstance, [ArgHost(min=1, max=1)], COMMON_CREATE_OPTS + add_opts,
> +    AddInstance, [ArgHost(min=1, max=1)],
> +    COMMON_CREATE_OPTS + add_opts + [OSPARAMS_NOLOG_OPT,
> +                                     OSPARAMS_NOLOG_NOSAVE_OPT],
>      "[...] -t disk-type -n node[:secondary-node] -o os-type <name>",
>      "Creates and adds a new instance to the cluster"),
>    "batch-create": (
> diff --git a/lib/cmdlib/instance.py b/lib/cmdlib/instance.py
> index 86247c5..2f38a01 100644
> --- a/lib/cmdlib/instance.py
> +++ b/lib/cmdlib/instance.py
> @@ -37,6 +37,7 @@ from ganeti import masterd
>  from ganeti import netutils
>  from ganeti import objects
>  from ganeti import pathutils
> +from ganeti import serializer
>  import ganeti.rpc.node as rpc
>  from ganeti import utils
>  
> @@ -836,6 +837,12 @@ class LUInstanceCreate(LogicalUnit):
>          if name not in self.op.osparams:
>            self.op.osparams[name] = value
>  
> +    if einfo.has_section(constants.INISECT_OSP_PRIVATE):
> +      # use the parameters, without overriding
> +      for name, value in einfo.items(constants.INISECT_OSP_PRIVATE):
> +        if name not in self.op.osparams_private:
> +          self.op.osparams_private[name] = serializer.Private(value, 
> descr=name)
> +
>    def _RevertToDefaults(self, cluster):
>      """Revert the instance parameters to the default values.
>  
> @@ -862,6 +869,11 @@ class LUInstanceCreate(LogicalUnit):
>        if name in os_defs and os_defs[name] == self.op.osparams[name]:
>          del self.op.osparams[name]

Missing comment, for consistency.

> +    os_defs_ = cluster.SimpleFillOS(self.op.os_type, {}, {})

Aren't these keyword arguments (at the end of the call) ?
  If so, there is another call just above.

And aren't secret params missing also?

> +    for name in self.op.osparams_private.keys():
> +      if name in os_defs_ and os_defs_[name] == 
> self.op.osparams_private[name]:
> +        del self.op.osparams_private[name]
> +
>    def _CalculateFileStorageDir(self):
>      """Calculate final instance file storage dir.
>  
> @@ -966,7 +978,15 @@ class LUInstanceCreate(LogicalUnit):
>      self.be_full = _ComputeFullBeParams(self.op, cluster)
>  
>      # build os parameters
> -    self.os_full = cluster.SimpleFillOS(self.op.os_type, self.op.osparams)
> +    if self.op.osparams_private is None:
> +      self.op.osparams_private = serializer.PrivateDict()
> +    if self.op.osparams_secret is None:
> +      self.op.osparams_secret = serializer.PrivateDict()
> +
> +    self.os_full = cluster.SimpleFillOS(self.op.os_type,
> +                                        self.op.osparams,
> +                                        self.op.osparams_private,
> +                                        self.op.osparams_secret)

Keyword args here too?

Thanks,
Jose

>      # now that hvp/bep are in final format, let's reset to defaults,
>      # if told to do so
> @@ -1321,6 +1341,7 @@ class LUInstanceCreate(LogicalUnit):
>                              hvparams=self.op.hvparams,
>                              hypervisor=self.op.hypervisor,
>                              osparams=self.op.osparams,
> +                            osparams_private=self.op.osparams_private,
>                              )
>  
>      if self.op.tags:
> @@ -1417,7 +1438,9 @@ class LUInstanceCreate(LogicalUnit):
>            feedback_fn("* running the instance OS create scripts...")
>            # FIXME: pass debug option from opcode to backend
>            os_add_result = \
> -            self.rpc.call_instance_os_add(self.pnode.uuid, (iobj, None), 
> False,
> +            self.rpc.call_instance_os_add(self.pnode.uuid,
> +                                          (iobj, self.op.osparams_secret),
> +                                          False,
>                                            self.op.debug_level)
>            if pause_sync:
>              feedback_fn("* resuming disk sync")
> @@ -2997,9 +3020,9 @@ class LUInstanceSetParams(LogicalUnit):
>                                  hvspecs)
>  
>      # osparams processing
> -    if self.op.osparams or self.op.osparams_private_cluster:
> +    if self.op.osparams or self.op.osparams_private:
>        public_parms = self.op.osparams or {}
> -      private_parms = self.op.osparams_private_cluster or {}
> +      private_parms = self.op.osparams_private or {}
>        dupe_keys = utils.GetRepeatedKeys(public_parms, private_parms)
>  
>        if dupe_keys:
> diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst
> index cc23891..f41cfd7 100644
> --- a/man/gnt-instance.rst
> +++ b/man/gnt-instance.rst
> @@ -37,6 +37,8 @@ ADD
>  | [{-B|\--backend-parameters} *BEPARAMS*]
>  | [{-H|\--hypervisor-parameters} *HYPERVISOR* [: option=*value*... ]]
>  | [{-O|\--os-parameters} *param*=*value*... ]
> +| [--os-parameters-private *param*=*value*... ]
> +| [--os-parameters-secret *param*=*value*... ]
>  | [\--file-storage-dir *dir\_path*] [\--file-driver {loop \| blktap \| 
> blktap2}]
>  | {{-n|\--node} *node[:secondary-node]* \| {-I|\--iallocator} *name*}
>  | {{-o|\--os-type} *os-type*}
> @@ -826,6 +828,18 @@ a hypothetical ``dhcp`` parameter to yes can be achieved 
> by::
>  
>      gnt-instance add -O dhcp=yes ...
>  
> +You can also specify OS parameters that should not be logged but reused
> +at the next reinstall with ``--os-parameters-private`` and OS parameters
> +that should not be logged or saved to configuration with
> +``--os-parameters-secret``. Bear in mind that:
> +
> +  * Launching the daemons in debug mode will cause debug logging to
> +    happen, which leaks private and secret parameters to the log files.
> +    Do not use the debug mode in production. Deamons will emit a warning
> +    on startup if they are in debug mode.
> +  * You will have to pass again all ``--os-parameters-secret`` parameters
> +    should you want to reinstall this instance.
> +
>  The ``-I (--iallocator)`` option specifies the instance allocator plugin
>  to use (``.`` means the default allocator). If you pass in this option
>  the allocator will select nodes for this instance automatically, so you
> diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs
> index 642ae5b..e16b32c 100644
> --- a/src/Ganeti/Constants.hs
> +++ b/src/Ganeti/Constants.hs
> @@ -1089,6 +1089,9 @@ inisectIns = "instance"
>  inisectOsp :: String
>  inisectOsp = "os"
>  
> +inisectOspPrivate :: String
> +inisectOspPrivate = "os_private"
> +
>  -- * Dynamic device modification
>  
>  ddmAdd :: String
> diff --git a/src/Ganeti/OpCodes.hs b/src/Ganeti/OpCodes.hs
> index 8762198..362b2e8 100644
> --- a/src/Ganeti/OpCodes.hs
> +++ b/src/Ganeti/OpCodes.hs
> @@ -438,6 +438,8 @@ $(genOpCode "OpCode"
>       , pInstNics
>       , pNoInstall
>       , pInstOsParams
> +     , pInstOsParamsPrivate
> +     , pInstOsParamsSecret
>       , pInstOs
>       , pPrimaryNode
>       , pPrimaryNodeUuid
> diff --git a/src/Ganeti/OpParams.hs b/src/Ganeti/OpParams.hs
> index cda57e5..9dcb5e6 100644
> --- a/src/Ganeti/OpParams.hs
> +++ b/src/Ganeti/OpParams.hs
> @@ -119,6 +119,8 @@ module Ganeti.OpParams
>    , pClusterOsParams
>    , pClusterOsParamsPrivate
>    , pInstOsParams
> +  , pInstOsParamsPrivate
> +  , pInstOsParamsSecret
>    , pCandidatePoolSize
>    , pMaxRunningJobs
>    , pUidPool
> @@ -1096,6 +1098,26 @@ pInstOsParams =
>    defaultField [| toJSObject [] |] $
>    simpleField "osparams" [t| JSObject JSValue |]
>  
> +pInstOsParamsPrivate :: Field
> +pInstOsParamsPrivate =
> +  field { fieldDoc = "meh"
> +          -- fieldShow = Just [| \(_,y) -> showPrivateJSObject y |]
> +        }
> +  where field =
> +          withDoc "Private OS parameters for instance" .
> +          optionalField $
> +          simpleField "osparams_private" [t| JSObject (Private JSValue) |]
> +
> +pInstOsParamsSecret :: Field
> +pInstOsParamsSecret =
> +  field { fieldDoc = "meh"
> +          -- fieldShow = Just [| \(_,y) -> showPrivateJSObject y |]
> +        }
> +  where field =
> +          withDoc "Secret OS parameters for instance" .
> +          optionalField $
> +          simpleField "osparams_secret" [t| JSObject (Private JSValue) |]
> +
>  pPrimaryNode :: Field
>  pPrimaryNode =
>    withDoc "Primary node for an instance" $
> diff --git a/test/hs/Test/Ganeti/OpCodes.hs b/test/hs/Test/Ganeti/OpCodes.hs
> index eb9d940..56a76fc 100644
> --- a/test/hs/Test/Ganeti/OpCodes.hs
> +++ b/test/hs/Test/Ganeti/OpCodes.hs
> @@ -255,17 +255,45 @@ instance Arbitrary OpCodes.OpCode where
>            return Nothing <*> genMaybe genNodeNameNE <*> return Nothing <*>
>            genMaybe genNameNE <*> arbitrary
>        "OP_INSTANCE_CREATE" ->
> -        OpCodes.OpInstanceCreate <$> genFQDN <*> arbitrary <*>
> -          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
> -          pure emptyJSObject <*> arbitrary <*> arbitrary <*> arbitrary <*>
> -          genMaybe genNameNE <*> pure emptyJSObject <*> arbitrary <*>
> -          genMaybe genNameNE <*> arbitrary <*> arbitrary <*> arbitrary <*>
> -          arbitrary <*> arbitrary <*> arbitrary <*> pure emptyJSObject <*>
> -          genMaybe genNameNE <*> genMaybe genNodeNameNE <*> return Nothing 
> <*>
> -          genMaybe genNodeNameNE <*> return Nothing <*> genMaybe (pure []) 
> <*>
> -          genMaybe genNodeNameNE <*> arbitrary <*> genMaybe genNodeNameNE <*>
> -          return Nothing <*> genMaybe genNodeNameNE <*> genMaybe genNameNE 
> <*>
> -          arbitrary <*> arbitrary <*> (genTags >>= mapM mkNonEmpty)
> +        OpCodes.OpInstanceCreate
> +          <$> genFQDN                         -- instance_name
> +          <*> arbitrary                       -- force_variant
> +          <*> arbitrary                       -- wait_for_sync
> +          <*> arbitrary                       -- name_check
> +          <*> arbitrary                       -- ignore_ipolicy
> +          <*> arbitrary                       -- opportunistic_locking
> +          <*> pure emptyJSObject              -- beparams
> +          <*> arbitrary                       -- disks
> +          <*> arbitrary                       -- disk_template
> +          <*> arbitrary                       -- file_driver
> +          <*> genMaybe genNameNE              -- file_storage_dir
> +          <*> pure emptyJSObject              -- hvparams
> +          <*> arbitrary                       -- hypervisor
> +          <*> genMaybe genNameNE              -- iallocator
> +          <*> arbitrary                       -- identify_defaults
> +          <*> arbitrary                       -- ip_check
> +          <*> arbitrary                       -- conflicts_check
> +          <*> arbitrary                       -- mode
> +          <*> arbitrary                       -- nics
> +          <*> arbitrary                       -- no_install
> +          <*> pure emptyJSObject              -- osparams
> +          <*> genMaybe arbitraryPrivateJSObj  -- osparams_private
> +          <*> genMaybe arbitraryPrivateJSObj  -- osparams_secret
> +          <*> genMaybe genNameNE              -- os_type
> +          <*> genMaybe genNodeNameNE          -- pnode
> +          <*> return Nothing                  -- pnode_uuid
> +          <*> genMaybe genNodeNameNE          -- snode
> +          <*> return Nothing                  -- snode_uuid
> +          <*> genMaybe (pure [])              -- source_handshake
> +          <*> genMaybe genNodeNameNE          -- source_instance_name
> +          <*> arbitrary                       -- source_shutdown_timeout
> +          <*> genMaybe genNodeNameNE          -- source_x509_ca
> +          <*> return Nothing                  -- src_node
> +          <*> genMaybe genNodeNameNE          -- src_node_uuid
> +          <*> genMaybe genNameNE              -- src_path
> +          <*> arbitrary                       -- compress
> +          <*> arbitrary                       -- start
> +          <*> (genTags >>= mapM mkNonEmpty)   -- tags
>        "OP_INSTANCE_MULTI_ALLOC" ->
>          OpCodes.OpInstanceMultiAlloc <$> arbitrary <*> genMaybe genNameNE <*>
>          pure []
> diff --git a/test/py/cmdlib/instance_unittest.py 
> b/test/py/cmdlib/instance_unittest.py
> index 23605d3..3fe3ee7 100644
> --- a/test/py/cmdlib/instance_unittest.py
> +++ b/test/py/cmdlib/instance_unittest.py
> @@ -465,6 +465,7 @@ class TestLUInstanceCreate(CmdlibTestCase):
>                           osparams={
>                             self.os_name_variant: {}
>                           },
> +                         osparams_private={},
>                           identify_defaults=True)
>      self.ExecOpCode(op)
>  
> -- 
> 1.9.0.rc1.175.g0b1dcb5
> 

-- 
Jose Antonio Lopes
Ganeti Engineering
Google Germany GmbH
Dienerstr. 12, 80331, München

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Christine Elizabeth Flores
Steuernummer: 48/725/00206
Umsatzsteueridentifikationsnummer: DE813741370

Reply via email to