api

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2018 License: MIT Imports: 13 Imported by: 5

Documentation

Overview

Package api stores an unversion api

Index

Constants

View Source
const (
	// MinAgentCount are the minimum number of agents per agent pool
	MinAgentCount = 1
	// MaxAgentCount are the maximum number of agents per agent pool
	MaxAgentCount = 100
	// MinPort specifies the minimum tcp port to open
	MinPort = 1
	// MaxPort specifies the maximum tcp port to open
	MaxPort = 65535
	// MaxDisks specifies the maximum attached disks to add to the cluster
	MaxDisks = 4
)

validation values

View Source
const (
	// AvailabilitySet means that the vms are in an availability set
	AvailabilitySet = "AvailabilitySet"
	// VirtualMachineScaleSets means that the vms are in a virtual machine scaleset
	VirtualMachineScaleSets = "VirtualMachineScaleSets"
	// ScaleSetPriorityRegular is the default ScaleSet Priority
	ScaleSetPriorityRegular = "Regular"
	// ScaleSetPriorityLow means the ScaleSet will use Low-priority VMs
	ScaleSetPriorityLow = "Low"
	// ScaleSetEvictionPolicyDelete is the default Eviction Policy for Low-priority VM ScaleSets
	ScaleSetEvictionPolicyDelete = "Delete"
	// ScaleSetEvictionPolicyDeallocate means a Low-priority VM ScaleSet will deallocate, rather than delete, VMs.
	ScaleSetEvictionPolicyDeallocate = "Deallocate"
)

Availability profiles

View Source
const (
	// StorageAccount means that the nodes use raw storage accounts for their os and attached volumes
	StorageAccount = "StorageAccount"
	// ManagedDisks means that the nodes use managed disks for their os and attached volumes
	ManagedDisks = "ManagedDisks"
)

storage profiles

View Source
const (
	// DCOS is the string constant for DCOS orchestrator type and defaults to DCOS188
	DCOS string = "DCOS"
)

the orchestrators supported by vlabs

Variables

This section is empty.

Functions

func ConvertContainerServiceToVLabs

func ConvertContainerServiceToVLabs(api *ContainerService) *vlabs.ContainerService

ConvertContainerServiceToVLabs converts an unversioned ContainerService to a vlabs ContainerService

func ConvertOrchestratorVersionProfileToVLabs

func ConvertOrchestratorVersionProfileToVLabs(api *OrchestratorVersionProfile) *vlabs.OrchestratorVersionProfile

ConvertOrchestratorVersionProfileToVLabs converts an unversioned OrchestratorVersionProfile to a vlabs OrchestratorVersionProfile

func GetOrchestratorVersionProfileListVLabs

func GetOrchestratorVersionProfileListVLabs(version string) (*vlabs.OrchestratorVersionProfileList, error)

GetOrchestratorVersionProfileListVLabs returns vlabs OrchestratorVersionProfileList object per (optionally) specified orchestrator and version

Types

type AgentPoolProfile

type AgentPoolProfile struct {
	Name                         string               `json:"name"`
	Count                        int                  `json:"count"`
	VMSize                       string               `json:"vmSize"`
	OSDiskSizeGB                 int                  `json:"osDiskSizeGB,omitempty"`
	DNSPrefix                    string               `json:"dnsPrefix,omitempty"`
	OSType                       OSType               `json:"osType,omitempty"`
	Ports                        []int                `json:"ports,omitempty"`
	AvailabilityProfile          string               `json:"availabilityProfile"`
	ScaleSetPriority             string               `json:"scaleSetPriority,omitempty"`
	ScaleSetEvictionPolicy       string               `json:"scaleSetEvictionPolicy,omitempty"`
	StorageProfile               string               `json:"storageProfile,omitempty"`
	DiskSizesGB                  []int                `json:"diskSizesGB,omitempty"`
	VnetSubnetID                 string               `json:"vnetSubnetID,omitempty"`
	Subnet                       string               `json:"subnet"`
	IPAddressCount               int                  `json:"ipAddressCount,omitempty"`
	Distro                       Distro               `json:"distro,omitempty"`
	Role                         AgentPoolProfileRole `json:"role,omitempty"`
	AcceleratedNetworkingEnabled bool                 `json:"acceleratedNetworkingEnabled,omitempty"`

	FQDN                   string            `json:"fqdn,omitempty"`
	CustomNodeLabels       map[string]string `json:"customNodeLabels,omitempty"`
	PreprovisionExtension  *Extension        `json:"preProvisionExtension"`
	PostprovisionExtension *Extension        `json:"postProvisionExtension"`
	Extensions             []Extension       `json:"extensions"`
	ImageRef               *ImageReference   `json:"imageReference,omitempty"`
}

