Example #1
0
class ConcreteTimePeriod(BaseSchema):
    alias = fields.String(description="The alias of the time period",
                          example="alias")
    active_time_ranges = fields.List(
        fields.Nested(ConcreteTimeRangeActive),
        description="The days for which time ranges were specified",
        example={
            "day": "all",
            "time_ranges": [{
                "start": "12:00",
                "end": "14:00"
            }]
        },
    )
    exceptions = fields.List(
        fields.Nested(ConcreteTimePeriodException),
        description="Specific day exclusions with their list of time ranges",
        example=[{
            "date": "2020-01-01",
            "time_ranges": [{
                "start": "14:00",
                "end": "18:00"
            }]
        }],
    )
    exclude = fields.List(  # type: ignore[assignment]
        fields.String(description="Name of excluding time period",
                      example="holidays"),
        description=
        "The collection of time period aliases whose periods are excluded",
    )
Example #2
0
class HostExtensions(BaseSchema):
    folder = fields.FolderField(
        description="The folder, in which this host resides.", )
    attributes = fields.attributes_field(
        "host",
        "update",
        description="Attributes of this host.",
        example={"ipaddress": "192.168.0.123"},
    )
    effective_attributes = fields.Dict(
        description=
        "All attributes of this host and all parent folders. Format may change!",
        allow_none=True,
        example={"tag_snmp_ds": None},
    )
    is_cluster = fields.Boolean(
        description=
        "If this is a cluster host, i.e. a container for other hosts.", )
    is_offline = fields.Boolean(description="Whether the host is offline", )
    cluster_nodes = fields.List(
        fields.HostField(),
        allow_none=True,
        missing=None,
        description=
        "In the case this is a cluster host, these are the cluster nodes.",
    )
Example #3
0
class ObjectCollectionMember(ObjectMemberBase):
    memberType = fields.Constant("collection")
    value = fields.List(fields.Nested(LinkSchema()))
    name = fields.String(example="important_values")
    title = fields.String(
        description="A human readable title of this object. Can be used for "
        "user interfaces.", )
Example #4
0
class TagConditionConditionSchemaBase(TagConditionSchemaBase):
    """Convert Rulesets to Checkmk structure and back

    Examples:

        >>> tcs = TagConditionConditionSchemaBase()
        >>> tcs.dump([{'hurz': {'$or': ['a', 'b', 'c']}}], many=True)
        [{'key': 'hurz', 'operator': 'one_of', 'value': ['a', 'b', 'c']}]

        >>> tcs.dump({'hurz': {'$or': ['a', 'b', 'c']}})
        {'key': 'hurz', 'operator': 'one_of', 'value': ['a', 'b', 'c']}

        >>> tcs.dump({'hurz': {'$or': 'h'}})
        Traceback (most recent call last):
        ...
        marshmallow.exceptions.ValidationError: Invalid type: 'h'

    """

    cast_to_dict = True

    allowed_operators = ("one_of", "none_of")
    operator_type = "collection"

    # field defined in superclass
    operator = fields.String(
        description="If the matched tag should be one of the given values, or not.",
        enum=list(allowed_operators),  # Our serializer only wants to know lists.
    )
    value = fields.List(
        fields.String(description="The value of a tag."),
        description="A list of values for the tag.",
    )
 def openapi_field(self) -> fields.Field:
     return fields.List(
         fields.String(validate=validators.ValidateAnyOfValidators([
             fields.ValidateIPv4(),
             validators.ValidateHostName(),
         ])),
         description="A list of IPv4 addresses.",
     )
Example #6
0
class ObjectProperty(Linkable):
    id = fields.String(description="The unique name of this property, local to this domain type.")
    value = fields.List(
        fields.String(),
        description="The value of the property. In this case a list.",
    )
    extensions = fields.Dict(
        description="Additional attributes alongside the property.",
    )
Example #7
0
class HostConfigCollection(DomainObjectCollection):
    domainType = fields.Constant(
        "host_config",
        description="The domain type of the objects in the collection.",
    )
    value = fields.List(
        fields.Nested(HostConfigSchema()),
        description="A list of host objects.",
    )
