Source Docs

auslib.AUS

auslib.blobs

auslib.config

class auslib.config.AUSConfig(filename)
getCaches()
getDburi()
getDomainAllowlist()
getLogLevel()
getLogfile()
loglevels = {'CRITICAL': 50, 'DEBUG': 10, 'ERROR': 40, 'INFO': 20, 'WARNING': 30}
required_options = {'database': ['dburi'], 'logging': ['logfile']}
validate()
class auslib.config.AdminConfig(filename)
getPageTitle()
getSecretKey()
getSystemAccounts()
required_options = {'app': ['secret_key'], 'database': ['dburi'], 'logging': ['logfile'], 'site-specific': ['page_title']}
class auslib.config.ClientConfig(filename)
getSpecialForceHosts()

auslib.db

auslib.dockerflow

auslib.errors

exception auslib.errors.BadDataError

Raised when a client sends data that appears to be invalid.

exception auslib.errors.BlobValidationError(message, errors, *args, **kwargs)
exception auslib.errors.PermissionDeniedError
exception auslib.errors.ReadOnlyError

Raised when a release marked as read-only is attempted to be changed.

exception auslib.errors.SignoffRequiredError

Raised when someone attempts to directly modify an object that requires signoff.

auslib.global_state

auslib.log

class auslib.log.BalrogLogger(name, level=0)
makeRecord(name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)

A factory method which can be overridden in subclasses to create specialized LogRecords.

class auslib.log.JsonLogFormatter(fmt=None, datefmt=None, logger_name='Balrog')

Log formatter that outputs machine-readable json.

This log formatter outputs JSON format messages that are compatible with Mozilla’s standard heka-based log aggregation infrastructure.

See also: https://mana.mozilla.org/wiki/display/CLOUDSERVICES/Logging+Standard https://mana.mozilla.org/wiki/pages/viewpage.action?pageId=42895640

Adapted from: https://github.com/mozilla-services/mozservices/blob/master/mozsvc/util.py#L106

DEFAULT_SYSLOG_LEVEL = 200
EXCLUDED_LOGRECORD_ATTRS = {'args', 'asctime', 'created', 'exc_info', 'exc_text', 'filename', 'funcName', 'levelname', 'levelno', 'lineno', 'message', 'module', 'msecs', 'msg', 'name', 'pathname', 'process', 'processName', 'relativeCreated', 'stack_info', 'thread', 'threadName'}
LOGGING_FORMAT_VERSION = '2.0'
SYSLOG_LEVEL_MAP = {10: 100, 20: 200, 30: 400, 40: 500, 50: 600}
format(record)

Map from Python LogRecord attributes to JSON log format fields

auslib.log.configure_logging(stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, formatter=<class 'auslib.log.JsonLogFormatter'>, format_='%(asctime)s - %(levelname)s - PID: %(process)s - Request: %(requestid)s - %(name)s.%(funcName)s#%(lineno)s: %(message)s', level=10)
auslib.log.safer_format_traceback(exc_typ, exc_val, exc_tb)

Format an exception traceback into safer string. We don’t want to let users write arbitrary data into our logfiles, which could happen if they e.g. managed to trigger a ValueError with a carefully-crafted payload. This function formats the traceback using “%r” for the actual exception data, which passes it through repr() so that any special chars are safely escaped.

auslib.util

auslib.util.autograph.make_hash(content)
auslib.util.autograph.sign_hash(autograph_uri, keyid, id, key, hash)
auslib.util.comparison.either_eq(value, operand)

The order of eq matters with GlobVersion; test both orders.

Nightly: because StrictVersion also compares self.prerelease,

StrictVersion(“70.0a1”) != GlobVersion(“70.*”), but GlobVersion(“70.*”) == StrictVersion(“70.0a1”)

dot-0: because StrictVersion can drop the trailing .0,

GlobVersion(“80.0.*”) != StrictVersion(“80.0.0”), but StrictVersion(“80.0.0”) == GlobVersion(“80.0.*”)

Because of this, let’s test eq in both directions.

auslib.util.comparison.get_op(pattern)
auslib.util.comparison.has_operator(value)
auslib.util.comparison.int_compare(value, compstr)

Do a int comparison of a bare int with another, which may carry a comparison operator. eg int_compare(1, ‘>2’) is False

auslib.util.comparison.string_compare(value, compstr)

Do a string comparison of a bare string with another, which may carry a comparison operator. eg string_compare(‘a’, ‘>b’) is False

auslib.util.comparison.strip_operator(value)
auslib.util.comparison.version_compare(value, compstr, versionClass=<function MozillaVersion>)

Do a version comparison between a string (representing a version), with another which may carry a comparison operator. A true version comparison is done. eg version_compare(‘1.1’, ‘>1.0’) is True