AgentPoolProfile represents an agent pool definition

func (*AgentPoolProfile) HasDisks

func (a *AgentPoolProfile) HasDisks() bool

HasDisks returns true if the customer specified disks

func (*AgentPoolProfile) IsAcceleratedNetworkingEnabled

func (a *AgentPoolProfile) IsAcceleratedNetworkingEnabled() bool

IsAcceleratedNetworkingEnabled returns true if the customer enabled Accelerated Networking

func (*AgentPoolProfile) IsAvailabilitySets

func (a *AgentPoolProfile) IsAvailabilitySets() bool

IsAvailabilitySets returns true if the customer specified disks

func (*AgentPoolProfile) IsCoreOS

func (a *AgentPoolProfile) IsCoreOS() bool

IsCoreOS returns true if the agent specified a CoreOS distro

func (*AgentPoolProfile) IsCustomVNET

func (a *AgentPoolProfile) IsCustomVNET() bool

IsCustomVNET returns true if the customer brought their own VNET

func (*AgentPoolProfile) IsLinux

func (a *AgentPoolProfile) IsLinux() bool

IsLinux returns true if the agent pool is linux

func (*AgentPoolProfile) IsLowPriorityScaleSet

func (a *AgentPoolProfile) IsLowPriorityScaleSet() bool

IsLowPriorityScaleSet returns true if the VMSS is Low Priority

func (*AgentPoolProfile) IsManagedDisks

func (a *AgentPoolProfile) IsManagedDisks() bool

IsManagedDisks returns true if the customer specified disks

func (*AgentPoolProfile) IsRHEL

func (a *AgentPoolProfile) IsRHEL() bool

IsRHEL returns true if the agent pool specified a RHEL distro

func (*AgentPoolProfile) IsStorageAccount

func (a *AgentPoolProfile) IsStorageAccount() bool

IsStorageAccount returns true if the customer specified storage account

func (*AgentPoolProfile) IsVirtualMachineScaleSets

func (a *AgentPoolProfile) IsVirtualMachineScaleSets() bool

IsVirtualMachineScaleSets returns true if the agent pool availability profile is VMSS

func (*AgentPoolProfile) IsWindows

func (a *AgentPoolProfile) IsWindows() bool

IsWindows returns true if the agent pool is windows

type AgentPoolProfileRole

type AgentPoolProfileRole string

AgentPoolProfileRole represents an agent role

const (
	// AgentPoolProfileRoleEmpty is the empty role
	AgentPoolProfileRoleEmpty AgentPoolProfileRole = ""
	// AgentPoolProfileRoleInfra is the infra role
	AgentPoolProfileRoleInfra AgentPoolProfileRole = "infra"
)

type Apiloader

type Apiloader struct {
	Translator *i18n.Translator
}

Apiloader represents the object that loads api model

func (*Apiloader) DeserializeContainerService

func (a *Apiloader) DeserializeContainerService(contents []byte, validate, isUpdate bool, existingContainerService *ContainerService) (*ContainerService, string, error)

DeserializeContainerService loads an ACS Cluster API Model, validates it, and returns the unversioned representation

func (*Apiloader) LoadContainerService

func (a *Apiloader) LoadContainerService(
	contents []byte,
	version string,
	validate, isUpdate bool,
	existingContainerService *ContainerService) (*ContainerService, error)

LoadContainerService loads an ACS Cluster API Model, validates it, and returns the unversioned representation

func (*Apiloader) LoadContainerServiceFromFile

func (a *Apiloader) LoadContainerServiceFromFile(jsonFile string, validate, isUpdate bool, existingContainerService *ContainerService) (*ContainerService, string, error)

LoadContainerServiceFromFile loads an ACS Cluster API Model from a JSON file

func (*Apiloader) SerializeContainerService