Example #8
0
class FolderCollection(DomainObjectCollection):
    domainType = fields.Constant(
        "folder_config",
        description="The domain type of the objects in the collection.",
    )
    value = fields.List(
        fields.Nested(FolderSchema()),
        description="A list of folder objects.",
    )
Example #9
0
class ConcreteTimePeriodException(BaseSchema):
    date = fields.String(
        example="2020-01-01",
        format="date",
        description="The date of the time period exception." "8601 profile",
    )
    time_ranges = fields.List(
        fields.Nested(ConcreteTimeRange),
        example="[{'start': '14:00', 'end': '18:00'}]",
    )
Example #10
0
class User(Linkable):
    userName = fields.String(description="A unique user name.")
    friendlyName = fields.String(
        required=True,
        description="The user's name in a form suitable to be rendered in a UI.",
    )
    email = fields.String(description="(optional) the user's email address, if known.")
    roles = fields.List(
        fields.String(),
        description="List of unique role names that apply to this user (can be empty).",
    )
Example #11
0
class ActionResultScalar(ActionResultBase):
    result = fields.Nested(
        Schema.from_dict(
            {
                "links": fields.List(
                    fields.Nested(LinkSchema),
                    required=True,
                ),
                "value": fields.String(
                    required=True,
                    example="Done.",
                ),
            },
            name="ActionResultScalarValue",
        ),
        description="The scalar result of the action.",
    )
Example #12
0
class ActionResultObject(ActionResultBase):
    result = fields.Nested(
        Schema.from_dict(
            {
                "links": fields.List(
                    fields.Nested(LinkSchema),
                    required=True,
                ),
                "value": fields.Dict(
                    required=True,
                    example={"duration": "5 seconds."},
                ),
            },
            name="ActionResultObjectValue",
        ),
        description="The result of the action. In this case, an object.",
    )
Example #13
0
class ActionResultObject(ActionResultBase):
    result = fields.Nested(
        Schema.from_dict(
            {
                'links':
                fields.List(
                    fields.Nested(LinkSchema),
                    required=True,
                ),
                'value':
                fields.Dict(
                    required=True,
                    example={'duration': '5 seconds.'},
                )
            },
            name='ActionResultObjectValue',
        ),
        description="The result of the action. In this case, an object.",
    )
Example #14
0
class PasswordExtension(BaseSchema):
    ident = fields.String(
        example="pass",
        description="The unique identifier for the password",
    )
    title = fields.String(
        example="Kubernetes login",
        description="The title for the password",
    )
    comment = fields.String(
        example="Kommentar",
        description="A comment for the password",
    )
    documentation_url = fields.String(
        example="localhost",
        attribute="docu_url",
        description="The URL pointing to documentation or any other page.",
    )
    password = fields.String(
        required=True,
        example="password",
        description="The password string",
    )
    owned_by = fields.String(
        example="admin",
        description=
        "The owner of the password who is able to edit, delete and use existing passwords.",
    )

    shared = fields.List(
        fields.String(
            example="all",
            description="The member the password is shared with",
        ),
        example=["all"],
        attribute="shared_with",
        description="The list of members the password is shared with",
    )
    customer = fields.customer_field(
        required=True,
        should_exist=True,
    )
Example #15
0
class HostParameters(BaseSchema):
    """All the parameters for the hosts list.

    Examples:

        >>> p = HostParameters()
        >>> p.load({})['columns']
        [Column(hosts.name: string)]

        >>> p.load({})['sites']
        []

    """

    sites = fields.List(
        fields.SiteField(),
        description="Restrict the query to this particular site.",
        load_default=[],
    )
    query = fields.query_field(Hosts, required=False)
    columns = fields.column_field(Hosts, mandatory=[Hosts.name])
Example #16
0
class ApiError(BaseSchema):
    code = fields.Integer(
        description="The HTTP status code.",
        required=True,
        example=404,
    )
    message = fields.Str(
        description="Detailed information on what exactly went wrong.",
        required=True,
        example="The resource could not be found.",
    )
    title = fields.Str(
        description="A summary of the problem.",
        required=True,
        example="Not found",
    )
    _fields = fields.Dict(
        data_key="fields",  # mypy
        keys=fields.String(description="The field name"),
        values=fields.List(fields.String(description="The error messages")),
        description="Detailed error messages on all fields failing validation.",
        required=False,
    )
