service¶
Service module.
- exception spicerack.service.DiscoveryRecordNotFoundError[source]¶
Bases:
ServiceError
Exception class raised when a DNS Discovery record is not found by name or there is none.
- exception spicerack.service.DiscoveryStateError[source]¶
Bases:
ServiceError
Exception class raised when a dns discovery record does not correspond to its conftool state.
- exception spicerack.service.ServiceError[source]¶
Bases:
SpicerackError
Generic exception class for errors in the service module.
- exception spicerack.service.ServiceNotFoundError[source]¶
Bases:
ServiceError
Exception class raised when a service is not found.
- exception spicerack.service.TooManyDiscoveryRecordsError[source]¶
Bases:
ServiceError
Exception class raised when more than one DNS Discovery record is present but not name was specified.
- class spicerack.service.Catalog(catalog: dict, *, alertmanager: spicerack.alertmanager.Alertmanager, confctl: spicerack.confctl.ConftoolEntity, authdns_servers: dict[str, str], dry_run: bool = True)[source]¶
Bases:
object
Class to represent the service catalog of Puppet's hierdata
service::catalog
.The catalog behaves like an Iterator, so it can be iterated in list-comprehension and similar contructs. It supports also
len()
, to quickly know how many services are loaded in the catalog.Examples
Get all service that are present in a given datacenter:
>>> esams = [service for service in catalog if "esams" in service.sites]
See how many services are configured:
>>> num_services = len(catalog)
Initialize the instance.
- Parameters:
catalog (
dict
) -- the content of Puppet'shieradata/common/service.yaml
.alertmanager (
spicerack.alertmanager.Alertmanager
) -- the alertmanager instance to interact with.confctl (
spicerack.confctl.ConftoolEntity
) -- the instance to interact with confctl.authdns_servers (
dict
[str
,str
]) -- a dictionary where keys are the hostnames and values are the IPs of the authoritative nameservers to be used.dry_run (
bool
, default:True
) -- whether this is a DRY-RUN.
- get(name: str) spicerack.service.Service [source]¶
Get a single service by name.
Examples
Get a specific service:
>>> service = catalog.get("service_name")
- Parameters:
name (
str
) -- the service name.- Raises:
spicerack.service.ServiceNotFoundError -- if the service is not found.
- Return type:
- class spicerack.service.Service(name: str, description: str, encryption: bool, ip: spicerack.service.ServiceIPs, port: int, sites: list[str], state: str, _dry_run: bool, _alertmanager: spicerack.alertmanager.AlertmanagerHosts, aliases: list[str] = <factory>, discovery: spicerack.service.ServiceDiscovery | None = None, httpbb_dir: str = '', lvs: spicerack.service.ServiceLVS | None = None, monitoring: spicerack.service.ServiceMonitoring | None = None, page: bool = True, probes: list[dict] = <factory>, public_aliases: list[str] = <factory>, public_endpoint: str = '', role: str = '') None [source]¶
Bases:
object
Class to represent a service as defined in Puppet's
service::catalog
hieradata.See also
Puppet's
modules/wmflib/types/service.pp
.- Parameters:
name (
str
) -- the service name.description (
str
) -- the service description.encryption (
bool
) -- whether TLS encryption is enabled or not on the service.ip (
spicerack.service.ServiceIPs
) -- the instance that represents all the service IPs.port (
int
) -- the port the service listen on.sites (
list
[str
]) -- the list of datacenters where the service is configured.state (
str
) -- the production state of the service (e.g.lvs_setup
)._alertmanager (
spicerack.alertmanager.AlertmanagerHosts
) -- the AlertmanagerHosts instance to perform downtime.aliases (
list
[str
], default:<factory>
) -- a list of aliases names for the service.discovery (
typing.Optional
[spicerack.service.ServiceDiscovery
], default:None
) -- the collection ofspicerack.service.ServiceDiscoveryRecord
instances reprensenting the DNS Discovery capabilities of the service.lvs (
typing.Optional
[spicerack.service.ServiceLVS
], default:None
) -- the load balancer configuration.monitoring (
typing.Optional
[spicerack.service.ServiceMonitoring
], default:None
) -- the service monitoring configuration.page (
bool
, default:True
) -- whether the monitoring for this service does page or not.probes (
list
[dict
], default:<factory>
) -- a list of probe dictionaries with all the parameters necessary to define the probes for this service.public_aliases (
list
[str
], default:<factory>
) -- the list of public aliases set for this service.public_endpoint (
str
, default:''
) -- the name of the public endpoint if present, empty string otherwise.role (
str
, default:''
) -- the service role name in Puppet if present, empty string otherwise.
- check_dns_state(ip_per_dc_map: dict[str, ipaddress.IPv4Address | ipaddress.IPv6Address], record_name: str = '', tries: int = 15) None [source]¶
Checks the state of dns discovery is consistent.
Checks that a discovery record state on the dns servers corresponds to the state in the conftool discovery backend.
- Parameters:
ip_per_dc_map (
dict
[str
,typing.Union
[ipaddress.IPv4Address
,ipaddress.IPv6Address
]]) -- mapping of datacenter -> client IP to use.record_name (
str
, default:''
) -- the discovery record name to inspect. If left empty, it will pick up the only discovery record.tries (
int
, default:15
) -- the number of retries to attempt before failing.
- Raises:
ValueError -- on invalid tries value.
spicerack.service.DiscoveryStateError -- if the two states don't correspond.
spicerack.service.DiscoveryRecordNotFoundError -- if there are no records at all or the record with the given
name can't be found. --
spicerack.service.TooManyDiscoveryRecordsError -- if the name is an empty string and there is more than one
record. --
- Return type:
- downtime(site: str, reason: spicerack.administrative.Reason, *, duration: datetime.timedelta = datetime.timedelta(seconds=14400)) str [source]¶
Downtime the service on the given site in Alertmanager and return its ID.
- Parameters:
site (
str
) -- the datacenter where to silence the service.reason (
spicerack.administrative.Reason
) -- the silence reason.duration (
datetime.timedelta
, default:datetime.timedelta(seconds=14400)
) -- how long to silence for.
- Raises:
spicerack.service.ServiceError -- if the service is not present in the given datacenter.
- Return type:
- downtimed(site: str, reason: spicerack.administrative.Reason, *, duration: datetime.timedelta = datetime.timedelta(seconds=14400), remove_on_error: bool = False) collections.abc.Iterator[None] [source]¶
Context manager to perform actions while the service is downtimed in the given site in Alertmanager.
- Parameters:
site (
str
) -- the datacenter where to silence the service.reason (
spicerack.administrative.Reason
) -- the silence reason.duration (
datetime.timedelta
, default:datetime.timedelta(seconds=14400)
) -- how long to silence for.remove_on_error (
bool
, default:False
) -- should the downtime be removed even if an exception was raised.
- Raises:
spicerack.service.ServiceError -- if the service is not present in the given datacenter.
- Return type:
- class spicerack.service.ServiceDiscovery(records: collections.abc.Sequence[spicerack.service.ServiceDiscoveryRecord])[source]¶
Bases:
Iterable
Represents the service Discovery records collection as list-like object with helper methods.
The discovery behaves like an Iterator, so it can be iterated in list-comprehension and similar contructs. It supports also
len()
, to quickly know how many records are configured for the service.Initialize the instance with the records.
- Parameters:
records (
collections.abc.Sequence
[spicerack.service.ServiceDiscoveryRecord
]) -- the DNS Discovery records.
- depool(site: str, *, name: str = '') None [source]¶
Depool the service from the given site in DNS Discovery.
- Parameters:
- Raises:
spicerack.service.DiscoveryRecordNotFoundError -- if there are no records at all or the record with the given
name can't be found. --
spicerack.service.TooManyDiscoveryRecordsError -- if the name is an empty string and there is more than one
record. --
- Return type:
- depooled(site: str, *, name: str = '', repool_on_error: bool = False) collections.abc.Iterator[None] [source]¶
Context manager to act while the service is depooled from the given site in DNS Discovery.
It will not repool the service on the given site if any exception is raised within the context manager context, unless
repool_on_error
is set toTrue
.- Parameters:
- Yields:
None -- it just gives back control to the caller.
- Raises:
spicerack.service.DiscoveryRecordNotFoundError -- if there are no records at all or the record with the given
name can't be found. --
spicerack.service.TooManyDiscoveryRecordsError -- if the name is an empty string and there is more than one
record. --
- Return type:
- get(name: str = '') spicerack.service.ServiceDiscoveryRecord [source]¶
Return the DNS Discovery record for the given name, raise an exception if not found.
- Parameters:
name (
str
, default:''
) -- the dnsdic name of the DNS Discovery record. If set to an empty string, and the service has only one service, it will return that one.- Raises:
spicerack.service.DiscoveryRecordNotFoundError -- if there are no records at all or the record with the given
name can't be found. --
spicerack.service.TooManyDiscoveryRecordsError -- if the name is an empty string and there is more than one
record. --
- Return type:
- pool(site: str, *, name: str = '') None [source]¶
Pool the service to the given site in DNS Discovery.
- Parameters:
- Raises:
spicerack.service.DiscoveryRecordNotFoundError -- if there are no records at all or the record with the given
name can't be found. --
spicerack.service.TooManyDiscoveryRecordsError -- if the name is an empty string and there is more than one
record. --
- Return type:
- class spicerack.service.ServiceDiscoveryRecord(active_active: bool, dnsdisc: str, instance: spicerack.dnsdisc.Discovery) None [source]¶
Bases:
object
Represents the DNS Discovery attributes of the service.
See also
Puppet's
modules/wmflib/types/service/discovery.pp
.- Parameters:
active_active (
bool
) --True
if the service is active/active in DNS Discovery.dnsdisc (
str
) -- the name used in conftool for the discovery record.instance (
spicerack.dnsdisc.Discovery
) -- the DNS Discovery intance to operate on the service.
- check_service_ips(service_ips: spicerack.service.ServiceIPs, ip_per_dc_map: dict[str, ipaddress.IPv4Address | ipaddress.IPv6Address]) None [source]¶
Check the DNS records.
For every datacenter the service is present in, we check that: * If the datacenter is pooled, resolving the name from a client in that datacenter returns the local IP of the service * If it's depooled, resolving the name from a client in that datacenter returns a non-local ip for the service.
The most important function of this check is to ensure the etcd change has been propagated before we cleare the dns recursor caches.
- Parameters:
service_ips (
spicerack.service.ServiceIPs
) -- An instance of service IPs related to this record.ip_per_dc_map (
dict
[str
,typing.Union
[ipaddress.IPv4Address
,ipaddress.IPv6Address
]]) -- map of client IPs from the different datacenters.
- Raises:
spicerack.serviceDiscoveryStateError -- on failure.
- Return type:
- class spicerack.service.ServiceIPs(data: dict[str, dict[str, str]]) None [source]¶
Bases:
object
Represent the service IPs.
See also
Puppet's
modules/wmflib/types/service/ipblock.pp
.- Parameters:
data (
dict
[str
,dict
[str
,str
]]) -- a dictionary representing the service IPs data as defined inservice::catalog
.
- get(site: str, label: str = 'default') ipaddress.IPv4Address | ipaddress.IPv6Address | None [source]¶
Get the IP for a given datacenter and optional label.
- Parameters:
- Returns:
if the matched IP is an IPv4. ipaddress.IPv6Address: if the matched IP is an IPv6. None: if there is no IP matching the criteria.
- Return type:
- property all: list[IPv4Address | IPv6Address]¶
Return all the service IPs.
- class spicerack.service.ServiceLVS(conftool: spicerack.service.ServiceLVSConftool, depool_threshold: str, enabled: bool, lvs_class: str, monitors: dict[str, dict] | None = None, bgp: bool = True, protocol: str = 'tcp', scheduler: str = 'wrr', ipip_encapsulation: bool = False) None [source]¶
Bases:
object
Represent the load balancer configuration for the service.
See also
Puppet's
modules/wmflib/types/service/lvs.pp
.- Parameters:
conftool (
spicerack.service.ServiceLVSConftool
) -- the conftool configuration for the service.depool_threshold (
str
) -- the percentage of the cluster that Pybal will keep pooled anyway on failure.enabled (
bool
) -- whether the service is enabled on the load balancers.lvs_class (
str
) -- the traffic class of the service (e.g.low-traffic
).monitors (
typing.Optional
[dict
[str
,dict
]], default:None
) -- a dictionary of Pybal monitors configured for the service.bgp (
bool
, default:True
) -- whether Pybal advertise the service via BGP or not.protocol (
str
, default:'tcp'
) -- the Internet protocol of the service.scheduler (
str
, default:'wrr'
) -- the IPVS scheduler used for the service.ipip_encapsulation (
bool
, default:False
) -- Whether the realservers receive traffic from the load balancers using IPIP encapsulation
- class spicerack.service.ServiceLVSConftool(cluster: str, service: str) None [source]¶
Bases:
object
Represent the conftool configuration for the service for the load balancers.
- class spicerack.service.ServiceMonitoring(check_command: str, sites: spicerack.service.ServiceMonitoringHostnames, contact_group: str = '', notes_url: str = '') None [source]¶
Bases:
object
Represent the monitoring configuration for the service.
See also
Puppet's
modules/wmflib/types/service/monitoring.pp
.- Parameters:
check_command (
str
) -- the Icinga check command used to monitor the service.sites (
spicerack.service.ServiceMonitoringHostnames
) -- the FQDNs used to monitor the service in each datacenter.contact_group (
str
, default:''
) -- the name of the Icinga contact group used for the service.notes_url (
str
, default:''
) -- the Icinga notes URL pointing to the service runbook.
- class spicerack.service.ServiceMonitoringHostnames(data: dict[str, dict[str, str]]) None [source]¶
Bases:
object
Represent the Icinga hostnames or FQDNs used to monitor the service in each datacenter.
See also
Puppet's
modules/wmflib/types/service/monitoring.pp
.