func (a *Apiloader) SerializeContainerService(containerService *ContainerService, version string) ([]byte, error)

SerializeContainerService takes an unversioned container service and returns the bytes

type BootstrapProfile

type BootstrapProfile struct {
	BootstrapURL  string                 `json:"bootstrapURL,omitempty"`
	DockerVersion string                 `json:"dockerVersion,omitempty"`
	Hosted        bool                   `json:"hosted,omitempty"`
	VMSize        string                 `json:"vmSize,omitempty"`
	OSDiskSizeGB  int                    `json:"osDiskSizeGB,omitempty"`
	StaticIP      string                 `json:"staticIP,omitempty"`
	HasPublicIP   bool                   `json:"hasPublicIP,omitempty"`
	Subnet        string                 `json:"subnet,omitempty"`
	EnableIPv6    bool                   `json:"enableIPv6,omitempty"`
	ExtraConfigs  map[string]interface{} `json:"extraConfigs,omitempty"`
}

BootstrapProfile represents the definition of the DCOS bootstrap node used to deploy the cluster

type ContainerService

type ContainerService struct {
	ID       string                `json:"id"`
	Location string                `json:"location"`
	Name     string                `json:"name"`
	Plan     *ResourcePurchasePlan `json:"plan,omitempty"`
	Tags     map[string]string     `json:"tags"`
	Type     string                `json:"type"`

	Properties *Properties `json:"properties,omitempty"`
}

ContainerService complies with the ARM model of resource definition in a JSON template.

func ConvertVLabsContainerService

func ConvertVLabsContainerService(vlabs *vlabs.ContainerService) *ContainerService

ConvertVLabsContainerService converts a vlabs ContainerService to an unversioned ContainerService

type CustomFile

type CustomFile struct {
	Source string `json:"source,omitempty"`
	Dest   string `json:"dest,omitempty"`
}

CustomFile has source as the full absolute source path to a file and dest is the full absolute desired destination path to put the file on a master node

type CustomNodesDNS

type CustomNodesDNS struct {
	DNSServer string `json:"dnsServer,omitempty"`
}

CustomNodesDNS represents the Search Domain when the custom vnet for a custom DNS as a nameserver.

type CustomProfile

type CustomProfile struct {
	Orchestrator string `json:"orchestrator,omitempty"`
}

CustomProfile specifies custom properties that are used for cluster instantiation. Should not be used by most users.

type CustomSearchDomain

type CustomSearchDomain struct {
	Name          string `json:"name,omitempty"`
	RealmUser     string `json:"realmUser,omitempty"`
	RealmPassword string `json:"realmPassword,omitempty"`
}

CustomSearchDomain represents the Search Domain when the custom vnet has a windows server DNS as a nameserver.

type DiagnosticsProfile

type DiagnosticsProfile struct {
	VMDiagnostics *VMDiagnostics `json:"vmDiagnostics"`
}

DiagnosticsProfile setting to enable/disable capturing diagnostics for VMs hosting container cluster.

type Distro

type Distro string

Distro represents Linux distro to use for Linux VMs

const (
	Ubuntu Distro = "ubuntu"
	RHEL   Distro = "rhel"
	CoreOS Distro = "coreos"
)

the LinuxDistros supported by vlabs

type Extension

type Extension struct {
	Name        string `json:"name"`
	SingleOrAll string `json:"singleOrAll"`
	Template    string `json:"template"`
}

Extension represents an extension definition in the master or agentPoolProfile

type ExtensionProfile

type ExtensionProfile struct {
	Name                           string             `json:"name"`
	Version                        string             `json:"version"`
	ExtensionParameters            string             `json:"extensionParameters,omitempty"`
	ExtensionParametersKeyVaultRef *KeyvaultSecretRef `json:"parametersKeyvaultSecretRef,omitempty"`
	RootURL                        string             `json:"rootURL,omitempty"`
	// This is only needed for preprovision extensions and it needs to be a bash script
	Script   string `json:"script,omitempty"`
	URLQuery string `json:"urlQuery,omitempty"`
}

ExtensionProfile represents an extension definition

type ImageReference

type ImageReference struct {
	Name          string `json:"name,omitempty"`
	ResourceGroup string `json:"resourceGroup,omitempty"`
}

ImageReference represents a reference to an Image resource in Azure.