auslib.util.hashes.getHashLen(hashName)
auslib.util.jsonschema_validators.ascii_validator(field_value)
auslib.util.jsonschema_validators.background_rate_validator(field_value)
auslib.util.jsonschema_validators.data_version_validator(field_value)
auslib.util.jsonschema_validators.integer_and_range_validator(field_name, field_value, min_val=None, max_val=None)
auslib.util.jsonschema_validators.json_field_validator(field_value)
auslib.util.jsonschema_validators.operator_validator(field_value)
auslib.util.jsonschema_validators.priority_validator(field_value)
auslib.util.jsonschema_validators.rule_id_validator(field_value)
auslib.util.jsonschema_validators.sc_when_validator(field_value)
auslib.util.jsonschema_validators.signoffs_required_validator(field_value)
auslib.util.jsonschema_validators.telemetry_uptake_validator(field_value)
auslib.util.jsonschema_validators.version_validator(field_value)
auslib.util.rulematching.matchBoolean(ruleValue, queryValue)

As with all other columns, if the value isn’t present in the Rule, the Rule matches. Unlike other columns, the non-existence of a boolean field in the updateQuery evaluates to False, so we need to handle True, False, and None explicitly. Note that None in the updateQuery is treated as “unknown”, and will cause any Rule without an explicit value for the field to match. The full truth table is:

rule | query | matches?
  F      0        Y
  F      1        N
  F     null      N
  T      0        N
  T      1        Y
  T     null      N
null     0        Y
null     1        Y
null    null      Y

Additional context in https://bugzilla.mozilla.org/show_bug.cgi?id=1386756

auslib.util.rulematching.matchBuildID(ruleBuildID, queryBuildID)

Decides whether a buildID from the rules matches an incoming one. If the ruleBuildID is null, we match any queryBuildID. If it’s not null, we must either match exactly, or match with a camparison operator.

auslib.util.rulematching.matchChannel(ruleChannel, queryChannel, fallbackChannel)

Decides whether a channel from the rules matches an incoming one. If the ruleChannel is null, we match any queryChannel. We also match if the channels match exactly, or match after wildcards in ruleChannel are resolved. Channels may have a fallback specified, too, so we must check if the fallback version of the queryChannel matches the ruleChannel.

auslib.util.rulematching.matchCsv(csvString, queryString, substring=True)

Decides whether a column from a rule matches an incoming one. Some columns in a rule may specify multiple values delimited by a comma. Once split we do a full or substring match against the query string. Because we support substring matches, there’s no need to support globbing as well.

auslib.util.rulematching.matchLocale(ruleLocales, queryLocale)

Decides if a comma seperated list of locales in a rule matches an update request

auslib.util.rulematching.matchMemory(ruleMemory, queryMemory)

Decides whether a memory value from the rules matches an incoming one. If the ruleMemory is null, we match any queryMemory. If it’s not null, we must either match exactly, or match with a comparison operator.

auslib.util.rulematching.matchRegex(foo, bar)
auslib.util.rulematching.matchSimpleExpression(ruleString, queryString, substring=True)

Decides whether a column from a rule matches an incoming one using simplified boolean logic. Only two operators are supported: ‘&&’ (and), ‘,’ (or). A rule like ‘AMD,SSE’ will match incoming rules that contain either ‘AMD’ or ‘SSE’. A rule like ‘AMD&&SSE’ will only match incoming rules that contain both ‘AMD’ and ‘SSE’. This function can do substring matching or full string matching. When doing substring matching, a rule specifying ‘AMD,Windows 10’ WILL match an incoming rule such as ‘Windows 10.1.2’. When doing full string matching, a rule specifying ‘AMD,SSE’ will NOT match an incoming rule that contains ‘SSE3’, but WILL match an incoming rule that contains either ‘AMD’ or ‘SSE3’.

auslib.util.rulematching.matchSimpleExpressionSubRule(subRuleString, queryString, substring)

Performs the actual logical ‘AND’ operation on a rule as well as partial/full string matching for each section of a rule. If all parts of the subRuleString match the queryString, then we have successfully resolved the logical ‘AND’ operation and return True. Partial matching makes use of Python’s “<substring> in <string>” functionality, giving us the ability for an incoming rule to match only a substring of a rule. Full matching makes use of Python’s “<string> in <list>” functionality, giving us the ability for an incoming rule to exactly match the whole rule. Currently, incoming rules are comma-separated strings.

auslib.util.rulematching.matchVersion(ruleVersion, queryVersion, versionClass=<function MozillaVersion>)

Decides whether a version from the rules matches an incoming version. If the ruleVersion is null, we match any queryVersion. If it’s not null, we must either match exactly, or match a comparison operator.

auslib.util.thirdparty.extendsyspath()
auslib.util.timestamp.getMillisecondTimestamp()
class auslib.util.versions.AncientMozillaVersion(vstring=None)

A version class that is slightly less restrictive than StrictVersion. Instead of just allowing “a” or “b” as prerelease tags, it allows any alpha. This allows us to support the once-shipped “3.6.3plugin1” and similar versions. It also supports versions w.x.y.z by transmuting to w.x.z, which is useful for versions like 1.5.0.x and 2.0.0.y

version_re = re.compile('^(\\d+) \\. (\\d+) \\. \\d (\\. (\\d+))\n                                ([a-zA-Z]+(\\d+))?$', re.VERBOSE)
class auslib.util.versions.GlobVersion(vstring=None)

