move argument/column handling to decoder (prepare for more post-processing in decoder)
This commit is contained in:
parent
1c5b971d86
commit
c03374d6df
@ -74,6 +74,9 @@ _TArgs = typing.TypeVar("_TArgs", bound="BaseArguments")
|
|||||||
|
|
||||||
@dataclasses.dataclass(slots=True, kw_only=True)
|
@dataclasses.dataclass(slots=True, kw_only=True)
|
||||||
class BaseArguments:
|
class BaseArguments:
|
||||||
|
def __post_init__(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_fields_to_parser(
|
def add_fields_to_parser(
|
||||||
cls: type[_TArgs],
|
cls: type[_TArgs],
|
||||||
|
@ -1,12 +1,28 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
|
||||||
from ldaptool._utils import argclasses
|
from ldaptool._utils import argclasses
|
||||||
|
|
||||||
|
|
||||||
|
def _parser_add_attributes(parser: argparse.ArgumentParser, dest: str) -> None:
|
||||||
|
parser.add_argument(
|
||||||
|
metavar="attributes",
|
||||||
|
dest=dest,
|
||||||
|
nargs="*",
|
||||||
|
help="""
|
||||||
|
Attributes to lookup (and columns to display in tables).
|
||||||
|
Fake attributes `dndomain`, `dnpath` an `dnfullpath` are available (created from dn).
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(slots=True, kw_only=True)
|
@dataclasses.dataclass(slots=True, kw_only=True)
|
||||||
class Arguments(argclasses.BaseArguments):
|
class Arguments(argclasses.BaseArguments):
|
||||||
|
columns: list[str] = dataclasses.field(default_factory=list, metadata=argclasses.manual(_parser_add_attributes))
|
||||||
|
attributes: list[str] = dataclasses.field(default_factory=list)
|
||||||
|
|
||||||
json: bool = dataclasses.field(
|
json: bool = dataclasses.field(
|
||||||
default=False,
|
default=False,
|
||||||
metadata=argclasses.arg(help="Use full json output"),
|
metadata=argclasses.arg(help="Use full json output"),
|
||||||
@ -19,29 +35,30 @@ class Arguments(argclasses.BaseArguments):
|
|||||||
default=", ",
|
default=", ",
|
||||||
metadata=argclasses.arg(help="Separator to join multiple values of one attribute with (default: %(default)r)"),
|
metadata=argclasses.arg(help="Separator to join multiple values of one attribute with (default: %(default)r)"),
|
||||||
)
|
)
|
||||||
|
|
||||||
dateonly: bool = dataclasses.field(
|
dateonly: bool = dataclasses.field(
|
||||||
default=True,
|
default=True,
|
||||||
metadata=argclasses.arg(help="Use only date part of decoded timestamps"),
|
metadata=argclasses.arg(help="Use only date part of decoded timestamps"),
|
||||||
)
|
)
|
||||||
dndomain: bool = dataclasses.field(
|
|
||||||
default=False,
|
dndomain: bool = False
|
||||||
metadata=argclasses.arg(help="Whether to export a virtual dndomain attribute (DNS domain from dn)"),
|
dnpath: bool = False
|
||||||
)
|
dnfullpath: bool = False
|
||||||
dnpath: bool = dataclasses.field(
|
|
||||||
default=False,
|
def __post_init__(self) -> None:
|
||||||
metadata=argclasses.arg(
|
super(Arguments, self).__post_init__() # super() not working here, unclear why.
|
||||||
help="""
|
|
||||||
Whether to export a virtual dnpath attribute
|
# extract special attribute names
|
||||||
('/' joined values of reversed DN without DNS labels)
|
attributes_set: dict[str, str] = {arg.lower(): arg for arg in self.columns} # index by lowercase name
|
||||||
"""
|
# create fake attributes on demand
|
||||||
),
|
if attributes_set.pop("dndomain", ""):
|
||||||
)
|
self.dndomain = True
|
||||||
dnfullpath: bool = dataclasses.field(
|
if attributes_set.pop("dnpath", ""):
|
||||||
default=False,
|
self.dnpath = True
|
||||||
metadata=argclasses.arg(
|
if attributes_set.pop("dnfullpath", ""):
|
||||||
help="""
|
self.dnfullpath = True
|
||||||
Whether to export a virtual dnfullpath attribute
|
# store remaining attributes (with original case)
|
||||||
('/' joined values of reversed DN; DNS domain as first label)
|
self.attributes = list(attributes_set.values())
|
||||||
"""
|
if self.columns and not self.attributes:
|
||||||
),
|
# if we only wanted fake attributes, make sure we only request 'dn' - empty list would query all attributes
|
||||||
)
|
self.attributes = ["dn"]
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
@ -8,28 +7,8 @@ import ldaptool.decode.arguments
|
|||||||
from ldaptool._utils import argclasses
|
from ldaptool._utils import argclasses
|
||||||
|
|
||||||
|
|
||||||
def _parser_add_attributes(parser: argparse.ArgumentParser, dest: str) -> None:
|
|
||||||
parser.add_argument(
|
|
||||||
metavar="attributes",
|
|
||||||
dest=dest,
|
|
||||||
nargs="*",
|
|
||||||
help="""
|
|
||||||
Attributes to lookup (and columns to display in tables).
|
|
||||||
Fake attributes `dndomain`, `dnpath` an `dnfullpath` are available (created from dn).
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(slots=True, kw_only=True)
|
@dataclasses.dataclass(slots=True, kw_only=True)
|
||||||
class Arguments(ldaptool.decode.arguments.Arguments):
|
class Arguments(ldaptool.decode.arguments.Arguments):
|
||||||
# overwrite fields for fake attributes to remove them from argparse;
|
|
||||||
# we enable those based on the attribute list
|
|
||||||
dndomain: bool = False
|
|
||||||
dnpath: bool = False
|
|
||||||
dnfullpath: bool = False
|
|
||||||
|
|
||||||
attributes: list[str] = dataclasses.field(default_factory=list, metadata=argclasses.manual(_parser_add_attributes))
|
|
||||||
columns: list[str] = dataclasses.field(default_factory=list)
|
|
||||||
filter: typing.Optional[str] = dataclasses.field(default=None, metadata=argclasses.arg(help="LDAP query filter"))
|
filter: typing.Optional[str] = dataclasses.field(default=None, metadata=argclasses.arg(help="LDAP query filter"))
|
||||||
find: typing.Optional[str] = dataclasses.field(
|
find: typing.Optional[str] = dataclasses.field(
|
||||||
default=None,
|
default=None,
|
||||||
@ -75,6 +54,8 @@ class Arguments(ldaptool.decode.arguments.Arguments):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
|
super(Arguments, self).__post_init__() # super() not working here, unclear why.
|
||||||
|
|
||||||
if not self.filter is None:
|
if not self.filter is None:
|
||||||
if not self.find is None:
|
if not self.find is None:
|
||||||
raise SystemExit("Can't use both --find and --filter")
|
raise SystemExit("Can't use both --find and --filter")
|
||||||
@ -86,19 +67,3 @@ class Arguments(ldaptool.decode.arguments.Arguments):
|
|||||||
else:
|
else:
|
||||||
# probably doesn't like empty filter?
|
# probably doesn't like empty filter?
|
||||||
self.filter = "(objectClass=*)"
|
self.filter = "(objectClass=*)"
|
||||||
|
|
||||||
# extract special attribute names
|
|
||||||
self.columns = self.attributes # use all names for columns (headings and their order)
|
|
||||||
attributes_set: dict[str, str] = {arg.lower(): arg for arg in self.attributes} # index by lowercase name
|
|
||||||
# create fake attributes on demand
|
|
||||||
if attributes_set.pop("dndomain", ""):
|
|
||||||
self.dndomain = True
|
|
||||||
if attributes_set.pop("dnpath", ""):
|
|
||||||
self.dnpath = True
|
|
||||||
if attributes_set.pop("dnfullpath", ""):
|
|
||||||
self.dnfullpath = True
|
|
||||||
# store remaining attributes (with original case)
|
|
||||||
self.attributes = list(attributes_set.values())
|
|
||||||
if self.columns and not self.attributes:
|
|
||||||
# if we only wanted fake attributes, make sure we only request 'dn' - empty list would query all attributes
|
|
||||||
self.attributes = ["dn"]
|
|
||||||
|
Loading…
Reference in New Issue
Block a user