type KeyVaultCertificate

type KeyVaultCertificate struct {
	CertificateURL   string `json:"certificateUrl,omitempty"`
	CertificateStore string `json:"certificateStore,omitempty"`
}

KeyVaultCertificate specifies a certificate to install On Linux, the certificate file is placed under the /var/lib/waagent directory with the file name <UppercaseThumbprint>.crt for the X509 certificate file and <UppercaseThumbprint>.prv for the private key. Both of these files are .pem formatted. On windows the certificate will be saved in the specified store.

type KeyVaultID

type KeyVaultID struct {
	ID string `json:"id,omitempty"`
}

KeyVaultID specifies a key vault

type KeyVaultSecrets

type KeyVaultSecrets struct {
	SourceVault       *KeyVaultID           `json:"sourceVault,omitempty"`
	VaultCertificates []KeyVaultCertificate `json:"vaultCertificates,omitempty"`
}

KeyVaultSecrets specifies certificates to install on the pool of machines from a given key vault the key vault specified must have been granted read permissions to CRP

type KeyvaultSecretRef

type KeyvaultSecretRef struct {
	VaultID       string `json:"vaultID"`
	SecretName    string `json:"secretName"`
	SecretVersion string `json:"version,omitempty"`
}

KeyvaultSecretRef specifies path to the Azure keyvault along with secret name and (optionaly) version for Service Principal's secret

type LinuxProfile

type LinuxProfile struct {
	AdminUsername string `json:"adminUsername"`
	SSH           struct {
		PublicKeys []PublicKey `json:"publicKeys"`
	} `json:"ssh"`
	Secrets            []KeyVaultSecrets   `json:"secrets,omitempty"`
	Distro             Distro              `json:"distro,omitempty"`
	ScriptRootURL      string              `json:"scriptroot,omitempty"`
	CustomSearchDomain *CustomSearchDomain `json:"customSearchDomain,omitempty"`
	CustomNodesDNS     *CustomNodesDNS     `json:"CustomNodesDNS,omitempty"`
}

LinuxProfile represents the linux parameters passed to the cluster

func (*LinuxProfile) HasCustomNodesDNS

func (l *LinuxProfile) HasCustomNodesDNS() bool

HasCustomNodesDNS returns true if the customer specified a dns server

func (*LinuxProfile) HasSearchDomain

func (l *LinuxProfile) HasSearchDomain() bool

HasSearchDomain returns true if the customer specified secrets to install

func (*LinuxProfile) HasSecrets

func (l *LinuxProfile) HasSecrets() bool

HasSecrets returns true if the customer specified secrets to install

type MasterProfile

type MasterProfile struct {
	Count                    int             `json:"count"`
	DNSPrefix                string          `json:"dnsPrefix"`
	SubjectAltNames          []string        `json:"subjectAltNames"`
	VMSize                   string          `json:"vmSize"`
	OSDiskSizeGB             int             `json:"osDiskSizeGB,omitempty"`
	VnetSubnetID             string          `json:"vnetSubnetID,omitempty"`
	VnetCidr                 string          `json:"vnetCidr,omitempty"`
	FirstConsecutiveStaticIP string          `json:"firstConsecutiveStaticIP,omitempty"`
	Subnet                   string          `json:"subnet"`
	IPAddressCount           int             `json:"ipAddressCount,omitempty"`
	StorageProfile           string          `json:"storageProfile,omitempty"`
	HTTPSourceAddressPrefix  string          `json:"HTTPSourceAddressPrefix,omitempty"`
	PreprovisionExtension    *Extension      `json:"preProvisionExtension"`
	PostprovisionExtension   *Extension      `json:"postProvisionExtension"`
	Extensions               []Extension     `json:"extensions"`
	Distro                   Distro          `json:"distro,omitempty"`
	ImageRef                 *ImageReference `json:"imageReference,omitempty"`
	CustomFiles              *[]CustomFile   `json:"customFiles,omitempty"`

	// Master LB public endpoint/FQDN with port
	// The format will be FQDN:2376
	// Not used during PUT, returned as part of GET
	FQDN string `json:"fqdn,omitempty"`
}

MasterProfile represents the definition of the master cluster

func (*MasterProfile) IsCoreOS

func (m *MasterProfile) IsCoreOS() bool