A version class that supports Firefox versions 5.0 and up, which ends with a glob *. Not really a StrictVersion at all, but it needs to be to compare with other MozillaVersions.

parse(vstring)
prerelease = None
version_re = re.compile('^(\\d+) \\. (\\d+\\.\\*|\\*)$', re.VERBOSE)
class auslib.util.versions.GlobVersionTuple(iterable=(), /)
class auslib.util.versions.LooseVersion(vstring=None)
component_re = re.compile('(\\d+ | [a-z]+ | \\.)', re.VERBOSE)
parse(vstring)
class auslib.util.versions.ModernMozillaVersion(vstring=None)

A version class that is slightly less restrictive than StrictVersion. Instead of just allowing “a” or “b” as prerelease tags, it allows any alpha. This allows us to support the once-shipped “3.6.3plugin1” and similar versions.

version_re = re.compile('^(\\d+) \\. (\\d+) (\\. (\\d+))?\n                                ([a-zA-Z]+(\\d+))?$', re.VERBOSE)
auslib.util.versions.MozillaVersion(version)
class auslib.util.versions.PinVersion(vstring=None)

A version class that supports application update pins. These are used for pinning an install to a particular version (see Bug 1529943). Update pins are formatted like ‘X.’ or ‘X.Y.’, where X is the major version and Y is the minor version.

Note that unlike the other version types in this file, this one does not derive from StrictVersion. This is because this is not a strict version and it should not be treated as such. ‘100.’, for example, is equal to ‘100.0.0’ and ‘100.99.99’. It is less than ‘101.0.0’ and greater than ‘99.99.99’. Deriving from StrictVersion would allow StrictVersion’s operators to operate on PinVersions, which would not function correctly. Despite these differences, the PinVersion interface is identical to that of StrictVersion and PinVersions can be compared to StrictVersions because PinVersion provides the necessary operators.

This class is very similar to GlobVersion, but needs to be separate. GlobVersion comparisons must be made via auslib.util.comparison.version_compare, which only supports equality checking for GlobVersion.

parse(vstring)
version_re = re.compile('^(\\d+) \\. ((\\d+) \\.)?$', re.VERBOSE)
class auslib.util.versions.PostModernMozillaVersion(vstring=None)

A version class that supports Firefox versions 5.0 and up, which may have “a1” but not “b2” tags in them

version_re = re.compile('^(\\d+) \\. (\\d+) (\\. (\\d+))?\n                                (a(\\d+))?$', re.VERBOSE)
class auslib.util.versions.StrictVersion(vstring=None)
parse(vstring)
version_re = re.compile('^(\\d+) \\. (\\d+) (\\. (\\d+))? ([ab](\\d+))?$', re.VERBOSE|re.ASCII)
class auslib.util.versions.Version(vstring=None)
parse(vstring)
auslib.util.versions.decrement_version(version)

Decrements a version to its ‘previous’ version by subtracting one from its last part. If the last part is 0, it is changed to 999, and the second last part is subtracted by one. This is repeated until subtraction happens or we run out of parts.

auslib.util.versions.get_version_class(product)
auslib.util.versions.get_version_parts(version)
auslib.util.versions.increment_version(version)

Increments a version to its ‘next’ version by adding one to the last part of the version.

auslib.web.admin

auslib.web.admin.views.problem.problem(status, title, detail, type=None, instance=None, headers=None, ext=None)

Returns a Problem Details error response.

Method is an exact copy of connexion.problem method except the returned Response object is of type flask.Response) instead of ConnexionResponse.

Reason: using connexion.problem results in TypeError: ‘ConnexionResponse’ object is not callable, sporadically in some APIs. Hence using flask.Response.

Parameters:
  • status (int) – The HTTP status code generated by the origin server for this occurrence of the problem.

  • title (str) – A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localisation.

  • detail (str) – An human readable explanation specific to this occurrence of the problem.

  • type – An absolute URI that identifies the problem type. When dereferenced, it SHOULD provide human-readable documentation for the problem type (e.g., using HTML). When this member is not present its value is assumed to be “about:blank”.

  • instance (str) – An absolute URI that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.

  • headers (dict | None) – HTTP headers to include in the response

  • ext (dict | None) – Extension members to include in the body

Type:

type: str

Returns:

error response

Return type:

Response

class auslib.web.admin.views.validators.BalrogRequestBodyValidator(schema, consumes, api, is_null_value_valid=False, validator=None, strict_validation=False)
validate_schema(data: dict, url: AnyStr) Optional[ConnexionResponse]

This function is largely based on https://github.com/zalando/connexion/blob/master/connexion/decorators/validation.py and should largely be kept in line with it.

auslib.web.admin.views.validators.is_when_present_and_in_past_validator(what)

Validates if scheduled_change_time value i.e. ‘when’ field value is present in input dictionary/object and if its value is in past or not

auslib.web.common

class auslib.web.common.history.HistoryHelper(hist_table, order_by, get_object_callback, history_filters_callback, process_revisions_callback=None, obj_not_found_msg='Requested object does not exist')
get_history(response_key='revisions')
auslib.web.common.history.annotateRevisionDifferences(revisions)
auslib.web.common.history.get_input_dict()

auslib.web.public