This is an automated email from the ASF dual-hosted git repository. ocket8888 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficcontrol-trafficops-types.git
commit cab0353fc63a7fe23a93d5ae62b99bf6e7826922 Author: ocket8888 <[email protected]> AuthorDate: Sat Apr 23 01:44:14 2022 -0600 Add the first batch of source files (copied in from TPv2/the docs overview pages/"API Next" document) --- src/about.ts | 17 ++ src/acme.ts | 10 + src/alert.ts | 30 ++ src/cache.group.ts | 157 ++++++++++ src/cdn.ts | 25 ++ src/delivery.service.ts | 756 +++++++++++++++++++++++++++++++++++++++++++++++ src/division.ts | 40 +++ src/index.ts | 75 +++++ src/invalidation.ts | 65 ++++ src/iso.ts | 44 +++ src/login.ts | 47 +++ src/logs.ts | 66 +++++ src/parameter.ts | 36 +++ src/physical.location.ts | 86 ++++++ src/plugin.ts | 10 + src/profile.ts | 96 ++++++ src/server.ts | 301 +++++++++++++++++++ src/stats.ts | 67 +++++ src/status.ts | 25 ++ src/type.ts | 29 ++ src/user.ts | 232 +++++++++++++++ src/vault.ts | 19 ++ 22 files changed, 2233 insertions(+) diff --git a/src/about.ts b/src/about.ts new file mode 100644 index 0000000..b7c4e1e --- /dev/null +++ b/src/about.ts @@ -0,0 +1,17 @@ +/** Represents the response to a request made to the /about API endpoint. */ +export interface About { + commitHash?: string; + commits?: string; + goVersion?: string; + name?: string; + release: string; + /* eslint-disable @typescript-eslint/naming-convention */ + RPMVersion?: string; + Version?: string; + /* eslint-enable @typescript-eslint/naming-convention */ +} + +/** SystemInfo represents a response from /system/info. */ +export interface SystemInfo { + [parameter: string]: string; +} diff --git a/src/acme.ts b/src/acme.ts new file mode 100644 index 0000000..c86ffa9 --- /dev/null +++ b/src/acme.ts @@ -0,0 +1,10 @@ +/** + * ACMEAccount represents an ACME account as required by and given in requests + * to and responses from /acme_accounts. + */ +export interface ACMEAccount { + email: string; + privateKey: string; + provider: string; + uri: string; +} diff --git a/src/alert.ts b/src/alert.ts new file mode 100644 index 0000000..943b266 --- /dev/null +++ b/src/alert.ts @@ -0,0 +1,30 @@ +/** The allowed/known "level"s of Traffic Ops API Alerts. */ +export const enum AlertLevel { + /** An error occurred, and the request could not be fulfilled. */ + ERROR = "error", + /** Informative alert, not indicative of success or failure. */ + INFO = "info", + /** The request succeeded, and the Alert text describes the action taken. */ + SUCCESS = "success", + /** The request may have succeeded, but the user should be aware of something. */ + WARNING = "warning" +} + +/** + * An Alert is some human-readable notification sent back from the Traffic Ops + * API for the user, in addition to a response object where applicable. + */ +export interface Alert { + level: AlertLevel; + text: string; +} + +/** + * Gets the text of any and all error-level Alerts. + * + * @param as Alerts to check for errors. + * @returns The `text` of each error-level Alert found in `as`. + */ +export function errors(as: Array<Alert>): Array<string> { + return as.filter(a=>a.level===AlertLevel.ERROR).map(a=>a.text); +} diff --git a/src/cache.group.ts b/src/cache.group.ts new file mode 100644 index 0000000..a121c60 --- /dev/null +++ b/src/cache.group.ts @@ -0,0 +1,157 @@ +/** Represents an ASN in an API response. */ +export interface ResponseASN { + asn: number; + cachegroup: string; + cachegroupId: number; + readonly id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; +} + +/** Represents an ASN in an API request. */ +export interface RequestASN { + asn: number; + cachegroupId: number; +} + +/** Represents, generically, an ASN in the context of a request or response. */ +export type ASN = RequestASN | ResponseASN; + +/** + * LocalizationMethod values are those allowed in the 'localizationMethods' of + * `CacheGroup`s. + */ +export const enum LocalizationMethod { + /** Coverage Zone file lookup. */ + CZ = "CZ", + /** Deep Coverage Zone file lookup. */ + DEEP_CZ = "DEEP_CZ", + /** Geographic database search. */ + GEO = "GEO" +} + +/** + * Converts a LocalizationMethod to a human-readable string. + * + * @param l The LocalizationMethod to convert. + * @returns A textual representation of 'l'. + */ +export function localizationMethodToString(l: LocalizationMethod): string { + switch (l) { + case LocalizationMethod.CZ: + return "Coverage Zone File"; + case LocalizationMethod.DEEP_CZ: + return "Deep Coverage Zone File"; + case LocalizationMethod.GEO: + return "Geo-IP Database"; + } +} + +/** + * Represents a Cache Group as required by the Traffic Ops API in requests. + */ +export interface RequestCacheGroup { + fallbacks?: Array<string> | null; + fallbackToClosest?: boolean | null; + /** + * Note that leaving latitude and longitude null or undefined **will break + * things**. + * + * See https://github.com/apache/trafficcontrol/issues/6378 + */ + latitude?: number | null; + localizationMethods?: Array<LocalizationMethod> | null; + /** + * Note that leaving latitude and longitude null or undefined **will break + * things**. + * + * See https://github.com/apache/trafficcontrol/issues/6378 + */ + longitude?: number | null; + name: string; + parentCacheGroupId?: number | null; + secondaryParentId?: number | null; + shortName: string; + typeId: number; +} + +/** + * The basic properties common to Cache Groups in all responses. + */ +interface ResponseCacheGroupBase { + fallbacks: Array<string>; + fallbackToClosest: boolean; + readonly id: number; + lastUpdated: Date; + latitude: number | null; + localizationMethods: Array<LocalizationMethod>; + longitude: number | null; + name: string; + shortName: string; + typeId: number; + typeName: string; +} + +/** + * A Cache Group with a parent. All related fields are guaranteed to be + * non-null. + */ +interface ResponseCacheGroupWithParent extends ResponseCacheGroupBase { + parentCacheGroupId: number; + parentCacheGroupName: string; +} + +/** + * A Cache Group with no parent. All related fields are guaranteed to be null. + */ +interface ResponseCacheGroupWithoutParent extends ResponseCacheGroupBase { + parentCacheGroupId: null; + parentCacheGroupName: null; +} + +/** + * A Cache Group with a secondary parent. All related fields are guaranteed to + * be non-null. + */ +interface ResponseCacheGroupWithSecondaryParent extends ResponseCacheGroupBase { + secondaryParentId: number; + secondaryParentName: string; +} + +/** + * A Cache Group without a secondary parent. All related fields are guaranteed + * to be null. + */ +interface ResponseCacheGroupWithoutSecondaryParent extends ResponseCacheGroupBase { + secondaryParentId: null; + secondaryParentName: null; +} + +/** A Cache Group with a parent but no secondary parent. */ +type ResponseCacheGroupWithParentButNotSecondary = ResponseCacheGroupWithParent & ResponseCacheGroupWithoutSecondaryParent; +/** A Cache Group with both a parent and a secondary parent. */ +type ResponseCacheGroupWithParentAndSecondary = ResponseCacheGroupWithParent & ResponseCacheGroupWithSecondaryParent; +/** A Cache Group with a secondary parent but no parent. */ +type ResponseCacheGroupWithSecondaryButNotParent = ResponseCacheGroupWithoutParent & ResponseCacheGroupWithSecondaryParent; +/** A Cache Group with neither a parent nor a secondary parent. */ +type ResponseCacheGroupWithoutParentOrSecondary = ResponseCacheGroupWithoutParent & ResponseCacheGroupWithoutSecondaryParent; + +/** + * Represents a Cache Group as returned by the Traffic Ops API in responses. + */ +export type ResponseCacheGroup = ResponseCacheGroupWithParentButNotSecondary | +ResponseCacheGroupWithParentAndSecondary | +ResponseCacheGroupWithSecondaryButNotParent | +ResponseCacheGroupWithoutParentOrSecondary; + +/** + * Represents a Cache Group. + * + * Refer to https://traffic-control-cdn.readthedocs.io/en/latest/overview/cache_groups.html + */ +export type CacheGroup = RequestCacheGroup | ResponseCacheGroup; diff --git a/src/cdn.ts b/src/cdn.ts new file mode 100644 index 0000000..c7d5220 --- /dev/null +++ b/src/cdn.ts @@ -0,0 +1,25 @@ +/** + * Represents a CDN as required by the Traffic Ops API in requests. + */ +export interface RequestCDN { + /** Whether or not DNSSEC is enabled within this CDN. */ + dnssecEnabled: boolean; + /** The Top-Level Domain within which the CDN operates. */ + domainName: string; + /** The name of the CDN. */ + name: string; +} + +/** + * Represents a CDN as returned by the Traffic Ops API in responses. + */ +export interface ResponseCDN { + dnssecEnabled: boolean; + domainName: string; + readonly id: number; + lastUpdated: Date; + name: string; +} + +/** Represents a CDN. */ +export type CDN = RequestCDN | ResponseCDN; diff --git a/src/delivery.service.ts b/src/delivery.service.ts new file mode 100644 index 0000000..7ebd6d0 --- /dev/null +++ b/src/delivery.service.ts @@ -0,0 +1,756 @@ +/** + * Represents the `geoLimit` field of a Delivery Service + */ +export const enum GeoLimit { + /** + * No geographic limiting is to be done. + */ + NONE = 0, + /** + * Only clients found in a Coverage Zone File may be permitted access. + */ + CZF_ONLY = 1, + /** + * Only clients found in a Coverage Zone File OR can be geo-located within a + * set of country codes may be permitted access. + */ + CZF_AND_COUNTRY_CODES = 2 +} + +/** + * Defines the supported Geograhic IP mapping database providers and their + * respective magic number identifiers. + */ +export const enum GeoProvider { + /** The standard database used for geo-location. */ + MAX_MIND = 0, + /** An alternative database with dubious support. */ + NEUSTAR = 1 +} + +/** + * Represents a single entry in a Delivery Service's `matchList` field. + */ +export interface DeliveryServiceMatch { + /** A regular expression matching on something depending on the 'type'. */ + pattern: string; + /** + * The number in the set of the expression, which has vague but incredibly + * important meaning. + */ + setNumber: number; + /** + * The type of match which determines how it's used. + */ + type: string; +} + +/** + * Represents the allowed routing protocols and their respective magic number + * identifiers. + */ +export const enum Protocol { + /** Serve HTTP traffic only. */ + HTTP = 0, + /** Serve HTTPS traffic only. */ + HTTPS = 1, + /** Serve both HTTPS and HTTP traffic. */ + HTTP_AND_HTTPS = 2, + /** Redirect HTTP requests to HTTPS URLs and serve HTTPS traffic normally. */ + HTTP_TO_HTTPS = 3 +} + +/** + * Converts Protocols to a textual representation. + * + * @param p The Protocol to convert. + * @returns A string representation of 'p', or 'UNKNOWN' if 'p' was unrecognized. + */ +export function protocolToString(p: Protocol): string { + switch (p) { + case Protocol.HTTP: + return "Serve only unsecured HTTP requests"; + case Protocol.HTTPS: + return "Serve only secured HTTPS requests"; + case Protocol.HTTP_AND_HTTPS: + return "Serve both unsecured HTTP requests and secured HTTPS requests"; + case Protocol.HTTP_TO_HTTPS: + return "Serve secured HTTPS requests normally, but redirect unsecured HTTP requests to use HTTPS"; + } +} + +/** + * Represents the allowed values of the `qstringIgnore` field of a + * `DeliveryService`. + */ +export const enum QStringHandling { + /** Use the query string in the cache key and pass in upstream requests. */ + USE = 0, + /** + * Don't use the query string in the cache key but do pass it in upstream + * requests. + */ + IGNORE = 1, + /** + * Neither use the query string in the cache key nor pass it in upstream + * requests. + */ + DROP = 2 +} + +/** + * Converts a QStringHandling to a textual representation. + * + * @param q The QStringHandling to convert. + * @returns A string representation of 'q'. + */ +export function qStringHandlingToString(q: QStringHandling): string { + switch (q) { + case QStringHandling.USE: + return "Use the query parameter string when deciding if a URL is cached, and pass it in upstream requests to the" + + " Mid-tier/origin"; + case QStringHandling.IGNORE: + return "Do not use the query parameter string when deciding if a URL is cached, but do pass it in upstream requests to the" + + " Mid-tier/origin"; + case QStringHandling.DROP: + return "Immediately strip URLs of their query parameter strings before checking cached objects or making upstream requests"; + } +} + +/** + * Represents the allowed values of the `rangeRequestHandling` field of a + * `Delivery Service`. + */ +export const enum RangeRequestHandling { + /** Range requests will not be cached. */ + NONE = 0, + /** + * The entire object will be fetched in the background to be cached, with + * the requested range served when it becomes available. + */ + BACKGROUND_FETCH = 1, + /** + * Cache range requests like any other request. + */ + CACHE_RANGE_REQUESTS = 2 +} + +/** + * Converts a RangeRequestHandling to a textual representation. + * + * @param r The RangeRequestHandling to convert. + * @returns A string representation of 'r'. + */ +export function rangeRequestHandlingToString(r: RangeRequestHandling): string { + switch (r) { + case RangeRequestHandling.NONE: + return "Do not cache Range requests"; + case RangeRequestHandling.BACKGROUND_FETCH: + return "Use the background_fetch plugin to serve Range requests while quietly caching the entire object"; + case RangeRequestHandling.CACHE_RANGE_REQUESTS: + return "Use the cache_range_requests plugin to directly cache object ranges"; + } +} + +/** + * The basic set of Delivery Service properties without being more specific as + * to the routing type, as they are given in requests. + */ +interface RequestDeliveryServiceBase { + /** Whether or not the Delivery Service is actively routed. */ + active: boolean; + /** Whether or not anonymization services are blocked. */ + anonymousBlockingEnabled?: number | null; + /** + * @deprecated This field no longer works and is subject to removal in the + * future. + */ + cacheurl: string | null; + /** The TTL of DNS responses from the Traffic Router, in seconds. */ + ccrDnsTtl?: number | null; + /** The ID of the CDN to which the Delivery Service belongs. */ + cdnId: number; + /** A sample path which may be requested to ensure the origin is working. */ + checkPath?: string | null; + /** + * A set of the query parameters that are important for Traffic Router to + * consider when performing "consistent hashing". + */ + consistentHashQueryParams?: Array<string> | null; + /** + * A regular expression used to extract request path fragments for use as + * keys in "consistent hashing" for routing purposes. + */ + consistentHashRegex?: string | null; + /** Whether or not to use "deep caching". */ + deepCachingType?: "ALWAYS" | "NEVER" | null; + /** A human-friendly name for the Delivery Service. */ + displayName: string; + /** An FQDN to use for DNS-routed bypass scenarios. */ + dnsBypassCname?: string | null; + /** An IPv4 address to use for DNS-routed bypass scenarios. */ + dnsBypassIp?: string | null; + /** An IPv6 address to use for DNS-routed bypass scenarios. */ + dnsBypassIp6?: string | null; + /** The TTL of DNS responses served in bypass scenarios. */ + dnsBypassTtl?: string | null; + /** The Delivery Service's DSCP. */ + dscp: number; + ecsEnabled?: boolean | null; + /** Extra header rewrite text used at the Edge tier. */ + edgeHeaderRewrite?: string | null; + firstHeaderRewrite?: string | null; + fqPacingRate?: number | null; + /** + * Describes limitation of content availability based on geographic + * location. + */ + geoLimit: GeoLimit; + /** + * The countries from which content access is allowed in the event that + * geographic limiting is taking place with a setting that allows for + * specific country codes to access content. + */ + geoLimitCountries?: string | null; + /** + * A URL to which to re-direct users who are blocked because of + * geographic-based access limiting + */ + geoLimitRedirectUrl?: string | null; + /** + * The provider of the IP-address-to-geographic-location database. + */ + geoProvider: GeoProvider; + /** + * The globally allowed maximum megabits per second to be served for the + * Delivery Service. + */ + globalMaxMbps?: number | null; + /** + * The globally allowed maximum transactions per second to be served for the + * Delivery Service. + */ + globalMaxTps?: number | null; + /** A URL to be used in HTTP-routed bypass scenarios. */ + httpBypassFqdn: string | null; + /** + * A URL from which information about a Delivery Service may be obtained. + * Historically, this has been used to link to the support ticket that + * requested the Delivery Service's creation. + */ + infoUrl: string | null; + /** The number of caches across which to spread content. */ + initialDispersion?: number | null; + innerHeaderRewrite?: string | null; + /** Whether or not routing of IPv6 clients should be supported. */ + ipv6RoutingEnabled?: boolean | null; + lastHeaderRewrite?: string | null; + /** Whether or not logging should be enabled for the Delivery Service. */ + logsEnabled: boolean; + /** A textual description of arbitrary length. */ + longDesc?: string | null; + /** + * A textual description of arbitrary length. + * + * @deprecated This has been removed in the latest API version. + */ + longDesc1?: string | null; + /** + * A textual description of arbitrary length. + * + * @deprecated This has been removed in the latest API version. + */ + longDesc2?: string | null; + /** + * Sets the maximum number of answers Traffic Router may provide in a single + * DNS response for this Delivery Service. + */ + maxDnsAnswers?: number | null; + /** + * The maximum number of connections that cache servers are allowed to open + * to the Origin(s). + * + * @default 0 + */ + maxOriginConnections?: number | null; + /** + * The maximum size (in bytes) of the request header that is allowed for + * this Delivery Service. + * + * @since 3.1 + * @default 0 + */ + maxRequestHeaderBytes?: number | null; + /** Extra header rewrite text to be used at the Mid-tier. */ + midHeaderRewrite?: string | null; + /** The latitude that should be used when geo-location of a client fails. */ + missLat?: number | null; + /** The longitude that should be used when geo-location of a client fails.*/ + missLong?: number | null; + /** Whether or not Multi-Site Origin is in use. */ + multiSiteOrigin?: boolean | null; + /** The URL of the Origin server, which I think means nothing for MSO. */ + orgServerFqdn?: string | null; + /** A string used to shield the Origin, somehow. */ + originShield?: string | null; + /** + * An integral, unique identifer for the Profile used by the Delivery + * Service. + */ + profileId?: number | null; + /** The protocols served by the Delivery Service. */ + protocol?: Protocol | null; + /** + * How query strings ought to be handled by cache servers serving content + * for this Delivery Service. + */ + qstringIgnore?: QStringHandling | null; + /** + * How HTTP Range requests ought to be handled by cache servers serving + * content for this Delivery Service. + */ + rangeRequestHandling?: RangeRequestHandling | null; + rangeSliceBlockSize?: null | number; + /** Some raw text to be inserted into regex_remap.config. */ + regexRemap?: string | null; + /** Whether or not regional geo-blocking should be used. */ + regionalGeoBlocking: boolean; + /** Some raw text to be inserted into remap.config. */ + remapText: string | null; + /** + * The lowest-level DNS label used in URLs for the Delivery Service. + * + * @default "cdn" + */ + routingName?: string | null; + serviceCategory?: string | null; + /** + * Whether or not responses from the cache servers for this Delivery + * Service's content will be signed. + */ + signed?: boolean | null; + /** + * The algorithm used to sign responses from the cache servers for this + * Delivery Service's content. + */ + signingAlgorithm?: "url_sig" | "uri_signing" | null; + /** The generation of SSL key used by this Delivery Service. */ + sslKeyVersion?: number | null; + /** + * An integral, unique identifier for the Tenant to whom this Delivery + * Service belongs. + */ + tenantId: number; + topology?: string | null; + /** + * HTTP headers that should be logged from client requests by Traffic + * Router. + */ + trRequestHeaders?: string | null; + /** Extra HTTP headers that Traffic Router should provide in responses. */ + trResponseHeaders?: string | null; + /** The integral, unique identifier of the type of the Delivery Service. */ + typeId: number; + /** The second-lowest-level DNS label used in the Delivery Service's URLs.*/ + xmlId: string; +} + +/** + * Represents an HTTP-type Delivery Service in the context of a request. + * + * Note that since Type is utterly determined by `typeId`, it's not possible to + * know without communicating with the server in some way whether or not any + * given object is actually HTTP-typed. + */ +export interface RequestHTTPDeliveryService extends RequestDeliveryServiceBase { + /** The number of caches across which to spread content. */ + initialDispersion: number; + /** Whether or not routing of IPv6 clients should be supported. */ + ipv6RoutingEnabled: boolean; + /** The latitude that should be used when geo-location of a client fails. */ + missLat: number; + /** The longitude that should be used when geo-location of a client fails.*/ + missLong: number; + /** Whether or not Multi-Site Origin is in use. */ + multiSiteOrigin: boolean; + /** The URL of the Origin server, which I think means nothing for MSO. */ + orgServerFqdn: string; + /** The protocols served by the Delivery Service. */ + protocol: Protocol; + /** + * How query strings ought to be handled by cache servers serving content + * for this Delivery Service. + */ + qstringIgnore: QStringHandling; + /** + * How HTTP Range requests ought to be handled by cache servers serving + * content for this Delivery Service. + */ + rangeRequestHandling: RangeRequestHandling; +} + +/** + * Represents a DNS-type Delivery Service in the context of a request. + * + * Note that since Type is utterly determined by `typeId`, it's not possible to + * know without communicating with the server in some way whether or not any + * given object is actually DNS-typed. + */ +export interface RequestDNSDeliveryService extends RequestDeliveryServiceBase { + /** Whether or not routing of IPv6 clients should be supported. */ + ipv6RoutingEnabled: boolean; + /** The latitude that should be used when geo-location of a client fails. */ + missLat: number; + /** The longitude that should be used when geo-location of a client fails.*/ + missLong: number; + /** Whether or not Multi-Site Origin is in use. */ + multiSiteOrigin: boolean; + /** The URL of the Origin server, which I think means nothing for MSO. */ + orgServerFqdn: string; + /** The protocols served by the Delivery Service. */ + protocol: Protocol; + /** + * How query strings ought to be handled by cache servers serving content + * for this Delivery Service. + */ + qstringIgnore: QStringHandling; + /** + * How HTTP Range requests ought to be handled by cache servers serving + * content for this Delivery Service. + */ + rangeRequestHandling: RangeRequestHandling; +} + +/** + * Represents a STEERING-type Delivery Service in the context of a request. + * + * Note that since Type is utterly determined by `typeId`, it's not possible to + * know without communicating with the server in some way whether or not any + * given object is actually STEERING-typed. + */ +export type RequestSteeringDeliveryService = RequestDeliveryServiceBase; + +/** + * Represents an ANY_MAP-type Delivery Service in the context of a request. + * + * Note that since Type is utterly determined by `typeId`, it's not possible to + * know without communicating with the server in some way whether or not any + * given object is actually ANY_MAP-typed. + */ +export type RequestAnyMapDeliveryService = RequestDeliveryServiceBase; + +/** + * Represents a Delivery Service as required by the Traffic Ops API in requests. + */ +export type RequestDeliveryService = RequestHTTPDeliveryService | RequestDNSDeliveryService | RequestSteeringDeliveryService | RequestAnyMapDeliveryService; + +/** + * The basic set of Delivery Service properties without being more specific as + * to the routing type, as they are found in responses. + */ +interface ResponseDeliveryServiceBase { + /** Whether or not the Delivery Service is actively routed. */ + active: boolean; + /** Whether or not anonymization services are blocked. */ + anonymousBlockingEnabled: boolean; + /** + * @deprecated This field no longer works and is subject to removal in the + * future. + */ + cacheurl: string | null; + /** The TTL of DNS responses from the Traffic Router, in seconds. */ + ccrDnsTtl: number | null; + /** The ID of the CDN to which the Delivery Service belongs. */ + cdnId: number; + /** + * The Name of the CDN to which the Delivery Service belongs. + * + * This is null in response to PUT or POST requests where it was null or + * unspecified in the response. + */ + cdnName: string | null; + /** A sample path which may be requested to ensure the origin is working. */ + checkPath: string | null; + /** + * A set of the query parameters that are important for Traffic Router to + * consider when performing "consistent hashing". + */ + consistentHashQueryParams: null | [string, ...Array<string>]; + /** + * A regular expression used to extract request path fragments for use as + * keys in "consistent hashing" for routing purposes. + */ + consistentHashRegex: string | null; + /** Whether or not to use "deep caching". */ + deepCachingType: "ALWAYS" | "NEVER"; + /** A human-friendly name for the Delivery Service. */ + displayName: string; + /** An FQDN to use for DNS-routed bypass scenarios. */ + dnsBypassCname: string | null; + /** An IPv4 address to use for DNS-routed bypass scenarios. */ + dnsBypassIp: string | null; + /** An IPv6 address to use for DNS-routed bypass scenarios. */ + dnsBypassIp6: string | null; + /** The TTL of DNS responses served in bypass scenarios. */ + dnsBypassTtl: number | null; + /** The Delivery Service's DSCP. */ + dscp: number; + ecsEnabled: boolean; + /** Extra header rewrite text used at the Edge tier. */ + edgeHeaderRewrite: string | null; + /** + * A list of the URLs which may be used to request Delivery Service content. + * + * These are generated on-the-fly by Traffic Ops based on the structure of + * the given Delivery Service - as such, they cannot be directly modified. + */ + readonly exampleURLs: readonly string[]; + firstHeaderRewrite: string | null; + fqPacingRate: number; + /** + * Describes limitation of content availability based on geographic + * location. + */ + geoLimit: GeoLimit; + /** + * The countries from which content access is allowed in the event that + * geographic limiting is taking place with a setting that allows for + * specific country codes to access content. + */ + geoLimitCountries: string | null; + /** + * A URL to which to re-direct users who are blocked because of + * geographic-based access limiting + */ + geoLimitRedirectURL: string | null; + /** + * The provider of the IP-address-to-geographic-location database. + */ + geoProvider: GeoProvider; + /** + * The globally allowed maximum megabits per second to be served for the + * Delivery Service. + */ + globalMaxMbps: number | null; + /** + * The globally allowed maximum transactions per second to be served for the + * Delivery Service. + */ + globalMaxTps: number | null; + /** A URL to be used in HTTP-routed bypass scenarios. */ + httpBypassFqdn: string | null; + /** An integral, unique identifier for the Delivery Service. */ + readonly id: number; + /** + * A URL from which information about a Delivery Service may be obtained. + * Historically, this has been used to link to the support ticket that + * requested the Delivery Service's creation. + */ + infoUrl: string | null; + /** The number of caches across which to spread content. */ + initialDispersion: number; + innerHeaderRewrite: string | null; + /** Whether or not routing of IPv6 clients should be supported. */ + ipv6RoutingEnabled: boolean; + lastHeaderRewrite: string | null; + /** When the Delivery Service was last updated via the API. */ + lastUpdated: Date; + /** Whether or not logging should be enabled for the Delivery Service. */ + logsEnabled: boolean; + /** A textual description of arbitrary length. */ + longDesc: string | null; + /** + * A textual description of arbitrary length. + * + * @deprecated This has been removed in the latest API version. + */ + longDesc1?: string; + /** + * A textual description of arbitrary length. + * + * @deprecated This has been removed in the latest API version. + */ + longDesc2?: string; + /** + * A list of regular expressions for routing purposes which should not ever + * be modified by hand. + */ + matchList: Array<DeliveryServiceMatch>; + /** + * Sets the maximum number of answers Traffic Router may provide in a single + * DNS response for this Delivery Service. + */ + maxDnsAnswers: number | null; + /** + * The maximum number of connections that cache servers are allowed to open + * to the Origin(s). + */ + maxOriginConnections: number; + /** + * The maximum size (in bytes) of the request header that is allowed for + * this Delivery Service. + * + * @since 3.1 + */ + maxRequestHeaderBytes: number; + /** Extra header rewrite text to be used at the Mid-tier. */ + midHeaderRewrite: string | null; + /** The latitude that should be used when geo-location of a client fails. */ + missLat: number; + /** The longitude that should be used when geo-location of a client fails.*/ + missLong: number; + /** Whether or not Multi-Site Origin is in use. */ + multiSiteOrigin: boolean; + /** A string used to shield the Origin, somehow. */ + originShield: string | null; + /** The URL of the Origin server, which I think means nothing for MSO. */ + orgServerFqdn: string; + /** The protocols served by the Delivery Service. */ + protocol: Protocol; + /** + * How query strings ought to be handled by cache servers serving content + * for this Delivery Service. + */ + qstringIgnore: QStringHandling; + /** + * How HTTP Range requests ought to be handled by cache servers serving + * content for this Delivery Service. + */ + rangeRequestHandling: RangeRequestHandling; + rangeSliceBlockSize: null | number; + /** Some raw text to be inserted into regex_remap.config. */ + regexRemap: string | null; + /** Whether or not regional geo-blocking should be used. */ + regionalGeoBlocking: boolean; + /** Some raw text to be inserted into remap.config. */ + remapText: string | null; + /** The lowest-level DNS label used in URLs for the Delivery Service. */ + routingName: string; + serviceCategory: string | null; + /** + * Whether or not responses from the cache servers for this Delivery + * Service's content will be signed. + */ + signed: boolean; + /** + * The algorithm used to sign responses from the cache servers for this + * Delivery Service's content. + */ + signingAlgorithm: "url_sig" | "uri_signing"; + /** The generation of SSL key used by this Delivery Service. */ + sslKeyVersion: number | null; + /** The name of the Tenant to whom this Delivery Service belongs. */ + tenant: string; + /** + * An integral, unique identifier for the Tenant to whom this Delivery + * Service belongs. + */ + tenantId: number; + topology: string | null; + /** Extra HTTP headers that Traffic Router should provide in responses. */ + trResponseHeaders: string | null; + /** + * HTTP headers that should be logged from client requests by Traffic + * Router. + */ + trRequestHeaders: string | null; + /** The type of the Delivery Service. */ + type: string; + /** The integral, unique identifier of the type of the Delivery Service. */ + typeId: number; + /** The second-lowest-level DNS label used in the Delivery Service's URLs.*/ + xmlId: string; +} + +/** + * A Delivery Service with a Profile. If a Delivery Service has a Profile, all + * of the related properties are guaranteed to be non-null in responses. + */ +interface ResponseDeliveryServiceWithProfile extends ResponseDeliveryServiceBase { + /** A description of the Profile used by the Delivery Service (read-only) */ + profileDescription: string; + /** + * An integral, unique identifer for the Profile used by the Delivery + * Service. + */ + profileId: number; + /** The name of the Profile used by the Delivery Service. */ + profileName: string; +} + +/** + * A Delivery Service with a Profile. If a Delivery Service does not has a + * Profile, all of the related properties are guaranteed to be null in + * responses. + */ +interface ResponseDeliveryServiceWithoutProfile extends ResponseDeliveryServiceBase { + /** A description of the Profile used by the Delivery Service (read-only) */ + profileDescription: null; + /** + * An integral, unique identifer for the Profile used by the Delivery + * Service. + */ + profileId: null; + /** The name of the Profile used by the Delivery Service. */ + profileName: null; +} + +/** + * Represents a Delivery Service as returned by the Traffic Ops API in + * responses. + */ +export type ResponseDeliveryService = ResponseDeliveryServiceWithProfile | ResponseDeliveryServiceWithoutProfile; + +/** + * Represents a Delivery Service. + */ +export type DeliveryService = RequestDeliveryService | ResponseDeliveryService; + +/** + * Determines if the Delivery Service is a candidate for bypassing. + * + * @param ds The Delivery Service to check. + * @returns `true` if it can have bypass settings, `false` otherwise. + */ +export function bypassable(ds: DeliveryService): boolean { + if (!Object.prototype.hasOwnProperty.call(ds, "type")) { + return false; + } + + switch ((ds as ResponseDeliveryService).type) { + case "HTTP": + case "HTTP_LIVE": + case "HTTP_LIVE_NATNL": + case "DNS": + case "DNS_LIVE": + case "DNS_LIVE_NATNL": + return true; + default: + return false; + } +} + +/** + * DSCapacity represents a response from the API to a request for the capacity + * of a Delivery Service. + */ +export interface DSCapacity { + availablePercent: number; + maintenancePercent: number; + unavailablePercent: number; + utilizedPercent: number; +} + +/** + * DSHealth represents a response from the API to a request for the health of a + * Delivery Service. + */ +export interface DSHealth { + cachegroups: Array<{ + name: string; + offline: number; + online: number; + }>; + totalOnline: number; + totalOffline: number; +} diff --git a/src/division.ts b/src/division.ts new file mode 100644 index 0000000..cdc25e0 --- /dev/null +++ b/src/division.ts @@ -0,0 +1,40 @@ +/** + * Represents a Division as required by the Traffic Ops API in requests. + */ +export interface RequestDivision { + name: string; +} + +/** + * Represents a Division as returned by the Traffic Ops API in responses. + */ +export interface ResponseDivision { + readonly id: number; + lastUpdated: Date; + name: string; +} + +/** Representns a Division. */ +export type Division = RequestDivision | ResponseDivision; + +/** + * Represents a Region as required by the Traffic Ops API in requests. + */ +export interface RequestRegion { + division: number; + name: string; +} + +/** + * Represents a Region as returned by the Traffic Ops API in responses. + */ +export interface ResponseRegion { + division: number; + divisionName: string; + readonly id: number; + lastUpdated: Date; + name: string; +} + +/** Represents a Region. */ +export type Region = RequestRegion | ResponseRegion; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..c1edef1 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,75 @@ +export * from "./about"; +export * from "./acme"; +export * from "./alert"; +export * from "./cache.group"; +export * from "./cdn"; +export * from "./delivery.service"; +export * from "./division"; +export * from "./invalidation"; +export * from "./iso"; +export * from "./login"; +export * from "./logs"; +export * from "./parameter"; +export * from "./physical.location"; +export * from "./plugin"; +export * from "./profile"; +export * from "./server"; +export * from "./stats"; +export * from "./status"; +export * from "./type"; +export * from "./user"; +export * from "./vault"; + +import type { Alert } from "./alert"; + +/** + * Represents a version of the Traffic Ops API for which this library was made. + */ +interface VersionType { + /** The major API version number. */ + readonly major: number; + /** The minor API version number. */ + readonly minor: number; + toString(): string; + /** + * Whether the API version is unstable. This will be `false` until the API + * has been included in a release in which it was not labelled as + * "unstable". + */ + readonly unstable: boolean; +} + +/** + * The version of the Traffic Ops API for which this library was made. + * + * In general, this is roughly the same as the library package version. However, + * the Traffic Ops API does not include patch-level numbering - which is good, + * because it allows this package to use those for bugfixes. + */ +export const VERSION: VersionType = { + major: 3, + minor: 1, + toString() { + return `${this.major}.${this.minor}`; + }, + unstable: false +}; + +/** + * (Nearly) All responses from the Traffic Ops API conform to this interface. + */ +export interface APIResponse<T> { + alerts?: Array<Alert>; + response: T; + summary?: { + count: number; + }; +} + +/** + * Represents a response from /ping - the *entire* response, as it isn't an + * APIResponse. + */ +export interface PingResponse { + ping: "pong"; +} diff --git a/src/invalidation.ts b/src/invalidation.ts new file mode 100644 index 0000000..80b05f0 --- /dev/null +++ b/src/invalidation.ts @@ -0,0 +1,65 @@ +/** JobType enumerates the valid types of Job. */ +export const enum JobType { + /** Content Invalidation Request. */ + PURGE = "PURGE" +} + +/** + * InvalidationJob objects represent periods of time over which specific objects + * may not be cached. + */ +export interface ResponseInvalidationJob { + /** + * A regular expression that matches content to be "invalidated" or + * "revalidated". + */ + assetURL: string; + /** + * The name of the user that created the Job. + */ + createdBy: string; + /** The XMLID of the Delivery Service within which the Job will operate. */ + deliveryService: string; + /** An integral, unique identifier for this Job. */ + readonly id: number; + /** The type of Job. */ + keyword: JobType; + /** + * though not enforced by the API (or database), this should ALWAYS have the + * format 'TTL:nh', describing the job's TTL in hours (`n` can be any + * integer value > 0). + */ + parameters: string; + /** + * The time at which the Job is scheduled to start. + */ + startTime: Date; +} + +/** + * A NewInvalidationJob is the data structure used to request creation of a new + * content invalidation job through the API. + */ +export interface RequestInvalidationJob { + /** + * This may be either the ID or the XMLID of the Delivery Service to which + * the Job will apply. + */ + deliveryService: number | string; + /** + * The effective starting date/time for the Job. + */ + startTime: Date | string; + /** + * A pattern that matches content to be invalidated. + */ + regex: string; + /** + * Either the number of hours or a "duration string" describing for how + * long the Job will remain in effect. + */ + ttl: number | string; +} + +/** Represents a content invalidation job. */ +export type InvalidationJob = RequestInvalidationJob | ResponseInvalidationJob; diff --git a/src/iso.ts b/src/iso.ts new file mode 100644 index 0000000..fb17d39 --- /dev/null +++ b/src/iso.ts @@ -0,0 +1,44 @@ +/** The basic fields common to all ISO request bodies. */ +interface ISOFields { + disk: string; + domainName: string; + hostName: string; + interfaceMtu: number; + interfaceName?: string | null; + ip6Address?: string | null; + ip6Gateway?: string | null; + osVersionsDir: string; + rootPass: string; +} + +/** + * An ISO generation request. If DHCP isn't used, network information must be + * manually supplied. + */ +interface ISORequestDHCP extends ISOFields { + dhcp: "no"; + ipAddress: string; + ipGateway: string; + ipNetmask: string; +} + +/** + * An ISO generation request. If DHCP is used, network inforation need not be + * supplied. + */ +interface ISORequestNonDHCP extends ISOFields { + dhcp: "yes"; +} + +/** + * Represents a request to the `/isos` endpoint of the Traffic Ops API. + */ +export type ISORequest = ISORequestDHCP | ISORequestNonDHCP; + +/** + * Represents a response from the Traffic Ops API to a request made to its + * `/osversions` endpoint. + */ +export interface OSVersions { + [osversion: string]: string; +} diff --git a/src/login.ts b/src/login.ts new file mode 100644 index 0000000..3483865 --- /dev/null +++ b/src/login.ts @@ -0,0 +1,47 @@ +/** + * The standard, traditional body of a login request. + */ +export interface LoginRequest { + /** The user's password. */ + p: string; + /** The user's username. */ + u: string; +} + +/** + * The body of a login request submitted through the `/user/login/oauth` + * endpoint of the Traffic Ops API. + */ +export interface OAuthLoginRequest { + authCodeTokenUrl: string; + code: string; + clientId: string; + redirectUri: string; +} + +/** + * The body of a login request submitted through the `/user/login/token` + * endpoint of the Traffic Ops API. + */ +export interface TokenLoginRequest { + /** The user's authentication token. */ + t: string; +} + +/** + * The body of a password reset request submitted through the + * `/user/reset_password` endpoint of the Traffic Ops API. + */ +export interface ResetPasswordRequest { + email: `${string}@${string}.${string}`; +} + +/** + * The body of a new user registration request submitted through the + * `/users/register` endpoint of the Traffic Ops API. + */ +export interface RegistrationRequest { + email: `${string}@${string}.${string}`; + role: number; + tenantId: number; +} diff --git a/src/logs.ts b/src/logs.ts new file mode 100644 index 0000000..f467162 --- /dev/null +++ b/src/logs.ts @@ -0,0 +1,66 @@ +/** + * Represents a single Traffic Ops ChangeLog entry as returned by the `/logs` + * endpoint of its API. + */ +export interface Log { + readonly id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + /** + * @deprecated This field has no further use, and is subject to removal in + * the future. + */ + level: "APICHANGE"; + message: string; + /** + * @deprecated This cannot be populated, and so should always be considered + * null, and is subject to removal in the future. + */ + readonly ticketNum: number | null; + user: string; +} + +/** + * Converts a changelog entry to a string, suitable for use as a line in a + * logfile. + * + * @example + * const l = { + * id: 1, + * lastUpdated: new Date(0), + * level: "APICHANGE", + * message: "a message", + * ticketNum: 2, + * user: me + * } + * + * console.log(logEntryToString(l)); + * // Output: + * // #1 1970-01-01T00:00:00.000Z: me via APICHANGE (From Ticket #2): a message + * + * @param log The Log entry being formatted. + * @returns A string representation of `log`. + */ +export function logEntryToString(log: Log): string { + const {id, lastUpdated, level, message, ticketNum, user} = log; + + let ret = `#${id} ${lastUpdated.toISOString()}: ${user} via ${level}`; + if (ticketNum !== null) { + ret += ` (From Ticket #${ticketNum})`; + } + + return `${ret}: ${message}`; +} + +/** + * Represents the response from the Traffic Ops API to a request made to its + * `/logs/newcount` endpoint. + */ +export interface NewLogCount { + newLogcount: number; +} diff --git a/src/parameter.ts b/src/parameter.ts new file mode 100644 index 0000000..0e749cd --- /dev/null +++ b/src/parameter.ts @@ -0,0 +1,36 @@ +/** + * A RequestParameter is a Parameter as given in PUT and POST requests to + * /parameters. + */ +export interface RequestParameter { + configFile: string; + name: string; + secure: boolean; + value: string; +} + +/** + * A ResponseParameter is a Parameter as given by Traffic Ops in its API + * responses. + */ +export interface ResponseParameter { + configFile: string; + readonly id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + name: string; + profiles: Array<string>; + secure: boolean; + value: string; +} + +/** + * A Parameter generically represents a Parameter, either in request format or + * response format. + */ +export type Parameter = RequestParameter | ResponseParameter; diff --git a/src/physical.location.ts b/src/physical.location.ts new file mode 100644 index 0000000..6eb4b45 --- /dev/null +++ b/src/physical.location.ts @@ -0,0 +1,86 @@ +/** + * Represents a Physical Location as returned by the Traffic Ops API in + * responses. + */ +export interface ResponsePhysicalLocation { + /** The Physical Location’s street address. */ + address: string; + /** The name of the city in which the Physical Location lies. */ + city: string; + /** Any and all human-readable comments. */ + comments: string | null; + /** The email address of the Physical Location’s poc. */ + email: string | null; + /** An integral, unique identifier for the Physical Location. */ + id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + /** The name of the Physical Location. */ + name: string; + /** A phone number where the the Physical Location’s poc might be reached. */ + phone: string | null; + /** The name of a “point of contact” for the Physical Location. */ + poc: string | null; + /** + * The name of the region within which the Physical Location lies. + * + * This will be `null` in responses to PUT or POST requests which didn't + * specify it, or which explicitly specified it as `null`. + */ + region: string | null; + /** + * An integral, unique identifier for the region within which the Physical + * Location lies. + */ + regionId: number; + /** An abbreviation of the name. */ + shortName: string; + /** + * An abbreviation (usually) of the name of the state or province within + * which this Physical Location lies. + */ + state: string; + /** The zip code of the Physical Location. */ + zip: string; +} + +/** + * Represents a Physical Location as required by the Traffic Ops API in + * requests. + */ +export interface RequestPhysicalLocation { + /** The Physical Location’s street address. */ + address: string; + /** The name of the city in which the Physical Location lies. */ + city: string; + /** Any and all human-readable comments. */ + comments?: string | null; + /** The email address of the Physical Location’s poc. */ + email?: string | null; + /** The name of the Physical Location. */ + name: string; + /** A phone number where the the Physical Location’s poc might be reached. */ + phone?: string | null; + /** The name of a “point of contact” for the Physical Location. */ + poc?: string | null; + /** + * An integral, unique identifier for the region within which the Physical + * Location lies. + */ + regionId: number; + /** + * An abbreviation (usually) of the name of the state or province within + * which this Physical Location lies. + */ + state: string; + /** The zip code of the Physical Location. */ + zip: string; +} + +/** Represents a Physical Location. */ +export type PhysicalLocation = ResponsePhysicalLocation | RequestPhysicalLocation; diff --git a/src/plugin.ts b/src/plugin.ts new file mode 100644 index 0000000..7df1df7 --- /dev/null +++ b/src/plugin.ts @@ -0,0 +1,10 @@ +/** + * Represents a Traffic Ops plugin as reported by the `/plugins` API endpoint. + * + * Plugins cannot be modified through the API. + */ +export interface TOPlugin { + readonly description: string; + readonly name: string; + readonly version: string; +} diff --git a/src/profile.ts b/src/profile.ts new file mode 100644 index 0000000..803dd58 --- /dev/null +++ b/src/profile.ts @@ -0,0 +1,96 @@ +/** ProfileTypes are the valid `type`s of Profiles. */ +export const enum ProfileType { + /** + * A Profile for a cache server (edge-tier or mid-tier). Grove cache + * servers, though, should use GROVE_PROFILE instead. + */ + ATS_PROFILE = "ATS_PROFILE", + /** A Profile for a Traffic Router server. */ + TR_PROFILE = "TR_PROFILE", + /** A Profile for a Traffic Monitor server. */ + TM_PROFILE = "TM_PROFILE", + /** A Profile for a Traffic Stats server. */ + TS_PROFILE = "TS_PROFILE", + /** A Profile for a Traffic Portal server. */ + TP_PROFILE = "TP_PROFILE", + /** A Profile for an InfluxDB instance/server. */ + INFLUXDB_PROFILE = "INFLUXDB_PROFILE", + /** + * A Profile for a Riak KV server. + * + * @deprecated Riak KV as a back-end for Traffic Vault is deprecated. + */ + RIAK_PROFILE = "RIAK_PROFILE", + /** A Profile for a Splunk server. */ + SPLUNK_PROFILE = "SPLUNK_PROFILE", + /** A Profile used by Delivery Services, rather than servers. */ + DS_PROFILE = "DS_PROFILE", + /** A Profile used by Origins and/or origin servers. */ + ORG_PROFILE = "ORG_PROFILE", + /** A Profile for Kafka servers. */ + KAFKA_PROFILE = "KAFKA_PROFILE", + /** A Profile for Logstash servers. */ + LOGSTASH_PROFILE = "LOGSTASH_PROFILE", + /** A Profile for ElasticSearch servers. */ + ES_PROFILE = "ES_PROFILE", + /** A Profile for any server that doesn't have a more specific Profile type. */ + UNK_PROFILE = "UNK_PROFILE", + /** A Profile for Grove cache servers. */ + GROVE_PROFILE = "GROVE_PROFILE" +} + +/** + * In responses from certain endpoints, Profiles include these custom + * representations of their assigned Parameters. + */ +interface ResponseProfileParameter { + configFile: string; + id: number; + lastUpdated: null; + name: string; + profiles: null; + secure: boolean; + value: string; +} + +/** A ResponseProfile is a Profile as given by Traffic Ops in API responses. */ +export interface ResponseProfile { + cdn: number; + /** + * This is null in responses to PUT or POST requests where 'cdnName' was + * not given. + */ + cdnName: string | null; + description: string; + id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + name: string; + /** + * This only appears when a response array contains exactly one Profile, + * and when that Profile has at least one assigned Parameter. + */ + params?: [ResponseProfileParameter, ...ResponseProfileParameter[]]; + routingDisabled: boolean; + type: ProfileType; +} + +/** RequestProfile is a Profile as required in requests by the Traffic Ops API. */ +export interface RequestProfile { + cdn: number; + description: string; + name: string; + routingDisabled: boolean; + type: ProfileType; +} + +/** + * A Profile represents, generically, a Profile in the context of either a + * request to or a response from the Traffic Ops API. + */ +export type Profile = RequestProfile | ResponseProfile; diff --git a/src/server.ts b/src/server.ts new file mode 100644 index 0000000..f06d9ea --- /dev/null +++ b/src/server.ts @@ -0,0 +1,301 @@ +/** + * This file is for modeling and functionality related to Server objects + */ + +/** IPAddress is a single IP address of a single network interface of a server. */ +export interface IPAddress { + /** The actual IP address. */ + address: string; + /** The IP address of a gateway for this IP, if one exists/is known. */ + gateway: string | null; + /** Whether or not this IP address is responsible for serving ATC traffic. */ + serviceAddress: boolean; +} + +/** Interface is a server's network interface. */ +export interface Interface { + /** The IP addresses assigned to this network interface. */ + ipAddresses: Array<IPAddress>; + /** The maximum bandwidth for considering the server healthy, if any. */ + maxBandwidth: number | null; + /** + * Whether or not the Traffic Monitor should consider this network interface + * in health calculations. + */ + monitor: boolean; + /** The maximum transmission unit of the network interface, if known. */ + mtu: number | null; + /** The name of the network interface in the `/dev` directory. */ + name: string; +} + +/** + * Searches a collection of IPAddresses exhaustively for service addresses. + * + * @param ips The IPAddresses to search. + * @returns A tuple of the found IPv4 and IPv6 addresses, each being `null` if + * not found. + */ +function exhaustiveServiceAddresses(ips: Array<IPAddress>): [IPAddress | null, IPAddress | null] { + let ipv4 = null; + let ipv6 = null; + for (const ip of ips) { + if (ip.serviceAddress) { + if (ip.address.includes(":")) { + if (ipv6 !== null) { + throw new Error(`found two IPv6 service addresses: '${ipv6.address}' and '${ip.address}'`); + } + ipv6 = ip; + } else if (ipv4 !== null) { + throw new Error(`found two IPv4 service addresses: '${ipv4.address}' and '${ip.address}'`); + } else { + ipv4 = ip; + } + } + } + return [ipv4, ipv6]; +} + +/** + * Searches for service IP Addresses in the given collection, traversing the + * list as little as possible to find a valid set. + * @param ips The collection of IPs to search. + * @returns A tuple of the found IPv4 and IPv6 addresses, each being `null` if + * not found. + */ +function inexhaustiveServiceAddresses(ips: Array<IPAddress>): [IPAddress | null, IPAddress | null] { + let ipv4 = null; + let ipv6 = null; + for (const ip of ips) { + if (ip.serviceAddress) { + if (ip.address.includes(":")) { + if (ipv6 !== null) { + throw new Error(`found two IPv6 service addresses: '${ipv6.address}' and '${ip.address}'`); + } + ipv6 = ip; + } else if (ipv4 !== null) { + throw new Error(`found two IPv4 service addresses: '${ipv4.address}' and '${ip.address}'`); + } else { + ipv4 = ip; + } + } + if (ipv4 !== null && ipv6 !== null) { + break; + } + } + return [ipv4, ipv6]; +} + +/** + * Extracts the "service" address of an {@link IPAddress} collection or + * {@link Interface}. + * + * @param inf The interface or raw list of IP addresses from which to extract + * service addresses. + * @param exhaustive If `true`, the function will check for service addresses + * exhaustively. When this is `false`, the function returns as soon as it finds + * one service address per address family - essentially assuming that there are + * no duplicates. Exhaustive searches will ensure there is no more than one + * service address per family by checking the entire collection. + * @returns A tuple of the IPv4 service address of the interface (or `null` if + * it doesn't have one) and the IPv6 service address of the interface (or `null` + * if it doesn't have one). Note that this function does not check for the case + * when a collection of IPs has no service addresses - it is up to the caller to + * recognize that a return value of `[null, null]` indicates an invalid + * collection. + * @throws {Error} When more than one service address is found for a single + * address family. + */ +export function serviceAddresses(inf: Interface | Array<IPAddress>, exhaustive = false): [ipv4Address: IPAddress | null, ipv6Address: IPAddress | null] { + const arr = inf instanceof Array ? inf : inf.ipAddresses; + if (exhaustive) { + return exhaustiveServiceAddresses(arr); + } + return inexhaustiveServiceAddresses(arr); +} + +/** + * Represents a nebulous "server" object as returned by Traffic Ops in + * responses. + */ +export interface ResponseServer { + /** The Cache Group to which the server belongs. */ + cachegroup: string; + /** + * The integral, unique identifier of the Cache Group to which the server + * belongs. + */ + cachegroupId: number; + /** + * The integral, unique identifier of the CDN to which the server belongs. + */ + cdnId: number; + /** The name of the CDN to which the server belongs. */ + cdnName: string; + /** + * The servers FQDN without its hostname - e.g. 'apache.org' from + * 'trafficcontrol.apache.org'. + */ + domainName: string; + /** + * Legacy field with no purpose. + * + * @deprecated This field has no purpose and is subject to removal in the + * future. + */ + guid: number | null; + /** + * The server's hostname, e.g. 'trafficcontrol' from + * 'trafficcontrol.apache.org'. + */ + hostName: string; + /** The port used to serve HTTPS responses, if any. */ + httpsPort: number | null; + /** An integral, unique identifier for this Server. */ + readonly id: number; + /** The IP address of the Server's ILO interface. */ + iloIpAddress: string | null; + /** The IP address of the gateway to the Server's ILO interface. */ + iloIpGateway: string | null; + /** + * A netmask that describes the subnet allocated to the Server's ILO + * interface. + */ + iloIpNetmask: string | null; + /** The Server's ILO interface's password. */ + iloPassword: string | null; + /** The Server's ILO interface's root user's name. */ + iloUsername: string | null; + /** The Server's network interfaces. */ + interfaces: Array<Interface>; + /** The date/time at which the Server was last updated. */ + lastUpdated: Date; + /** The IP address of the server's management interface. */ + mgmtIpAddress: string | null; + /** The IP address of the gateway to the Server's management interface. */ + mgmtIpGateway: string | null; + /** + * The netmask that describes the subnet allocated to the Server's + * management interface. + */ + mgmtIpNetmask: string | null; + /** The reason the Server has been taken out of service. */ + offlineReason: string | null; + /** The physical location in which the Server resides. */ + physLocation: string; + /** + * An integral, unique identifier for the physical location in which the + * Server resides. + */ + physLocationId: number; + /** The Profile used by the Server. */ + profile: string; + /** + * A description of the Profile used by the Server. + * + * @deprecated Future representations of Server objects will drop the + * Profile description entirely, as it's trivially deduced from Profile + * identity. + */ + profileDesc: string; + /** + * An integral, unique identifier for the Profile used by the Server. + * + * @deprecated In the latest API version, a server's Profile is identified + * only by name, not unique, integral identifier. + */ + profileId: number; + /** Whether or not revalidations are pending for this Server. */ + revalPending: boolean; + /** + * Legacy field with no purpose. + * + * @deprecated This field has no purpose and is subject to removal in the + * future. + */ + rack: string | null; + /** The hostname of the router that routes to this Server. */ + routerHostName: string | null; + /** The... name... of the port... used by the Server's router?? */ + routerPortName: string | null; + /** The Server's status. */ + status: string; + /** An integral, unique, identifier for the Server's Status. */ + statusId: number; + /** The time at which the server's status was last updated. */ + statusLastUpdated: Date | null; + /** The port on which the Server listens for incoming TCP connections. */ + tcpPort: number | null; + /** The type of the Server. */ + type: string; + /** An integral, unique identifier for the Type of this Server. */ + typeId: number; + /** Whether or not this Server has updates pending. */ + updPending: boolean; + /** + * The string used by Traffic Router for consistent hashing to this Server. + * + * This is generated for the server upon its creation, and cannot be + * modified afterwards. + */ + readonly xmppId: string; + /** legacy field with no purpose. */ + xmppPasswd?: string | null; +} + +/** + * Servercheck models the data returned by the /servercheck API endpoint. + */ +export interface Servercheck { + /** contains the server's Status */ + adminState: string; + /** the name of the Cache Group to which the server belongs */ + cacheGroup: string; + /** + * Checks emulates a map of check names to their numbers. All values are + * numbers, but some may express boolean concepts; for example, the ORT + * check uses 1 to represent "true" and any other value indicates "false". + */ + checks?: Record<string, number>; + /** the server's hostname */ + hostName: string; + /** the server's ID */ + id: number; + /** the name of the server's Profile */ + profile: string; + /** whether or not the server has pending revalidations */ + revalPending: boolean; + /** the name of the server's Type */ + type: string; + /** whether or not the server has updates pending */ + updPending: boolean; +} + +/** + * Builds a true Map from the Servercheck's "checks" property. + * + * @param srv The Servercheck to convert. + * @returns A map of servercheck check names to their values. + */ +export function checkMap(srv: Servercheck): Map<string, number | boolean> { + const ret = new Map(); + if (!srv.checks) { + return ret; + } + for (const [key, value] of Object.entries(srv.checks)) { + switch (key) { + case "ILO": + case "10G": + case "FQDN": + case "DSCP": + case "10G6": + case "MTU": + ret.set(key, value === 1); + break; + default: + ret.set(key, value); + break; + } + } + return ret; +} diff --git a/src/stats.ts b/src/stats.ts new file mode 100644 index 0000000..3d0752e --- /dev/null +++ b/src/stats.ts @@ -0,0 +1,67 @@ +/** CacheStatsSeries is a set of data collected by Traffic Stats. */ +export interface CacheStatsSeries { + columns: ["time", "sum_count"]; + count: number; + name: `${"bandwidth" | "connections" | "maxkbps"}.cdn.1min`; + /** + * Each first tuple element is actually a string that represents a + * date/time, in a custom format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + values: Array<[Date, number | null]>; +} + +/** CacheStatsSummary is a summary of some statistics set. */ +export interface CacheStatsSummary { + average: number; + count: number; + fifthPercentile: number; + max: number; + min: number; + ninetyEightPercentile: number; + ninetyFifthPercentile: number; +} + +/** Represents a response from /cache_stats.*/ +export interface CacheStats { + /** + * This will be excluded if the 'exclude' query string parameter was + * "series" **or** if there were no data points for the requested data set. + */ + series?: CacheStatsSeries; + /** + * This will be excluded **only** if the 'exclude' query string parameter + * was "summary". + */ + summary?: CacheStatsSummary; +} + +/** + * CurrentStats represents a response from the `/current_stats` Traffic Ops API + * endpoint. + */ +export interface CurrentStats { + /** + * Each entry in the `currentStats` array reports the recorded stats for the + * named CDN. The last entry is always the total across all CDNs, and + * doesn't report capacity. The first entry is *usually* the special ALL + * CDN, which - wherever it does appear - will always have `null` for all + * its stats. + */ + currentStats: [ + ...Array< + { + bandwidth: number | null; + capacity: number | null; + cdn: string; + connections: number | null; + } + >, + { + bandwidth: number | null; + cdn: "total"; + connections: number | null; + } + ]; +} diff --git a/src/status.ts b/src/status.ts new file mode 100644 index 0000000..dbc025a --- /dev/null +++ b/src/status.ts @@ -0,0 +1,25 @@ +/** ResponseStatus represents a Status as returned in responses from the API. */ +export interface ResponseStatus { + description: string | null; + id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + name: string; +} + +/** RequestStatus represents a Status as used in requests to the API. */ +export interface RequestStatus { + description?: string | null; + name: string; +} + +/** + * Status generically represents a Status in the context of an API request or + * response. + */ +export type Status = ResponseStatus | RequestStatus; diff --git a/src/type.ts b/src/type.ts new file mode 100644 index 0000000..7b11fa4 --- /dev/null +++ b/src/type.ts @@ -0,0 +1,29 @@ +/** + * TypeFromResponse represents a Type as shown in the responses from the API. + * + * This breaks the naming convention used in the rest of this library because + * ResponseType is already a global type in browsers and NodeJS. + */ +export interface TypeFromResponse { + description: string; + id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + name: string; + useInTable: string; +} + +/** RequestType represents a Type as given in requests to the API. */ +export interface RequestType { + description: string; + name: string; + useInTable: string; +} + +/** Type generically represents a Type in the context of an API request or response. */ +export type Type = TypeFromResponse | RequestType; diff --git a/src/user.ts b/src/user.ts new file mode 100644 index 0000000..7950f25 --- /dev/null +++ b/src/user.ts @@ -0,0 +1,232 @@ +/** + * PostRequestUser is a user as it appears in a POST request to /users. + * This is subtly different from a user as required in other contexts. For more + * information, see apache/trafficcontrol#6299. + */ +export interface PostRequestUser { + addressLine1?: string | null; + addressLine2?: string | null; + city?: string | null; + company?: string | null; + confirmLocalPasswd: string; + country?: string | null; + email: `${string}@${string}.${string}`; + fullName: string; + /** @deprecated This has no purpose and should never be used. */ + gid?: number | null; + localPasswd: string; + newUser?: boolean | null; + phoneNumber?: string | null; + postalCode?: string | null; + publicSshKey?: string | null; + role: number; + stateOrProvince?: string | null; + tenantId?: never; + tenantID: number; + /** @deprecated This has no purpose and should never be used. */ + uid?: number | null; + username: string; +} + +/** + * Represents a user in a PUT request where the user's password is *not* being + * changed. + */ +interface PutRequestNotChangingPasswordUser { + addressLine1?: string | null; + addressLine2?: string | null; + city?: string | null; + company?: string | null; + country?: string | null; + email: `${string}@${string}.${string}`; + fullName: string; + /** @deprecated This has no purpose and should never be used. */ + gid?: number | null; + newUser?: boolean | null; + phoneNumber?: string | null; + postalCode?: string | null; + publicSshKey?: string | null; + role: number; + stateOrProvince?: string | null; + tenantId?: never; + tenantID: number; + /** @deprecated This has no purpose and should never be used. */ + uid?: number | null; + username: string; +} + +/** + * PostRequestUser is a user as it appears in a POST request to /users. + * This is subtly different from a user as required in other contexts. For more + * information, see apache/trafficcontrol#6299. + */ +export type PutRequestUser = PostRequestUser | PutRequestNotChangingPasswordUser; + +/** Groups the fields common to responses from /users in all contexts. */ +interface ResponseUser { + addressLine1: string | null; + addressLine2: string | null; + city: string | null; + company: string | null; + country: string | null; + email: `${string}@${string}.${string}`; + fullName: string; + /** @deprecated This has no purpose and should never be used. */ + gid: number | null; + id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + newUser: boolean | null; + phoneNumber: string | null; + postalCode: string | null; + publicSshKey: string | null; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + registrationSent?: null | Date; + role: number; + stateOrProvince: null; + tenant: string; + tenantID?: never; + tenantId: number; + /** @deprecated This has no purpose and should never be used. */ + uid: number | null; + username: string; +} + +/** Represents a response from /users to a PUT or POST request. */ +export interface PutOrPostResponseUser extends ResponseUser { + /** + * This appears only in response to POST requests, or to PUT requests where + * the user's password was changed. + */ + confirmLocalPasswd?: string; + rolename?: never; + roleName: string; +} + +/** Represents a response from /users to a GET request. */ +export interface GetResponseUser extends ResponseUser { + confirmLocalPasswd?: never; + rolename: string; + roleName?: never; +} + +/** + * User generically represents a user in the context of a PUT, POST, or GET + * request or response to/from /users. + */ +export type User = PutRequestUser | PostRequestUser | PutOrPostResponseUser | GetResponseUser; + +/** + * ResponseCurrentUser represents a response from /user/current. + */ +export interface ResponseCurrentUser { + addressLine1: string | null; + addressLine2: string | null; + city: string | null; + company: string | null; + country: string | null; + email: `${string}@${string}.${string}`; + fullName: string; + gid: number | null; + id: number; + /** + * This is actually a string that represents a date/time, in a custom + * format. Refer to + * [the Traffic Ops API documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format) + * for details. + */ + lastUpdated: Date; + localUser: boolean; + newUser: boolean; + phoneNumber: string | null; + postalCode: string | null; + publicSshKey: string | null; + role: number; + rolename?: never; + roleName: string; + stateOrProvince: string | null; + tenant: string; + tenantId: number; + uid: number | null; + username: string; +} + +/** + * Currently, a request to /user/current has no properties. This bug is tracked + * by apache/trafficcontrol#6367. + */ +export interface RequestCurrentUser { + addressLine1?: string | null; + addressLine2?: string | null; + city?: string | null; + company?: string | null; + country?: string | null; + /** + * Note that while this is allowed to be null or undefined, it will **not** + * be allowed to be either of those things as a property of a + * {@link PostRequestUser} nor as a property of a {@link PutRequestUser}. + * This means that setting it as such can cause problems for future requests + * and should be avoided whenever possible. + */ + email?: string | null; + /** + * Note that while this is allowed to be null or undefined, it will **not** + * be allowed to be either of those things as a property of a + * {@link PostRequestUser} nor as a property of a {@link PutRequestUser}. + * This means that setting it as such can cause problems for future requests + * and should be avoided whenever possible. + */ + fullName?: string | null; + /** + * @deprecated This serves no purpose and is subject to removal in the + * future. + */ + gid?: string | null; + localUser?: boolean | null; + newUser?: boolean | null; + phoneNumber?: string | null; + postalCode?: string | null; + publicSshKey?: string | null; + /** + * Unlike in virtually every other context, this is allowed to be `null` or + * undefined. In that case, it has the meaning "leave this unchanged" rather + * than setting it to `null` as with most other properties. + */ + role?: number | null; + stateOrProvince?: string | null; + /** + * Unlike in virtually every other context, this is allowed to be `null` or + * undefined. In that case, it has the meaning "leave this unchanged" rather + * than setting it to `null` as with most other properties. + */ + tenantId?: number | null; + tenantID?: never; + /** + * @deprecated This serves no purpose and is subject to removal in the + * future. + */ + uid?: string | null; + /** + * Unlike in virtually every other context, this is allowed to be `null` or + * undefined. In that case, it has the meaning "leave this unchanged" rather + * than setting it to `null` as with most other properties. + */ + username?: never; +} + +/** + * CurrentUser generically represents a "current user" representation in the + * context of either a request or response. This differs from a "user" in a few + * key ways as tracked by apache/trafficcontrol#6299. + */ +export type CurrentUser = ResponseCurrentUser | RequestCurrentUser; diff --git a/src/vault.ts b/src/vault.ts new file mode 100644 index 0000000..9fc84f9 --- /dev/null +++ b/src/vault.ts @@ -0,0 +1,19 @@ +/** + * The type of a response from the `vault/ping` endpoint of the Traffic Ops API. + */ +export interface VaultPing { + status: string; + server: string; +} + +/** + * The type of a response from the `vault/bucket/{{bucket}}/key/{{key}}/values` + * endpoint of the Traffic Ops API. + * + * @deprecated This representation is extremely tightly coupled with the + * deprecated Riak backend Traffic Vault provider, and has been removed from the + * latest API version. + */ +export interface BucketValues { + [bucket: string]: unknown; +}