IsCoreOS returns true if the master specified a CoreOS distro

func (*MasterProfile) IsCustomVNET

func (m *MasterProfile) IsCustomVNET() bool

IsCustomVNET returns true if the customer brought their own VNET

func (*MasterProfile) IsManagedDisks

func (m *MasterProfile) IsManagedDisks() bool

IsManagedDisks returns true if the master specified managed disks

func (*MasterProfile) IsRHEL

func (m *MasterProfile) IsRHEL() bool

IsRHEL returns true if the master specified a RHEL distro

func (*MasterProfile) IsStorageAccount

func (m *MasterProfile) IsStorageAccount() bool

IsStorageAccount returns true if the master specified storage account

type OSType

type OSType string

OSType represents OS types of agents

const (
	Windows OSType = "Windows"
	Linux   OSType = "Linux"
)

the OSTypes supported by vlabs

type OrchestratorProfile

type OrchestratorProfile struct {
	OrchestratorType        string            `json:"orchestratorType"`
	OrchestratorVersion     string            `json:"orchestratorVersion"`
	OAuthEnabled            bool              `json:"oauthEnabled,omitempty"`
	OpenAccess              bool              `json:"openAccess,omitempty"`
	LinuxBootstrapProfile   *BootstrapProfile `json:"linuxBootstrapProfile,omitempty"`
	WindowsBootstrapProfile *BootstrapProfile `json:"windowsBootstrapProfile,omitempty"`
	Registry                string            `json:"registry,omitempty"`
	RegistryUser            string            `json:"registryUser,omitempty"`
	RegistryPass            string            `json:"registryPassword,omitempty"`
}

OrchestratorProfile contains Orchestrator properties

func (*OrchestratorProfile) IsDCOS

func (o *OrchestratorProfile) IsDCOS() bool

IsDCOS returns true if this template is for DCOS orchestrator

func (*OrchestratorProfile) RequireRouteTable

func (o *OrchestratorProfile) RequireRouteTable() bool

RequireRouteTable returns true if this deployment requires routing table

type OrchestratorVersionProfile

type OrchestratorVersionProfile struct {
	// Orchestrator type and version
	OrchestratorProfile
	// Whether this orchestrator version is deployed by default if orchestrator release is not specified
	Default bool `json:"default,omitempty"`
	// List of available upgrades for this orchestrator version
	Upgrades []string `json:"upgrades,omitempty"`
}

OrchestratorVersionProfile contains information of a supported orchestrator version:

func GetOrchestratorVersionProfile

func GetOrchestratorVersionProfile(orch *OrchestratorProfile) (*OrchestratorVersionProfile, error)

GetOrchestratorVersionProfile returns orchestrator info for upgradable container service

type PrivateCluster

type PrivateCluster struct {
	Enabled *bool `json:"enabled,omitempty"`
}

PrivateCluster defines the configuration for a private cluster

type Properties

type Properties struct {
	ProvisioningState       ProvisioningState        `json:"provisioningState,omitempty"`
	OrchestratorProfile     *OrchestratorProfile     `json:"orchestratorProfile,omitempty"`
	MasterProfile           *MasterProfile           `json:"masterProfile,omitempty"`
	AgentPoolProfiles       []*AgentPoolProfile      `json:"agentPoolProfiles,omitempty"`
	LinuxProfile            *LinuxProfile            `json:"linuxProfile,omitempty"`
	WindowsProfile          *WindowsProfile          `json:"windowsProfile,omitempty"`
	ExtensionProfiles       []*ExtensionProfile      `json:"extensionProfiles"`
	DiagnosticsProfile      *DiagnosticsProfile      `json:"diagnosticsProfile,omitempty"`
	ServicePrincipalProfile *ServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"`
	CustomProfile           *CustomProfile           `json:"customProfile,omitempty"`
}

Properties represents the ACS cluster definition

func (*Properties) HasManagedDisks

func (p *Properties) HasManagedDisks() bool

HasManagedDisks returns true if the cluster contains Managed Disks

func (*Properties) HasStorageAccountDisks

func (p *Properties) HasStorageAccountDisks() bool

HasStorageAccountDisks returns true if the cluster contains Storage Account Disks

func (*Properties) HasVirtualMachineScaleSets