Example #17
0
"""
from cmk.utils.livestatus_helpers.expressions import And
from cmk.utils.livestatus_helpers.queries import Query
from cmk.utils.livestatus_helpers.tables import Services

from cmk.gui import fields, sites
from cmk.gui.plugins.openapi.restful_objects import constructors, Endpoint, response_schemas
from cmk.gui.plugins.openapi.restful_objects.constructors import object_action_href
from cmk.gui.plugins.openapi.restful_objects.parameters import HOST_NAME, OPTIONAL_HOST_NAME
from cmk.gui.plugins.openapi.utils import problem

PARAMETERS = [{
    "sites":
    fields.List(
        fields.SiteField(),
        description="Restrict the query to this particular site.",
        load_default=list,
    ),
    "query":
    fields.query_field(
        Services,
        required=False,
        example='{"op": "=", "left": "host_name", "right": "example.com"}',
    ),
    "columns":
    fields.column_field(
        Services,
        mandatory=[
            Services.host_name,
            Services.description,
        ],
Example #18
0
class Linkable(BaseSchema):
    links = fields.List(
        fields.Nested(LinkSchema),
        required=True,
        description="list of links to other resources.",
    )
Example #19
0
class HostOrServiceConditionSchema(base.BaseSchema):
    """

    Examples:

        >>> wor = HostOrServiceConditionSchema()  # without regex
        >>> rv = wor.load({
        ...     'match_on': ['foo'],
        ...     'operator': 'one_of',
        ... })
        >>> rv
        ['foo']

        >>> wor.dump(rv)
        {'match_on': ['foo'], 'operator': 'one_of'}

        >>> wr = HostOrServiceConditionSchema(use_regex="always")  # with regex
        >>> rv = wr.load({
        ...     'match_on': ['abc$', 'xyz$'],
        ...     'operator': 'one_of',
        ... })
        >>> rv
        [{'$regex': 'abc$'}, {'$regex': 'xyz$'}]

        >>> wr.dump(rv)
        {'match_on': ['abc$', 'xyz$'], 'operator': 'one_of'}

        >>> wadr = HostOrServiceConditionSchema(use_regex="adaptive")  #  when prefixed with ~
        >>> rv = wadr.load({
        ...     'match_on': ['~(heute|gestern)$', 'heute', '~[v]orgestern$'],
        ...     'operator': 'one_of',
        ... })
        >>> rv
        [{'$regex': '^(heute|gestern)$'}, 'heute', {'$regex': '^[v]orgestern$'}]

        >>> wadr.dump(rv)
        {'match_on': ['~(heute|gestern)$', 'heute', '~[v]orgestern$'], 'operator': 'one_of'}

    """

    def __init__(
        self,
        *,
        only: typing.Optional[types.StrSequenceOrSet] = None,
        exclude: types.StrSequenceOrSet = (),
        many: bool = False,
        context: typing.Optional[typing.Dict] = None,
        load_only: types.StrSequenceOrSet = (),
        dump_only: types.StrSequenceOrSet = (),
        partial: typing.Union[bool, types.StrSequenceOrSet] = False,
        unknown: typing.Optional[str] = None,
        use_regex: typing.Literal["always", "never", "adaptive"] = "adaptive",
    ):
        self.use_regex = use_regex
        super().__init__(
            only=only,
            exclude=exclude,
            many=many,
            context=context,
            load_only=load_only,
            dump_only=dump_only,
            partial=partial,
            unknown=unknown,
        )

    cast_to_dict = True

    match_on = fields.List(
        fields.String(),
        description="A list of string matching regular expressions.",
    )
    operator = fields.String(
        enum=["one_of", "none_of"],
        description=(
            "How the hosts or services should be matched.\n"
            " * one_of - will match if any of the hosts or services is matched\n"
            " * none_of - will match if none of the hosts are matched. In other words: will match"
            " all hosts or services which are not specified.\n"
        ),
    )

    @pre_dump(pass_many=False)
    def convert_to_api(
        self,
        data: HostOrServiceConditions,
        many: bool = False,
        partial: bool = False,
    ) -> typing.Optional[ApiMatchExpression]:
        if not data:
            return None

        def _remove_regex_dict(_entry):
            if isinstance(_entry, dict) and "$regex" in _entry:
                regex = _entry["$regex"]
                if self.use_regex == "adaptive" and regex:
                    if regex[0] == "^":
                        return "~" + regex[1:]

                    return "~" + regex

                return regex

            if isinstance(_entry, str):
                return _entry

            raise ValidationError(f"Unknown format: {_entry}")

        def _ensure_list(_entry) -> typing.List[str]:
            if isinstance(_entry, list):
                return _entry

            return [_entry]

        rv: ApiMatchExpression = {
            "match_on": [],
            "operator": "one_of",
        }
        if isinstance(data, dict):
            try:
                entries = _ensure_list(_unpack_value(data))
            except ValueError as exc:
                raise ValidationError(str(exc)) from exc
            rv["operator"] = _unpack_operator(data)
        else:
            entries = _ensure_list(data)

        rv["match_on"] = [_remove_regex_dict(entry) for entry in entries]

        return rv

    @post_load(pass_many=False)
    def convert_to_checkmk(
        self,
        data: ApiMatchExpression,
        many: bool = False,
        partial: bool = False,
    ) -> HostOrServiceConditions:
        def _wrap_entry(_entry):
            if _entry[0] == "~":
                return {"$regex": f"^{_entry[1:]}"}

            return _entry

        match_on: HostOrServiceConditionsSimple
        if self.use_regex == "always":
            match_on = [{"$regex": entry} for entry in data["match_on"]]
        elif self.use_regex == "adaptive":
            match_on = [_wrap_entry(entry) for entry in data["match_on"]]
        elif isinstance(data["match_on"], list):
            match_on = typing.cast(HostOrServiceConditionsSimple, data["match_on"])
        else:
            raise ValidationError(f"Unknown type: {data['match_on']!r}.")

        if data["operator"] == "one_of":  # pylint: disable=no-else-return
            return match_on
        elif data["operator"] == "none_of":
            return {"$nor": match_on}
        else:
            raise ValidationError(f"Unknown match type: {data['operator']}")
Example #20
0
 def openapi_field(self) -> fields.Field:
     return fields.List(
         fields.String(),
         description="Attributes which are locked.",
     )
Example #21
0
class ConcreteTimeRangeActive(BaseSchema):
    day = fields.String(
        description="The day for which the time ranges are specified",
        pattern=f"{'|'.join(weekday_ids())}",
    )
    time_ranges = fields.List(fields.Nested(ConcreteTimeRange))
Example #22
0
 def openapi_field(self) -> fields.Field:
     return fields.List(
         fields.String(validate=fields.ValidateIPv6()),
         description="A list of IPv6 addresses.",
     )
Example #23
0
"""
from cmk.utils.livestatus_helpers.expressions import And
from cmk.utils.livestatus_helpers.queries import Query
from cmk.utils.livestatus_helpers.tables import Services

from cmk.gui import fields, sites
from cmk.gui.plugins.openapi.restful_objects import constructors, Endpoint, response_schemas
from cmk.gui.plugins.openapi.restful_objects.constructors import object_action_href
from cmk.gui.plugins.openapi.restful_objects.parameters import HOST_NAME, OPTIONAL_HOST_NAME
from cmk.gui.plugins.openapi.utils import problem

PARAMETERS = [{
    'sites':
    fields.List(
        fields.SiteField(),
        description="Restrict the query to this particular site.",
        missing=list,
    ),
    'query':
    fields.query_field(
        Services,
        required=False,
        example='{"op": "=", "left": "host_name", "right": "example.com"}',
    ),
    'columns':
    fields.column_field(
        Services,
        mandatory=[
            Services.host_name,
            Services.description,
        ],
Example #24
0
 def openapi_field(self) -> fields.Field:
     return fields.List(
         fields.HostField(should_exist=True),
         description="A list of parents of this host.",
     )