func (p *Properties) HasVirtualMachineScaleSets() bool

HasVirtualMachineScaleSets returns true if the cluster contains Virtual Machine Scale Sets

func (*Properties) HasWindows

func (p *Properties) HasWindows() bool

HasWindows returns true if the cluster contains windows

func (*Properties) TotalNodes

func (p *Properties) TotalNodes() int

TotalNodes returns the total number of nodes in the cluster configuration

type ProvisioningState

type ProvisioningState string

ProvisioningState represents the current state of container service resource.

const (
	// Creating means ContainerService resource is being created.
	Creating ProvisioningState = "Creating"
	// Updating means an existing ContainerService resource is being updated
	Updating ProvisioningState = "Updating"
	// Failed means resource is in failed state
	Failed ProvisioningState = "Failed"
	// Succeeded means resource created succeeded during last create/update
	Succeeded ProvisioningState = "Succeeded"
	// Deleting means resource is in the process of being deleted
	Deleting ProvisioningState = "Deleting"
	// Migrating means resource is being migrated from one subscription or
	// resource group to another
	Migrating ProvisioningState = "Migrating"
	// Upgrading means an existing ContainerService resource is being upgraded
	Upgrading ProvisioningState = "Upgrading"
)

type PublicKey

type PublicKey struct {
	KeyData string `json:"keyData"`
}

PublicKey represents an SSH key for LinuxProfile

type ResourcePurchasePlan

type ResourcePurchasePlan struct {
	Name          string `json:"name"`
	Product       string `json:"product"`
	PromotionCode string `json:"promotionCode"`
	Publisher     string `json:"publisher"`
}

ResourcePurchasePlan defines resource plan as required by ARM for billing purposes.

type ServicePrincipalProfile

type ServicePrincipalProfile struct {
	ClientID          string             `json:"clientId"`
	Secret            string             `json:"secret,omitempty"`
	ObjectID          string             `json:"objectId,omitempty"`
	KeyvaultSecretRef *KeyvaultSecretRef `json:"keyvaultSecretRef,omitempty"`
}

ServicePrincipalProfile contains the client and secret used by the cluster for Azure Resource CRUD

type TypeMeta

type TypeMeta struct {
	// APIVersion is on every object
	APIVersion string `json:"apiVersion"`
}

TypeMeta describes an individual API model object

type VMDiagnostics

type VMDiagnostics struct {
	Enabled bool `json:"enabled"`

	// Specifies storage account Uri where Boot Diagnostics (CRP &
	// VMSS BootDiagostics) and VM Diagnostics logs (using Linux
	// Diagnostics Extension) will be stored. Uri will be of standard
	// blob domain. i.e. https://storageaccount.blob.core.windows.net/
	// This field is readonly as ACS RP will create a storage account
	// for the customer.
	StorageURL *neturl.URL `json:"storageUrl"`
}

VMDiagnostics contains settings to on/off boot diagnostics collection in RD Host

type VlabsARMContainerService

type VlabsARMContainerService struct {
	TypeMeta
	*vlabs.ContainerService
}

VlabsARMContainerService is the type we read and write from file needed because the json that is sent to ARM and dcos-engine is different from the json that the ACS RP Api gets from ARM

type WindowsProfile

type WindowsProfile struct {
	AdminUsername         string            `json:"adminUsername"`
	AdminPassword         string            `json:"adminPassword"`
	ImageVersion          string            `json:"imageVersion"`
	WindowsImageSourceURL string            `json:"windowsImageSourceURL"`
	WindowsPublisher      string            `json:"windowsPublisher"`
	WindowsOffer          string            `json:"windowsOffer"`
	WindowsSku            string            `json:"windowsSku"`
	Secrets               []KeyVaultSecrets `json:"secrets,omitempty"`
}

WindowsProfile represents the windows parameters passed to the cluster

func (*WindowsProfile) HasCustomImage

func (w *WindowsProfile) HasCustomImage() bool

HasCustomImage returns true if there is a custom windows os image url specified

func (*WindowsProfile) HasSecrets

func (w *WindowsProfile) HasSecrets() bool

HasSecrets returns true if the customer specified secrets to install

Directories

Path Synopsis
Package vlabs stores an experimental api model for acs
Package vlabs stores an experimental api model for acs

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL