Update default access token lifetime to 1 day

= Authentication
{product-author}
{product-version}
:data-uri:
:icons:
:experimental:
:toc: macro
:toc-title:

toc::[]

== Overview

The authentication layer is responsible for identifying the user associated with requests to the OpenShift API. Information about the requesting user is then used by the authorization layer to determine whether the request should be allowed.

== API Authentication

Requests to the OpenShift API are authenticated using the following methods:

* OAuth Access Tokens
** Obtained from the OpenShift OAuth server using the `<master>/oauth/authorize` and `<master>/oauth/token` endpoints
** Sent as an "Authorization: Bearer …" header or an "access_token=…" query parameter
* X.509 Client Certificates
** Requires a https connection to the API server
** Verified by the API server against a trusted certificate authority bundle
** The API server creates and distributes certificates to controllers to authenticate themselves

Any request with an invalid access token or an invalid certificate is rejected by the authentication layer with a 401 error.

If no access token or certificate is presented, the authentication layer assigns the `system:anonymous` user and the `system:unauthenticated` group to the request. This allows the authorization layer to determine which requests (if any) an anonymous user is allowed to make.

== OAuth overview

The OpenShift master includes a built-in OAuth server. End-users obtain OAuth access tokens to authenticate themselves to the API.

When a person requests a new OAuth token, the OAuth server uses the configured identity provider(s) to determine the identity of the person making the request.

It then determines what user that identity maps to, creates an access token for that user, and returns the token for use.

=== OAuth clients

Every request for an OAuth token must specify the OAuth client which will receive and use the token. The following OAuth clients are automatically created when starting the OpenShift API:

 * `openshift-web-console`: used to request tokens for the web console
 * `openshift-browser-client`: used to request tokens at `<master>/oauth/token/request` with a user-agent that can handle interactive logins
 * `openshift-challenging-client`: used to request tokens with a user-agent that can handle `WWW-Authenticate` challenges

To register additional clients:
====
----
osc create -f <(echo '
{
    "kind": "OAuthClient",
    "version": "v1beta1",
    "metadata": {
        "name":"demo" <1>
    },
    "secret": "...", <2>
    "redirectURIs": [
        "http://www.example.com/" <3>
    ]
}')
----
<1> The `name` of the OAuth client is used as the `client_id` parameter when making requests to `<master>/oauth/authorize` and `<master>/oauth/token`.
<2> The `secret` is used as the `client_secret` parameter when making requests to `<master>/oauth/token`.
<3> The `redirect_uri` parameter specified in requests to `<master>/oauth/authorize` and `<master>/oauth/token` must be equal to (or prefixed by) one of the URIs in `redirectURIs`.
====

=== Integrations

All requests for OAuth tokens involve a request to `<master>/oauth/authorize`. Most authentication integrations will place an authenticating proxy in front of this endpoint, or configure OpenShift to validate credentials against a backing identity provider.

Because requests to `<master>/oauth/authorize` can come from user-agents that cannot display interactive login pages (like `osc`), authenticating using a `WWW-Authenticate` challenge is supported in addition to interactive login flows.

If an authenticating proxy is placed in front of the `<master>/oauth/authorize` endpoint, it should send unauthenticated non-browser user-agents `WWW-Authenticate` challenges, rather than displaying an interactive login page or redirecting to an interactive login flow.

If the authenticating proxy cannot support `WWW-Authenticate` challenges (or if OpenShift is configured to use an identity provider that does not support WWW-Authenticate challenges), users can visit `<master>/oauth/token/request` using a browser to obtain an access token manually.

== OAuth configuration

OAuth configuration is specified in the master config file.

When running without a master config file, the `AllowAllPasswordIdentityProvider` identity provider is used, which allows any non-empty username and password to log in. This is useful for test purposes.

To use other identity providers, you must run from a config file. For more information about creating and running from config files, see link:../using_openshift/master_node_configuration.html[Master and Node Configuration].

=== Identity providers

==== Allow All [[AllowAllPasswordIdentityProvider]]

`AllowAllPasswordIdentityProvider` allows any non-empty login and password. This is the default identity provider when running OpenShift without a config file.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_allow_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: AllowAllPasswordIdentityProvider
----
<1> This provider name is prefixed to logins to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
====

==== Deny All [[DenyAllPasswordIdentityProvider]]

`DenyAllPasswordIdentityProvider` denies all username and passwords.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_deny_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: DenyAllPasswordIdentityProvider
----
<1> This provider name is prefixed to logins to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
====

==== HTPasswd [[HTPasswdPasswordIdentityProvider]]

`HTPasswdPasswordIdentityProvider` validates logins and passwords against a flat-file generated using http://httpd.apache.org/docs/2.4/programs/htpasswd.html[htpasswd]

* Only MD5 and SHA encryption types are supported. MD5 encryption is recommended, and is the default for htpasswd. Plaintext, crypt, and bcrypt hashes are not currently supported.
* The file is re-read if its modification time changes, without requiring a server restart
* To create the file: `htpasswd -c </path/to/users.htpasswd> <login>`
* To add or update a login to the file: `htpasswd </path/to/users.htpasswd> <login>`
* To remove a login from the file: `htpasswd </path/to/users.htpasswd> -D <login>`

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_htpasswd_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: HTPasswdPasswordIdentityProvider
      file: /path/to/users.htpasswd <4>
----
<1> This provider name is prefixed to logins to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
<4> File generated using http://httpd.apache.org/docs/2.4/programs/htpasswd.html[htpasswd].
====

==== Basic-Auth (remote) [[BasicAuthPasswordIdentityProvider]]

`BasicAuthPasswordIdentityProvider` validates logins and passwords against a remote server using a server-to-server basic-auth request.

* Logins and passwords are validated against a basic-auth protected, JSON-returning remote URL
* A 401 response indicates failed auth.
* A non-200 status, or the presence of a non-empty "error" key, indicates an error: `{"error":"Error message"}`
* A 200 status with an "id" key indicates success: `{"id":"userid"}`
** The id must be unique to the authenticated user
** The id must not be able to be modified
* A successful response may optionally provide additional data:
** Display name. Example: `{"id":"userid", "name": "User Name", ...}`
** Email address. Example: `{"id":"userid", "email":"user@example.com", ...}`
** Preferred login. This is useful when the unique, unchangeable user id is a database key or UID, and a more human-readable name exists. This is used as a hint when provisioning the OpenShift user for the authenticated identity. Example: `{"id":"014fbff9a07c", "login":"bob", ...}`

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_remote_basic_auth_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: BasicAuthPasswordIdentityProvider
      url: https://www.example.com/remote-idp <4>
      ca: /path/to/ca.file <5>
      certFile: /path/to/client.crt <6>
      keyFile: /path/to/client.key <7>
----
<1> This provider name is prefixed to the returned user id to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
<4> URL accepting credentials in basic-auth headers.
<5> Certificate bundle to use to validate server certificates for the configured URL. Optional.
<6> Client certificate to present when making requests to the configured URL. Optional.
<7> Key for the client certificate. Required if `certFile` is specified.
====

==== Request Header [[RequestHeaderIdentityProvider]]

`RequestHeaderIdentityProvider` identifies users from request header values, like `X-Remote-User`. It is typically used in combination with an authenticating proxy, which sets the request header value.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_request_header_provider <1>
    challenge: false <2>
    login: false <3>
    provider:
      apiVersion: v1
      kind: RequestHeaderIdentityProvider
      clientCA: /path/to/client-ca.file <4>
      headers: <5>
      - X-Remote-User
      - SSO-User
----
<1> This provider name is prefixed to the user id in the request header to form an identity name.
<2> `RequestHeaderIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> `RequestHeaderIdentityProvider` cannot be used to back a login page.
<4> PEM-encoded certificate bundle. If set, a valid client certificate must be presented and validated against the certificate authorities in the specified file before the request headers are checked for usernames. Optional.
<5> Header names to check, in order, for user ids. The first header containing a value is used as the user id. Required, case-insensitive.
====

==== GitHub [[GitHub]]

`GitHubIdentityProvider` uses GitHub as an identity provider, using the OAuth integration.

Note that using GitHub as an identity provider requires users to get a token using `<master>/oauth/token/request` to use with command-line tools.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: github <1>
    challenge: false <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: GitHubIdentityProvider
      clientID: ... <4>
      clientSecret: ... <5>
----
<1> This provider name is prefixed to the GitHub numeric user id to form an identity name. It is also used to build the callback URL.
<2> `GitHubIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to GitHub to log in.
<4> The client id of a link:https://github.com/settings/applications/new[registered GitHub OAuth application]. The application must be configured with a callback URL of `<master>/oauth2callback/<identityProviderName>`
<5> The client secret issued by GitHub.
====

==== Google [[Google]]

`GoogleIdentityProvider` uses Google as an identity provider, using Google's OpenID Connect integration.

See https://developers.google.com/identity/protocols/OpenIDConnect for more information.

Note that using Google as an identity provider requires users to get a token using `<master>/oauth/token/request` to use with command-line tools.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: google <1>
    challenge: false <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: GoogleIdentityProvider
      clientID: ... <4>
      clientSecret: ... <5>
----
<1> This provider name is prefixed to the Google numeric user id to form an identity name. It is also used to build the redirect URL.
<2> `GoogleIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to Google to log in.
<4> The client id of a link:https://console.developers.google.com/[registered Google project]. The project must be configured with a redirect URI of `<master>/oauth2callback/<identityProviderName>`
<5> The client secret issued by Google.
====

==== OpenID Connect [[OpenID]]

`OpenIDIdentityProvider` integrates with an OpenID Connect identity provider, using an link:http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[Authorization Code Flow].

ID Token and UserInfo decryption is not supported.

By default, the `openid` scope is requested. Extra scopes (if needed) can be specified in the `extraScopes` config field.

Claims are read from the JWT `id_token` returned from the OpenID identity provider (and from the JSON returned by the `UserInfo` URL, if specified).

At least one claim must be configured as the claim to use as the user's identity. The link:http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[standard identity claim] is `sub`.

You can also indicate which claims to use as the user's preferred username, display name, and email address. If multiple claims are specified, the first one with a non-empty value is used. The link:http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[standard claims] are:

* `sub` (used as the user identity)
* `preferred_username` (used as the preferred user name when provisioning a user)
* `email` (email address)
* `name` (display name)

Note that using an OpenID Connect identity provider requires users to get a token using `<master>/oauth/token/request` to use with command-line tools.

Standard config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_openid_connect <1>
    challenge: false <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      clientID: ... <4>
      clientSecret: ... <5>
      claims:
        id:
        - sub <6>
        preferredUsername:
        - preferred_username
        name:
        - name
        email:
        - email
      urls:
        authorize: https://myidp.example.com/oauth2/authorize <7>
        token: https://myidp.example.com/oauth2/token <8>
----
<1> This provider name is prefixed to the value of the identity claim to form an identity name. It is also used to build the redirect URL.
<2> `OpenIDIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to the authorize URL to log in.
<4> The client id of a client registered with the OpenID provider. The client must be allowed to redirect to `<master>/oauth2callback/<identityProviderName>`
<5> The client secret.
<6> Use the value of the `sub` claim in the returned `id_token` as the user's identity.
<7> link:http://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint[Authorization Endpoint] described in the OpenID spec. Must use https.
<8> link:http://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint[Token Endpoint] described in the OpenID spec. Must use https.
====

A custom certificate bundle, extra scopes, and UserInfo URL can also be specified.

Full config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_openid_connect
    challenge: false
    login: true
    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      clientID: ...
      clientSecret: ...
      ca: my-openid-ca-bundle.crt <1>
      extraScopes: <2>
      - email
      - profile
      claims:
        id: <3>
        - custom_id_claim
        - sub
        preferredUsername: <4>
        - preferred_username
        - email
        name: <5>
        - nickname
        - given_name
        - name
        email: <6>
        - custom_email_claim
        - email
      urls:
        authorize: https://myidp.example.com/oauth2/authorize
        token: https://myidp.example.com/oauth2/token
        userInfo: https://myidp.example.com/oauth2/userinfo <7>
----
<1> Certificate bundle to use to validate server certificates for the configured URLs. If empty, system trusted roots are used.
<2> List of scopes to request (in addition to the `openid` scope) during the authorization request.
<3> List of claims to use as the identity. First non-empty claim is used. At least one claim is required. If none of the listed claims have a value, authentication will fail.
<4> List of claims to use as the preferred username when provisioning a user for this identity. First non-empty claim is used.
<5> List of claims to use as the display name. First non-empty claim is used.
<6> List of claims to use as the email address. First non-empty claim is used.
<7> link:http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] described in the OpenID spec. Must use https.
====

=== Token options

The OAuth server generates two kinds of tokens.

Authorize codes are short-lived tokens whose only use is to be exchanged for an access token. Set `authorizeTokenMaxAgeSeconds` to control the lifetime of authorize codes. The default lifetime is 5 minutes.

Access tokens are longer-lived tokens that grant access to the API. Set `accessTokenMaxAgeSeconds` to control the lifetime of access tokens. The default lifetime is 24 hours.

Master config:
----
oauthConfig:
  ...
  tokenConfig:
    accessTokenMaxAgeSeconds: 86400
    authorizeTokenMaxAgeSeconds: 300
----

=== Grant options

To configure how the OAuth server responds to token requests for a client the user has not previously granted permission, set the `method` value in the `grantConfig` stanza. Valid values are:

* `auto`
** Auto-approve the grant and retry the request
* `prompt`
** Prompt the user to approve or deny the grant
* `deny`
** Auto-deny the grant and return a failure error to the client

Master config:
----
oauthConfig:
  ...
  grantConfig:
    method: auto
----

=== Session options

The OAuth server uses a signed and encrypted cookie-based session during login and redirect flows.

If no `sessionSecretsFile` is specified, a random signing and encryption secret is generated at each start of the master server. This means that any logins in progress will have their sessions invalidated if the master is restarted. It also means that if multiple masters are configured, they will not be able to decode sessions generated by one of the other masters.

To specify the signing and encryption secret to use, specify a `sessionSecretsFile`. This allows you separate secret values from the config file, and keep the config file distributable for debugging, etc.

Master config:
====
----
oauthConfig:
  ...
  sessionConfig:
    sessionMaxAgeSeconds: 300 <1>
    sessionName: ssn <2>
    sessionSecretsFile: "..." <3>
----
<1> Controls the maximum age of a session (sessions auto-expire once a token request is complete). If auto-grant is not enabled, sessions must last as long as the user is expected to take to approve or reject a client authorization request.
<2> Name of the cookie used to store the session.
<3> Filename containing serialized SessionSecrets object. If empty, a random signing and encryption secret is generated at each server start.
====

Multiple secrets can be specified in the `sessionSecretsFile` to enable rotation. New sessions are signed and encrypted using the first secret in the list. Existing sessions are decrypted/authenticated by each secret until one succeeds.

Session secret config:
====
----
apiVersion: v1
kind: SessionSecrets
secrets: <1>
- authentication: "..." <2>
  encryption: "..." <3>
- authentication: "..."
  encryption: "..."
...
----
<1> List of secrets used to authenticate and encrypt cookie sessions. At least one secret must be specified. Each secret must set an authentication and encryption secret.
<2> Signing secret, used to authenticate sessions using HMAC. Recommended to use a secret with 32 or 64 bytes.
<3> Encrypting secret, used to encrypt sessions. Must be 16, 24, or 32 characters long, to select AES-128, AES-192, or AES-256.
====

= Authentication
{product-author}
{product-version}
:data-uri:
:icons:
:experimental:
:toc: macro
:toc-title:

toc::[]

== Overview

The authentication layer is responsible for identifying the user associated with requests to the OpenShift API. Information about the requesting user is then used by the authorization layer to determine whether the request should be allowed.

== API Authentication

Requests to the OpenShift API are authenticated using the following methods:

* OAuth Access Tokens
** Obtained from the OpenShift OAuth server using the `<master>/oauth/authorize` and `<master>/oauth/token` endpoints
** Sent as an "Authorization: Bearer …" header or an "access_token=…" query parameter
* X.509 Client Certificates
** Requires a https connection to the API server
** Verified by the API server against a trusted certificate authority bundle
** The API server creates and distributes certificates to controllers to authenticate themselves

Any request with an invalid access token or an invalid certificate is rejected by the authentication layer with a 401 error.

If no access token or certificate is presented, the authentication layer assigns the `system:anonymous` user and the `system:unauthenticated` group to the request. This allows the authorization layer to determine which requests (if any) an anonymous user is allowed to make.

== OAuth overview

The OpenShift master includes a built-in OAuth server. End-users obtain OAuth access tokens to authenticate themselves to the API.

When a person requests a new OAuth token, the OAuth server uses the configured identity provider(s) to determine the identity of the person making the request.

It then determines what user that identity maps to, creates an access token for that user, and returns the token for use.

=== OAuth clients

Every request for an OAuth token must specify the OAuth client which will receive and use the token. The following OAuth clients are automatically created when starting the OpenShift API:

 * `openshift-web-console`: used to request tokens for the web console
 * `openshift-browser-client`: used to request tokens at `<master>/oauth/token/request` with a user-agent that can handle interactive logins
 * `openshift-challenging-client`: used to request tokens with a user-agent that can handle `WWW-Authenticate` challenges

To register additional clients:
====
----
osc create -f <(echo '
{
    "kind": "OAuthClient",
    "version": "v1beta1",
    "metadata": {
        "name":"demo" <1>
    },
    "secret": "...", <2>
    "redirectURIs": [
        "http://www.example.com/" <3>
    ]
}')
----
<1> The `name` of the OAuth client is used as the `client_id` parameter when making requests to `<master>/oauth/authorize` and `<master>/oauth/token`.
<2> The `secret` is used as the `client_secret` parameter when making requests to `<master>/oauth/token`.
<3> The `redirect_uri` parameter specified in requests to `<master>/oauth/authorize` and `<master>/oauth/token` must be equal to (or prefixed by) one of the URIs in `redirectURIs`.
====

=== Integrations

All requests for OAuth tokens involve a request to `<master>/oauth/authorize`. Most authentication integrations will place an authenticating proxy in front of this endpoint, or configure OpenShift to validate credentials against a backing identity provider.

Because requests to `<master>/oauth/authorize` can come from user-agents that cannot display interactive login pages (like `osc`), authenticating using a `WWW-Authenticate` challenge is supported in addition to interactive login flows.

If an authenticating proxy is placed in front of the `<master>/oauth/authorize` endpoint, it should send unauthenticated non-browser user-agents `WWW-Authenticate` challenges, rather than displaying an interactive login page or redirecting to an interactive login flow.

If the authenticating proxy cannot support `WWW-Authenticate` challenges (or if OpenShift is configured to use an identity provider that does not support WWW-Authenticate challenges), users can visit `<master>/oauth/token/request` using a browser to obtain an access token manually.

== OAuth configuration

OAuth configuration is specified in the master config file.

When running without a master config file, the `AllowAllPasswordIdentityProvider` identity provider is used, which allows any non-empty username and password to log in. This is useful for test purposes.

To use other identity providers, you must run from a config file. For more information about creating and running from config files, see link:../using_openshift/master_node_configuration.html[Master and Node Configuration].

=== Identity providers

==== Allow All [[AllowAllPasswordIdentityProvider]]

`AllowAllPasswordIdentityProvider` allows any non-empty login and password. This is the default identity provider when running OpenShift without a config file.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_allow_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: AllowAllPasswordIdentityProvider
----
<1> This provider name is prefixed to logins to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
====

==== Deny All [[DenyAllPasswordIdentityProvider]]

`DenyAllPasswordIdentityProvider` denies all username and passwords.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_deny_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: DenyAllPasswordIdentityProvider
----
<1> This provider name is prefixed to logins to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
====

==== HTPasswd [[HTPasswdPasswordIdentityProvider]]

`HTPasswdPasswordIdentityProvider` validates logins and passwords against a flat-file generated using http://httpd.apache.org/docs/2.4/programs/htpasswd.html[htpasswd]

* Only MD5 and SHA encryption types are supported. MD5 encryption is recommended, and is the default for htpasswd. Plaintext, crypt, and bcrypt hashes are not currently supported.
* The file is re-read if its modification time changes, without requiring a server restart
* To create the file: `htpasswd -c </path/to/users.htpasswd> <login>`
* To add or update a login to the file: `htpasswd </path/to/users.htpasswd> <login>`
* To remove a login from the file: `htpasswd </path/to/users.htpasswd> -D <login>`

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_htpasswd_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: HTPasswdPasswordIdentityProvider
      file: /path/to/users.htpasswd <4>
----
<1> This provider name is prefixed to logins to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
<4> File generated using http://httpd.apache.org/docs/2.4/programs/htpasswd.html[htpasswd].
====

==== Basic-Auth (remote) [[BasicAuthPasswordIdentityProvider]]

`BasicAuthPasswordIdentityProvider` validates logins and passwords against a remote server using a server-to-server basic-auth request.

* Logins and passwords are validated against a basic-auth protected, JSON-returning remote URL
* A 401 response indicates failed auth.
* A non-200 status, or the presence of a non-empty "error" key, indicates an error: `{"error":"Error message"}`
* A 200 status with an "id" key indicates success: `{"id":"userid"}`
** The id must be unique to the authenticated user
** The id must not be able to be modified
* A successful response may optionally provide additional data:
** Display name. Example: `{"id":"userid", "name": "User Name", ...}`
** Email address. Example: `{"id":"userid", "email":"user@example.com", ...}`
** Preferred login. This is useful when the unique, unchangeable user id is a database key or UID, and a more human-readable name exists. This is used as a hint when provisioning the OpenShift user for the authenticated identity. Example: `{"id":"014fbff9a07c", "login":"bob", ...}`

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_remote_basic_auth_provider <1>
    challenge: true <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: BasicAuthPasswordIdentityProvider
      url: https://www.example.com/remote-idp <4>
      ca: /path/to/ca.file <5>
      certFile: /path/to/client.crt <6>
      keyFile: /path/to/client.key <7>
----
<1> This provider name is prefixed to the returned user id to form an identity name.
<2> When `true`, unauthenticated token requests from non-web clients (like `osc`) will be sent a WWW-Authenticate challenge header for this provider.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to a login page backed by this provider.
<4> URL accepting credentials in basic-auth headers.
<5> Certificate bundle to use to validate server certificates for the configured URL. Optional.
<6> Client certificate to present when making requests to the configured URL. Optional.
<7> Key for the client certificate. Required if `certFile` is specified.
====

==== Request Header [[RequestHeaderIdentityProvider]]

`RequestHeaderIdentityProvider` identifies users from request header values, like `X-Remote-User`. It is typically used in combination with an authenticating proxy, which sets the request header value.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_request_header_provider <1>
    challenge: false <2>
    login: false <3>
    provider:
      apiVersion: v1
      kind: RequestHeaderIdentityProvider
      clientCA: /path/to/client-ca.file <4>
      headers: <5>
      - X-Remote-User
      - SSO-User
----
<1> This provider name is prefixed to the user id in the request header to form an identity name.
<2> `RequestHeaderIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> `RequestHeaderIdentityProvider` cannot be used to back a login page.
<4> PEM-encoded certificate bundle. If set, a valid client certificate must be presented and validated against the certificate authorities in the specified file before the request headers are checked for usernames. Optional.
<5> Header names to check, in order, for user ids. The first header containing a value is used as the user id. Required, case-insensitive.
====

==== GitHub [[GitHub]]

`GitHubIdentityProvider` uses GitHub as an identity provider, using the OAuth integration.

Note that using GitHub as an identity provider requires users to get a token using `<master>/oauth/token/request` to use with command-line tools.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: github <1>
    challenge: false <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: GitHubIdentityProvider
      clientID: ... <4>
      clientSecret: ... <5>
----
<1> This provider name is prefixed to the GitHub numeric user id to form an identity name. It is also used to build the callback URL.
<2> `GitHubIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to GitHub to log in.
<4> The client id of a link:https://github.com/settings/applications/new[registered GitHub OAuth application]. The application must be configured with a callback URL of `<master>/oauth2callback/<identityProviderName>`
<5> The client secret issued by GitHub.
====

==== Google [[Google]]

`GoogleIdentityProvider` uses Google as an identity provider, using Google's OpenID Connect integration.

See https://developers.google.com/identity/protocols/OpenIDConnect for more information.

Note that using Google as an identity provider requires users to get a token using `<master>/oauth/token/request` to use with command-line tools.

Master config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: google <1>
    challenge: false <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: GoogleIdentityProvider
      clientID: ... <4>
      clientSecret: ... <5>
----
<1> This provider name is prefixed to the Google numeric user id to form an identity name. It is also used to build the redirect URL.
<2> `GoogleIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to Google to log in.
<4> The client id of a link:https://console.developers.google.com/[registered Google project]. The project must be configured with a redirect URI of `<master>/oauth2callback/<identityProviderName>`
<5> The client secret issued by Google.
====

==== OpenID Connect [[OpenID]]

`OpenIDIdentityProvider` integrates with an OpenID Connect identity provider, using an link:http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[Authorization Code Flow].

ID Token and UserInfo decryption is not supported.

By default, the `openid` scope is requested. Extra scopes (if needed) can be specified in the `extraScopes` config field.

Claims are read from the JWT `id_token` returned from the OpenID identity provider (and from the JSON returned by the `UserInfo` URL, if specified).

At least one claim must be configured as the claim to use as the user's identity. The link:http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[standard identity claim] is `sub`.

You can also indicate which claims to use as the user's preferred username, display name, and email address. If multiple claims are specified, the first one with a non-empty value is used. The link:http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[standard claims] are:

* `sub` (used as the user identity)
* `preferred_username` (used as the preferred user name when provisioning a user)
* `email` (email address)
* `name` (display name)

Note that using an OpenID Connect identity provider requires users to get a token using `<master>/oauth/token/request` to use with command-line tools.

Standard config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_openid_connect <1>
    challenge: false <2>
    login: true <3>
    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      clientID: ... <4>
      clientSecret: ... <5>
      claims:
        id:
        - sub <6>
        preferredUsername:
        - preferred_username
        name:
        - name
        email:
        - email
      urls:
        authorize: https://myidp.example.com/oauth2/authorize <7>
        token: https://myidp.example.com/oauth2/token <8>
----
<1> This provider name is prefixed to the value of the identity claim to form an identity name. It is also used to build the redirect URL.
<2> `OpenIDIdentityProvider` cannot be used to send WWW-Authenticate challenges.
<3> When `true`, unauthenticated token requests from web clients (like the web console) will be redirected to the authorize URL to log in.
<4> The client id of a client registered with the OpenID provider. The client must be allowed to redirect to `<master>/oauth2callback/<identityProviderName>`
<5> The client secret.
<6> Use the value of the `sub` claim in the returned `id_token` as the user's identity.
<7> link:http://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint[Authorization Endpoint] described in the OpenID spec. Must use https.
<8> link:http://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint[Token Endpoint] described in the OpenID spec. Must use https.
====

A custom certificate bundle, extra scopes, and UserInfo URL can also be specified.

Full config:
====
----
oauthConfig:
  ...
  identityProviders:
  - name: my_openid_connect
    challenge: false
    login: true
    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      clientID: ...
      clientSecret: ...
      ca: my-openid-ca-bundle.crt <1>
      extraScopes: <2>
      - email
      - profile
      claims:
        id: <3>
        - custom_id_claim
        - sub
        preferredUsername: <4>
        - preferred_username
        - email
        name: <5>
        - nickname
        - given_name
        - name
        email: <6>
        - custom_email_claim
        - email
      urls:
        authorize: https://myidp.example.com/oauth2/authorize
        token: https://myidp.example.com/oauth2/token
        userInfo: https://myidp.example.com/oauth2/userinfo <7>
----
<1> Certificate bundle to use to validate server certificates for the configured URLs. If empty, system trusted roots are used.
<2> List of scopes to request (in addition to the `openid` scope) during the authorization request.
<3> List of claims to use as the identity. First non-empty claim is used. At least one claim is required. If none of the listed claims have a value, authentication will fail.
<4> List of claims to use as the preferred username when provisioning a user for this identity. First non-empty claim is used.
<5> List of claims to use as the display name. First non-empty claim is used.
<6> List of claims to use as the email address. First non-empty claim is used.
<7> link:http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] described in the OpenID spec. Must use https.
====

=== Token options

The OAuth server generates two kinds of tokens.

Authorize codes are short-lived tokens whose only use is to be exchanged for an access token. Set `authorizeTokenMaxAgeSeconds` to control the lifetime of authorize codes. The default lifetime is 5 minutes.

Access tokens are longer-lived tokens that grant access to the API. Set `accessTokenMaxAgeSeconds` to control the lifetime of access tokens. The default lifetime is 1 hour.

Master config:
----
oauthConfig:
  ...
  tokenConfig:
    accessTokenMaxAgeSeconds: 3600
    authorizeTokenMaxAgeSeconds: 300
----

=== Grant options

To configure how the OAuth server responds to token requests for a client the user has not previously granted permission, set the `method` value in the `grantConfig` stanza. Valid values are:

* `auto`
** Auto-approve the grant and retry the request
* `prompt`
** Prompt the user to approve or deny the grant
* `deny`
** Auto-deny the grant and return a failure error to the client

Master config:
----
oauthConfig:
  ...
  grantConfig:
    method: auto
----

=== Session options

The OAuth server uses a signed and encrypted cookie-based session during login and redirect flows.

If no `sessionSecretsFile` is specified, a random signing and encryption secret is generated at each start of the master server. This means that any logins in progress will have their sessions invalidated if the master is restarted. It also means that if multiple masters are configured, they will not be able to decode sessions generated by one of the other masters.

To specify the signing and encryption secret to use, specify a `sessionSecretsFile`. This allows you separate secret values from the config file, and keep the config file distributable for debugging, etc.

Master config:
====
----
oauthConfig:
  ...
  sessionConfig:
    sessionMaxAgeSeconds: 300 <1>
    sessionName: ssn <2>
    sessionSecretsFile: "..." <3>
----
<1> Controls the maximum age of a session (sessions auto-expire once a token request is complete). If auto-grant is not enabled, sessions must last as long as the user is expected to take to approve or reject a client authorization request.
<2> Name of the cookie used to store the session.
<3> Filename containing serialized SessionSecrets object. If empty, a random signing and encryption secret is generated at each server start.
====

Multiple secrets can be specified in the `sessionSecretsFile` to enable rotation. New sessions are signed and encrypted using the first secret in the list. Existing sessions are decrypted/authenticated by each secret until one succeeds.

Session secret config:
====
----
apiVersion: v1
kind: SessionSecrets
secrets: <1>
- authentication: "..." <2>
  encryption: "..." <3>
- authentication: "..."
  encryption: "..."
...
----
<1> List of secrets used to authenticate and encrypt cookie sessions. At least one secret must be specified. Each secret must set an authentication and encryption secret.
<2> Signing secret, used to authenticate sessions using HMAC. Recommended to use a secret with 32 or 64 bytes.
<3> Encrypting secret, used to encrypt sessions. Must be 16, 24, or 32 characters long, to select AES-128, AES-192, or AES-256.
====


Docs ServerRSocketFactoryCustomizer->ServerRSocketFactoryProcessor

The documentation incorrectly used ServerRSocketFactoryCustomizer which
was renamed to ServerRSocketFactoryProcessor. The docs now use the correct
class name

Fixes gh-7737


code updates

code updates

// Module included in the following assemblies:
//
// * virt/virtual_machines/advanced_vm_management/virt-configuring-a-watchdog.adoc

[id="virt-defining-a-watchdog"]
= Defining a watchdog device

Define how the watchdog proceeds when the operating system (OS) no longer responds.

.Available actions
[horizontal]
`poweroff`:: The virtual machine (VM) powers down immediately.
`reset`:: The VM reboots in place and the guest OS cannot react. Because the length of time required for the guest OS to reboot can cause liveness probes to timeout, use of this option is discouraged. This timeout can extend the time it takes the VM to reboot if cluster-level protections notice the liveness probe failed and forcibly reschedule it.
`shutdown`:: The VM gracefully powers down by stopping all services.

.Procedure

. Create a YAML file with the following contents:

+
[source,yaml]
----
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  labels:
    kubevirt.io/vm: vm2-rhel84-watchdog
  name: <vm-name>
spec:
  running: false
  template:
    metadata:
     labels:
        kubevirt.io/vm: vm2-rhel84-watchdog
    spec:
      domain:
        devices:
          watchdog:
            name: <watchdog>
            i6300esb:
              action: "poweroff" <1>
...
----
<1> Specify the `watchdog` action (`poweroff`, `reset`, or `shutdown`).

+
The example above configures the `i6300esb` watchdog device on a RHEL8 VM with the poweroff action and exposes the device as `/dev/watchdog`.
+
This device can now be used by the watchdog binary.

. Apply the YAML file to your cluster by running the following command:

+
[source,yaml]
----
$ oc apply -f <file_name>.yaml
----

.Verification

--
[IMPORTANT]
====
This procedure is provided for testing watchdog functionality only and must not be run on production machines.
====
--

. Run the following command to verify that the VM is connected to the watchdog device:

+
[source,terminal]
----
$ lspci | grep watchdog -i
----

. Run one of the following commands to confirm the watchdog is active:

* Trigger a kernel panic:
+
[source,terminal]
----
# echo c > /proc/sysrq-trigger
----

* Terminate the watchdog service:
+
[source,terminal]
----
# pkill -9 watchdog
----

// Module included in the following assemblies:
//
// * virt/virtual_machines/advanced_vm_management/virt-configuring-a-watchdog.adoc

[id="virt-defining-a-watchdog"]
= Defining a watchdog device

Define how the watchdog proceeds when the operating system (OS) no longer responds.

.Available actions
[horizontal]
`poweroff`:: The virtual machine (VM) powers down immediately.
`reset`:: The VM reboots in place and the guest OS cannot react. Because the length of time required for the guest OS to reboot can cause liveness probes to timeout, use of this option is discouraged. This timeout can extend the time it takes the VM to reboot if cluster-level protections notice the liveness probe failed and forcibly reschedule it.
`shutdown`:: The VM gracefully powers down by stopping all services.

.Procedure

. Create a YAML file with the following contents:

+
[source,yaml]
----
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  labels:
    kubevirt.io/vm: vm2-rhel84-watchdog
  name: <vm-name>
spec:
  running: false
  template:
    metadata:
     labels:
        kubevirt.io/vm: vm2-rhel84-watchdog
    spec:
      domain:
        devices:
          watchdog:
            name: <watchdog>
            i6300esb:
              action: "poweroff" <1>
...
----
<1> Specify the `watchdog` action (`poweroff`, `reset`, or `shutdown`).

+
The example above configures the `i6300esb` watchdog device on a RHEL8 VM with the poweroff action and exposes the device as `/dev/watchdog`.
+
This device can now be used by the watchdog binary.

. Apply the YAML file to your cluster by running the following command:

+
[source,yaml]
----
$ oc apply -f <file_name>.yaml
----

.Verification

--
[IMPORTANT]
====
This procedure is provided for testing watchdog functionality only and must not be run on production machines.
====
--

. Run the following command to verify that the VM is connected to the watchdog device:

+
[source,terminal]
----
$ lspci | grep watchdog -i
----

. Run one of the following commands to confirm the watchdog is active:

* Trigger a kernel panic:
+
[source,terminal]
----
$ echo c > /proc/sysrq-trigger
----

* Terminate the watchdog service:
+
[source,terminal]
----
$ kill -9 pgrep watchdog
----


Title "IDE plugin" changed. Typo fix.

Title "IDE plugin" changed. Typo fix.

= Getting started
:toc:
:icons: font
:linkcss!:

== Download

In this download area, you will be able to download the distribution (binary and source), the Windows installer (for some of the versions) and the documentation for **Groovy**.

For a quick and effortless start on Mac OSX, Linux or Cygwin, you can use link:http://gvmtool.net[GVM] (the Groovy enVironment Manager) to download and configure any **Groovy** version of your choice. Basic (TODO)[instructions] can be found below.

=== Groovy 2.1

==== Groovy 2.1.6

==== Groovy 2.1.5

=== Groovy 2.2

==== Groovy 2.2.0-beta-1

=== Groovy 2.0

==== Groovy 2.0.8

=== Groovy 1.8 (Maintenance Release)

==== Groovy 1.8.9

=== Snapshots

=== Older Releases

==== Groovy 1.7.11

==== Groovy 1.6.9

==== Groovy 1.5.8

=== Legacy Groovy 1.0

== Maven Repositories

=== Groovy 2.0.X  and newer

=== Groovy 1.6.X - 1.8.X

=== Groovy 1.1.X - 1.5.X

=== Groovy 1.0

=== Snapshot Releases

== GVM (the Groovy enVironment Manager)

== Other ways to get Groovy

=== Installation on Mac OS X

==== MacPorts

Set up link:http://www.macports.org[MacPorts] and type in the Terminal:

[source,shell]
----
sudo port install groovy
----

==== Homebrew

=== Installation on Windows

=== Other Distributions

=== Source Code

=== IDE plugin

== Install Binary

These instructions describe how to install a binary distribution of **Groovy**.

* First, link:#download-groovy[Download] a binary distribution of Groovy and unpack it into some file on your local file system.
* Set your ++GROOVY_HOME++ environment variable to the directory you unpacked the distribution.
* Add ++GROOVY_HOME/bin++ to your ++PATH++ environment variable.
* Set your ++JAVA_HOME++ environment variable to point to your JDK. On OS X this is ++/Library/Java/Home++, on other unixes its often ++/usr/java++ etc. If you've already installed tools like Ant or Maven you've probably already done this step.

You should now have Groovy installed properly. You can test this by typing the following in a command shell:

[source,shell]
----
groovysh
----

Which should create an interactive groovy shell where you can type Groovy statements. Or to run the link:tools/tools-groovyconsole.html[Swing interactive console] type:

[source,shell]
----
groovyConsole
----

To run a specific Groovy script type:

[source,shell]
----
groovy SomeScript.groovy
----

= Getting started
:toc:
:icons: font
:linkcss!:

== Download

In this download area, you will be able to download the distribution (binary and source), the Windows installer (for some of the versions) and the documentation for **Groovy**.

For a quick and effortless start on Mac OSX, Linux or Cygwin, you can use link:http://gvmtool.net[GVM] (the Groovy enVironment Manager) to download and configure any **Groovy** version of your choice. Basic (TODO)[instructions] can be found below.

=== Groovy 2.1

==== Groovy 2.1.6

==== Groovy 2.1.5

=== Groovy 2.2

==== Groovy 2.2.0-beta-1

=== Groovy 2.0

==== Groovy 2.0.8

=== Groovy 1.8 (Maintenance Release)

==== Groovy 1.8.9

=== Snapshots

=== Older Releases

==== Groovy 1.7.11

==== Groovy 1.6.9

==== Groovy 1.5.8

=== Legacy Groovy 1.0

== Maven Repositories

=== Groovy 2.0.X  and newer

=== Groovy 1.6.X - 1.8.X

=== Groovy 1.1.X - 1.5.X

=== Groovy 1.0

=== Snapshot Releases

== GVM (the Groovy enVironment Manager)

== Other ways to get Groovy

=== Installation on Mac OS X

==== MacPorts

Set up link:http://www.macports.org[MacPorts] and type in the Terminal:

[source,shell]
----
sudo port install groovy
----

==== Homebrew

=== Installation on Windows

=== Other Distributions

=== Source Code

== IDE plugin

== Install Binary

These instructions describe how to install a binary distribution of **Groovy**.

* First, link:#download-groovy[Download] a binary distribution of Groovy and unpack it into some file on your local file system.
* Set your ++GROOVY_HOME++ environment variable to the directory you unpacked the distribution.
* Add ++GROOVY_HOME/bin++ to your ++PATH++ environment variable.
* Set your ++JAVA_HOME++ environment variable to point to your JDK. On OS X this is ++/Library/Java/Home++, on other unixes its often ++/usr/java++ etc. If you've already installed tools like Ant or Maven you've probably already done this step.

You should now have Groovy installed properly. You can test this by typing the following in a command shell:

[source,shell]
----
groovysh
----

Which should create an interactive groovy shell where you can type Groovy statements. Or to run the link:tools/tools-groovyconsole.html[Swing interactive console] type:

[source,shell]
----
groovyConsole
----

To run a specific Groovy script type:

[source,shell]
----
groovy SomeScript.groovy
----


vscode

vscode

= Tech lab 04 (version 3)

== Overall goal

Track, with Github, Microsoft Azure and possibly ServiceNow, the course material on a technical level.

== Section II priorities: it's all about the team.

. Recommended editor: VSCode

. Figure out public/private key for Github.

. Form 3 teams.

. Each team member: Get a free student account for Azure. (Not sure if there is an approval cycle.) Do NOT give them a credit card.

. Spin up a VM and access it there.

. Get some software (any of the things we worked on last week) running on it in a way that others can view (preferably a simple curl that returns a string or a number).

. Put that software into version control, in the aitm-labs/svc* repo as appropriate. I control those repos? How do you do this using GitHub?

. Explore the Microsoft work management / Kanban capabilities. Connect them to Github pull requests. Update your software and ensure that the person making the changes does not push to master, but instead issues a pull request of a team mate (basic peer review).

. Connect Azure pipelines with GitHub so that you can automatically deploy on commit from Github.

= Tech lab 04 (version 3)

== Overall goal

Track, with Github, Microsoft Azure and possibly ServiceNow, the course material on a technical level.

== Section II priorities: it's all about the team.

. Recommended editor: VSCode

. Form 3 teams.

. Each team member: Get a free student account for Azure. (Not sure if there is an approval cycle.) Do NOT give them a credit card.

. Spin up a VM and access it there.

. Get some software (any of the things we worked on last week) running on it in a way that others can view (preferably a simple curl that returns a string or a number).

. Put that software into version control, in the aitm-labs/svc* repo as appropriate. I control those repos? How do you do this using GitHub?

. Explore the Microsoft work management / Kanban capabilities. Connect them to Github pull requests. Update your software and ensure that the person making the changes does not push to master, but instead issues a pull request of a team mate (basic peer review).

. Connect Azure pipelines with GitHub so that you can automatically deploy on commit from Github.


QUick starts above fold

QUick starts above fold

= Funcatron
:toc:

== Quick Starts

link:/master/funcatron/info/spring_boot.html[Spring Boot Quickstart].

link:/master/funcatron/info/dev_intro.html[Lambda-style Quickstart].

== About

Serverless on Your Cluster:

* Define Endpoints in Swagger
* Write Functions in Java, Scala, Clojure, Python, or JavaScript
* Deploy to Mesos, Kubernets, or Swarm
* Autoscale

_Funcatron let's you deploy serverless on any cloud provider or in your
private cloud. Focus on the functions, avoid vendor lock-in._

This document sets out the goals for the http://funcatron.org[Funcatron] project.

### Getting Started w/Spring Boot

If you've already got a https://spring.io/guides/gs/spring-boot/[Spring Boot]
app and you want to run it in Funcatron... you're in luck. Add a few dependencies
and 2 classes to your existing Spring Boot app and you're good to go.
The link:/master/funcatron/info/spring_boot.html[Spring Boot Quickstart]
gets you started... quickly.

And check out the link:/master/funcatron/info/architecture_strategy.html[Architecture
Strategy] for a deeper dive into Funcatron.

### Getting Started Lambda-style

"`Lambdas`" are small units of computing... Funcations. Funcatron
supports writing small funcations, associating them with REST endpoints,
and autoscaling. The
link:/master/funcatron/info/dev_intro.html[Developer Intro] to
Funcatron walks you through building Funcatron bundles Lambda-style.

And check out the link:/master/funcatron/info/architecture_strategy.html[Architecture
Strategy] for a deeper dive into Funcatron.

### What's Funcatron

Amazon's https://aws.amazon.com/lambda/[Lambda] popularized
http://www.martinfowler.com/articles/serverless.html["`serverless`"]
code deployment. It's dead simple: associate a "`function`" with an event.
Each time the event happens, the function is applied and the function's
return value is returned to the event source. An event could be an HTTP(S)
request, something on an event queue, whatever.

Functions are ephemeral. They exist for the duration of the function call.
Once the function returns a value, all of its state and scope and everything
else about it is assumed to go away.

Scaling this kind of architecture is simple: the more frequently a function gets
applied, the more compute resources are allocated to support the function...
and https://en.wikipedia.org/wiki/Bob%27s_your_uncle[Bob's Your Uncle].

The current popular function runners (competitors to Amazon's Lambda), however, are
proprietary: when you write to the API for Lambda or Google's
https://cloud.google.com/functions/docs/[Cloud Functions],
_**you're locked into that vendor**_.

There's currently no (well, there's https://developer.ibm.com/openwhisk/[OpenWhisk])
generic way to do the auto-scale function thing on a private cloud or in a
way that can migrate from one cloud provider to another.

Funcatron addresses this. Funcatron is a cloud-provider-neutral mechanism for
developing, testing, and deploying auto-scalable functions.

Funcatron is designed to run on container orchestration clusters:
https://mesosphere.com/[Mesos], http://kubernetes.io/[Kubernetes], or
https://docker.com[Docker Swarm].

### Software Lifecycle

Software goes through a lifecycle:

- Authoring
- Testing
- Staging
- Production
- Debugging

Funcatron addresses software at each stage of the lifecycle.

#### Authoring

An engineers sits down to write software. The faster the turn-around between
code written and "`trying it out,`" the more productive the engineer will be.

Funcatron supports a "`save, reload`" model where the engineer saves a file
(presuming they're using an IDE that does compilation on save or are using a
non-compiled language), and their function endpoints are available. That's it.
No uploading. No reconfiguration. No waiting. The endpoint is available on save.

Further, the Funcatron model requires knowledge of two things:

* http://swagger.io[Swagger]
* How to write a simple function in Java, Scala, Clojure, Python, or JavaScript.

**That's it.**

The engineer defines the endpoints in Swagger and uses the `operationId` to
specify the function (or class for Java and Scala) to apply when then endpoint
is requested. Funcatron takes care of the rest.

Between the fast turn-around and low "`new stuff to learn`" quotient,
it's easy to get started with Funcatron. It's also easy to stay productive
with Funcatron.

Also, developers need only have Docker installed on their development machine
to live-test Funcatron code.

#### Testing

Because Funcatron endpoints are single functions (or methods on newly
instantiated classes), writing unit tests is simple. Write a unit test and
test the function.

#### Staging

Funcatron code bundles (Funcs) contain a Swagger endpoint definition and the
functions
that are associated with the endpoint and any library code. For JVM languages,
these are bundled into an Uber JAR. For Python, a
https://github.com/pantsbuild/pex[PEX]
file. The Swagger definitions for an endpoint are unique based on
host name and root path.

Funcatron supports aliasing Swagger fields and values in different
environments such that a single Swagger definition can be run
in staging and testing environments without change.
Thus, there's one deployment unit (a Func bundle) that have well defined
behaviors across test, staging, and production servers.

#### Production

Funcatron allows simple deployment and undeployment of end-point collections
defined in Swagger files and implemented in a JVM language, Python, or NodeJS.

Requests are forwarded from Nginx via a message queue to a dispatcher (a Tron).
Based on the hostname and root path, the message is placed on a queue for
a specific Func. The Func processes the request and sends the response
to a reply queue. The Nginx process dequeues the response and returns
it as an HTTP response.

The number of Func instances running on a cluster is based on the queue depth
and response time. The Func manager sends statistics back to the Trons
and the Trons change Func allocation based on these statistics by
communicating with the container orchestration substrate (Mesos, Kubernetes,
Swarm) and changing the allocation of Func running containers.

From the DevOps point of view: deploy a Func and it binds to the appropriate
HTTP endpoint and scales to handle load.

#### Debugging & Test Cases

Funcatron logs a unique request ID and the SHA of the Func with every log line
related to a request. This allows correlation of requests as they fan out through
a cluster.

Funcatron allows dynamic changing log levels on a Func-by-Func basis which allows
capturing more information on demand.

All communications between the front end, Funcs, and back again are via well
defined JSON payloads. Funcatron allows capturing request and response
payloads on a Func-by-Func basis (complete streams, or random sampling).
This data can be used for testing or debugging.

### Architecture

Funcatron has some ambitious goals... and has an architecture to facilitate
achieving these goals.

In all but development mode, Funcatron runs on a Docker container orchestration
system: Mesos, Kubernetes, or Docker Swarm. We call this the "container
substrate." Each of the Funcatron components can be scaled independently with
messages to the container substrate.

For HTTP requests, Funcatron uses Nginx and Lua (via the
http://openresty.org/en/[OpenResty] project) to handle the HTTP requests.
A small
Lua script encodes the request as a payload that's sent to a message broker
(initially RabbitMQ, but this will be pluggable, e.g. Kafka, Redis). For large
request or response bodies, there will be a direct connection between the Front End
and the Runner.
For all but the highest volume installations, 2 Nginx instances
should be sufficient.

Based on the combination of `host` and `pathPrefix` attributes in the Swagger
module definition, the Tron enqueues the request on the appropriate queue.

A Runner module dequeues messages from a number of host/pathPrefix queues and
forwards the request to the appropriate Func. The runner then takes the function
return value and appropriately encodes it and places it on the reply queue which
dequeued by the original endpoint.

Each Func can run multiple modules. Based on queue depth, queue service time,
and CPU usage stats from the Funcs, more runners can be allocated on the substrate,
or more Funcs can be allocated across the runners.

The Lua scripts dequeues the response and turns in into an Nginx response.

Because all of the operation of the Funcs and Trons can be captured as messages
(and all the messages are in JSON), it's possible to capture message streams for
testing and debugging purposes.

Every request has a unique ID and each log line includes the unique ID so it's
possible to correlate a request as it moves across the cluster.

[plantuml]
----
skinparam handwritten true

() "Upload/Enable" as Operator

() "HTTPS Proxy" as Proxy

node "Message Queue" as MQ

package "Public Facing" {
    [Frontend]
}

node {
    [Tron]
    [Runner]
}

Proxy -> [Frontend] : "HTTP port 80"

[Frontend] <--> MQ : Stomp

[Tron] <--> MQ : AMQP

Note left of [Frontend]: Multiple instances

[Frontend] -> [Runner] : "HTTP port 4000"

[Runner] -> [Tron] : "HTTP port 3000"

Note left of [Runner] : Multiple instances\nAuto-scaled

Note left of [Tron] : One instance

Note left of MQ : Cluster

Note left of Operator : Access to control\nFuncatron cluster

[Runner] <--> MQ : AMQP

Operator -> [Tron] : "HTTP port 3000"
----

#### Notes

The initial implementation uses Nginx/OpenResty, RabbitMQ, Java/Scala, and Mesos
to support HTTP requests. This is not "`hardcoded`" but pluggable. Specifically:

* Anything that can enqueue a payload and dequeue the response can
  work with the rest of Funcatron. The initial implementation is HTTP via
  Nginx/OpenResty, but nothing in the rest of the system depends on what enqueues
  the request and dequeues the response.
* RabbitMQ is the initial message broker, but it could be Kafka, Redis, or any other
  message broker. This is pluggable.
* Initially, dispatch from Runners to Funcs will be Java/Scala/Kotlin classes. But the
  dispatch is also pluggable so other languages (Clojure) and
  runtimes (Python, NodeJS, Ruby/Rails) will be supported.
* "`But Swagger is HTTP only`" well... yes and no... the verb and the scheme are
  HTTP-specific, but they can be ignored... and by the time the request is
  dequeued by the Runner, the origin (HTTP or something else) of the message
  is irrelevant. The power of Swagger is two-fold:
  ** Excellent definitions of incoming and outgoing data shapes
  ** Great tooling and lots of general Swagger skills

Because everything in Funcatron is asynchronous messages, how the messages are
passed, where the message originate and where responses are dequeued are all
pluggable and irrelevant to the other parts of the system.

The key idea in Funcatron is the Func is a well defined bundle of functionality
that's associated with a particular message signature that maps to well HTTP via
host, pathPrefix, path, and verb, but could map to something else.

It may be possible to chain Func invocations. I don't yet have a concrete
design, but rather than enqueuing a Func return value as a response, it may
be possible to package it as a request (the request body contains the Func
return value) and forwarding it to another Func for further processing.

Finally, if there's no `reply-to` field in a message, the Func is applied (invoked)
but the results are discarded. This allows for side effects from the Func
rather than just computation.

### Contributing

Please see https://github.com/funcatron/tron/blob/master/CONTRIBUTING.md[CONTRIBUTING] for details on
how to make a contribution.

### Licenses and Support

Funcatron is licensed under an Apache 2 license.

Support is available from the project's founder,
[David Pollak](mailto:feeder.of.the.bears@gmail.com).

== Documentation Versions

$$VERSIONLIST$$

= Funcatron
:toc:

== About

Serverless on Your Cluster:

* Define Endpoints in Swagger
* Write Functions in Java, Scala, Clojure, Python, or JavaScript
* Deploy to Mesos, Kubernets, or Swarm
* Autoscale

_Funcatron let's you deploy serverless on any cloud provider or in your
private cloud. Focus on the functions, avoid vendor lock-in._

This document sets out the goals for the http://funcatron.org[Funcatron] project.

### Getting Started w/Spring Boot

If you've already got a https://spring.io/guides/gs/spring-boot/[Spring Boot]
app and you want to run it in Funcatron... you're in luck. Add a few dependencies
and 2 classes to your existing Spring Boot app and you're good to go.
The link:/master/funcatron/info/spring_boot.html[Spring Boot Quickstart]
gets you started... quickly.

And check out the link:/master/funcatron/info/architecture_strategy.html[Architecture
Strategy] for a deeper dive into Funcatron.

### Getting Started Lambda-style

"`Lambdas`" are small units of computing... Funcations. Funcatron
supports writing small funcations, associating them with REST endpoints,
and autoscaling. The
link:/master/funcatron/info/dev_intro.html[Developer Intro] to
Funcatron walks you through building Funcatron bundles Lambda-style.

And check out the link:/master/funcatron/info/architecture_strategy.html[Architecture
Strategy] for a deeper dive into Funcatron.

### What's Funcatron

Amazon's https://aws.amazon.com/lambda/[Lambda] popularized
http://www.martinfowler.com/articles/serverless.html["`serverless`"]
code deployment. It's dead simple: associate a "`function`" with an event.
Each time the event happens, the function is applied and the function's
return value is returned to the event source. An event could be an HTTP(S)
request, something on an event queue, whatever.

Functions are ephemeral. They exist for the duration of the function call.
Once the function returns a value, all of its state and scope and everything
else about it is assumed to go away.

Scaling this kind of architecture is simple: the more frequently a function gets
applied, the more compute resources are allocated to support the function...
and https://en.wikipedia.org/wiki/Bob%27s_your_uncle[Bob's Your Uncle].

The current popular function runners (competitors to Amazon's Lambda), however, are
proprietary: when you write to the API for Lambda or Google's
https://cloud.google.com/functions/docs/[Cloud Functions],
_**you're locked into that vendor**_.

There's currently no (well, there's https://developer.ibm.com/openwhisk/[OpenWhisk])
generic way to do the auto-scale function thing on a private cloud or in a
way that can migrate from one cloud provider to another.

Funcatron addresses this. Funcatron is a cloud-provider-neutral mechanism for
developing, testing, and deploying auto-scalable functions.

Funcatron is designed to run on container orchestration clusters:
https://mesosphere.com/[Mesos], http://kubernetes.io/[Kubernetes], or
https://docker.com[Docker Swarm].

### Software Lifecycle

Software goes through a lifecycle:

- Authoring
- Testing
- Staging
- Production
- Debugging

Funcatron addresses software at each stage of the lifecycle.

#### Authoring

An engineers sits down to write software. The faster the turn-around between
code written and "`trying it out,`" the more productive the engineer will be.

Funcatron supports a "`save, reload`" model where the engineer saves a file
(presuming they're using an IDE that does compilation on save or are using a
non-compiled language), and their function endpoints are available. That's it.
No uploading. No reconfiguration. No waiting. The endpoint is available on save.

Further, the Funcatron model requires knowledge of two things:

* http://swagger.io[Swagger]
* How to write a simple function in Java, Scala, Clojure, Python, or JavaScript.

**That's it.**

The engineer defines the endpoints in Swagger and uses the `operationId` to
specify the function (or class for Java and Scala) to apply when then endpoint
is requested. Funcatron takes care of the rest.

Between the fast turn-around and low "`new stuff to learn`" quotient,
it's easy to get started with Funcatron. It's also easy to stay productive
with Funcatron.

Also, developers need only have Docker installed on their development machine
to live-test Funcatron code.

#### Testing

Because Funcatron endpoints are single functions (or methods on newly
instantiated classes), writing unit tests is simple. Write a unit test and
test the function.

#### Staging

Funcatron code bundles (Funcs) contain a Swagger endpoint definition and the
functions
that are associated with the endpoint and any library code. For JVM languages,
these are bundled into an Uber JAR. For Python, a
https://github.com/pantsbuild/pex[PEX]
file. The Swagger definitions for an endpoint are unique based on
host name and root path.

Funcatron supports aliasing Swagger fields and values in different
environments such that a single Swagger definition can be run
in staging and testing environments without change.
Thus, there's one deployment unit (a Func bundle) that have well defined
behaviors across test, staging, and production servers.

#### Production

Funcatron allows simple deployment and undeployment of end-point collections
defined in Swagger files and implemented in a JVM language, Python, or NodeJS.

Requests are forwarded from Nginx via a message queue to a dispatcher (a Tron).
Based on the hostname and root path, the message is placed on a queue for
a specific Func. The Func processes the request and sends the response
to a reply queue. The Nginx process dequeues the response and returns
it as an HTTP response.

The number of Func instances running on a cluster is based on the queue depth
and response time. The Func manager sends statistics back to the Trons
and the Trons change Func allocation based on these statistics by
communicating with the container orchestration substrate (Mesos, Kubernetes,
Swarm) and changing the allocation of Func running containers.

From the DevOps point of view: deploy a Func and it binds to the appropriate
HTTP endpoint and scales to handle load.

#### Debugging & Test Cases

Funcatron logs a unique request ID and the SHA of the Func with every log line
related to a request. This allows correlation of requests as they fan out through
a cluster.

Funcatron allows dynamic changing log levels on a Func-by-Func basis which allows
capturing more information on demand.

All communications between the front end, Funcs, and back again are via well
defined JSON payloads. Funcatron allows capturing request and response
payloads on a Func-by-Func basis (complete streams, or random sampling).
This data can be used for testing or debugging.

### Architecture

Funcatron has some ambitious goals... and has an architecture to facilitate
achieving these goals.

In all but development mode, Funcatron runs on a Docker container orchestration
system: Mesos, Kubernetes, or Docker Swarm. We call this the "container
substrate." Each of the Funcatron components can be scaled independently with
messages to the container substrate.

For HTTP requests, Funcatron uses Nginx and Lua (via the
http://openresty.org/en/[OpenResty] project) to handle the HTTP requests.
A small
Lua script encodes the request as a payload that's sent to a message broker
(initially RabbitMQ, but this will be pluggable, e.g. Kafka, Redis). For large
request or response bodies, there will be a direct connection between the Front End
and the Runner.
For all but the highest volume installations, 2 Nginx instances
should be sufficient.

Based on the combination of `host` and `pathPrefix` attributes in the Swagger
module definition, the Tron enqueues the request on the appropriate queue.

A Runner module dequeues messages from a number of host/pathPrefix queues and
forwards the request to the appropriate Func. The runner then takes the function
return value and appropriately encodes it and places it on the reply queue which
dequeued by the original endpoint.

Each Func can run multiple modules. Based on queue depth, queue service time,
and CPU usage stats from the Funcs, more runners can be allocated on the substrate,
or more Funcs can be allocated across the runners.

The Lua scripts dequeues the response and turns in into an Nginx response.

Because all of the operation of the Funcs and Trons can be captured as messages
(and all the messages are in JSON), it's possible to capture message streams for
testing and debugging purposes.

Every request has a unique ID and each log line includes the unique ID so it's
possible to correlate a request as it moves across the cluster.

[plantuml]
----
skinparam handwritten true

() "Upload/Enable" as Operator

() "HTTPS Proxy" as Proxy

node "Message Queue" as MQ

package "Public Facing" {
    [Frontend]
}

node {
    [Tron]
    [Runner]
}

Proxy -> [Frontend] : "HTTP port 80"

[Frontend] <--> MQ : Stomp

[Tron] <--> MQ : AMQP

Note left of [Frontend]: Multiple instances

[Frontend] -> [Runner] : "HTTP port 4000"

[Runner] -> [Tron] : "HTTP port 3000"

Note left of [Runner] : Multiple instances\nAuto-scaled

Note left of [Tron] : One instance

Note left of MQ : Cluster

Note left of Operator : Access to control\nFuncatron cluster

[Runner] <--> MQ : AMQP

Operator -> [Tron] : "HTTP port 3000"
----

#### Notes

The initial implementation uses Nginx/OpenResty, RabbitMQ, Java/Scala, and Mesos
to support HTTP requests. This is not "`hardcoded`" but pluggable. Specifically:

* Anything that can enqueue a payload and dequeue the response can
  work with the rest of Funcatron. The initial implementation is HTTP via
  Nginx/OpenResty, but nothing in the rest of the system depends on what enqueues
  the request and dequeues the response.
* RabbitMQ is the initial message broker, but it could be Kafka, Redis, or any other
  message broker. This is pluggable.
* Initially, dispatch from Runners to Funcs will be Java/Scala/Kotlin classes. But the
  dispatch is also pluggable so other languages (Clojure) and
  runtimes (Python, NodeJS, Ruby/Rails) will be supported.
* "`But Swagger is HTTP only`" well... yes and no... the verb and the scheme are
  HTTP-specific, but they can be ignored... and by the time the request is
  dequeued by the Runner, the origin (HTTP or something else) of the message
  is irrelevant. The power of Swagger is two-fold:
  ** Excellent definitions of incoming and outgoing data shapes
  ** Great tooling and lots of general Swagger skills

Because everything in Funcatron is asynchronous messages, how the messages are
passed, where the message originate and where responses are dequeued are all
pluggable and irrelevant to the other parts of the system.

The key idea in Funcatron is the Func is a well defined bundle of functionality
that's associated with a particular message signature that maps to well HTTP via
host, pathPrefix, path, and verb, but could map to something else.

It may be possible to chain Func invocations. I don't yet have a concrete
design, but rather than enqueuing a Func return value as a response, it may
be possible to package it as a request (the request body contains the Func
return value) and forwarding it to another Func for further processing.

Finally, if there's no `reply-to` field in a message, the Func is applied (invoked)
but the results are discarded. This allows for side effects from the Func
rather than just computation.

### Contributing

Please see https://github.com/funcatron/tron/blob/master/CONTRIBUTING.md[CONTRIBUTING] for details on
how to make a contribution.

### Licenses and Support

Funcatron is licensed under an Apache 2 license.

Support is available from the project's founder,
[David Pollak](mailto:feeder.of.the.bears@gmail.com).

== Documentation Versions

$$VERSIONLIST$$


Fix documentation

Fix documentation

= Narada tracker adapter base

This project based on https://gitlab.qarea.org/tgms/narada-tgms-base/tree/master

== Additions/changes to base project

=== migrate

* Add httptimeout configuration for requests to remote services

=== entities package

* Package provides required entities structure and needed errors for adapter

=== api/rpcsvc package

* Implements all needed JSONRPC2 api calls and provide interface for adapter client

=== MySQL

* Removed all MySQL related files, if you need one - take it from narada-tgms-base

Narada tracker adapter base
================

This project based on https://gitlab.qarea.org/tgms/narada-tgms-base/tree/master

== Additions/changes to base project

=== migrate

* Add httptimeout configuration for requests to remote services

=== entities package

* Package provides required entities structure and needed errors for adapter

=== api/rpcsvc package

* Implements all needed JSONRPC2 api calls and provide interface for adapter client

=== MySQL

* Removed all MySQL related files, if you need one - take it from narada-tgms-base


Update 2016-05-17-Kuznya-a-ved-udobno-JBoss-Forge-pretty-sweet.adoc

= Кузня, а ведь удобно { JBoss Forge, pretty sweet }
:hp-tags: полезняшки, черновик

Пробую по книжке покачаться до беспрерывной интеграции http://bit.ly/1XLMRZZ[Continuous Enterprise Development in Java _by Andrew Lee Rubinger, Aslak Knutsen_] . И вот там используется кузня. Столько рутины уже автоматизировано. Ведь удобно. Надо покопать дальше. Тут ведь и тестирование интеграционное удобнее. Ну т.е. расписано как сделать.

*Что понравилось:*

 . Описываешь почти человеческим языком
 . Инкрементальное описание проекта
 . Довольно тонкая настройка
 . Выбор реализаций ифреймворков
 . Хорошая подсказка по <TAB>, по ней в основном и учусь.
 . По проекту гуляешь как по структуре каталогов в системе, те половина команд уже получается знаешь.

*Не понравилось:*
_По сколько учусь по книге, то книга устарела. Но и официальный сайт тоже устарел. Приходится идти почти в слепую. В книге описывается версия 1 или 2, на сайте версия 3. То что скачалось jboss IDE там используется 3.0.1 кажется. И оно отличается от версии 3, отсутствуют некоторые свойства._

 . Хоть я и выбрал scaffolding faces 2.2, когда сгенерировались вьюхи, там используется JSTL! Хотя и BalusC и официальный Oracle, кажется, уже говорят в фейсах забудьте про JSTL. Там своё уже есть, то и используйте.

[NOTE]
====
Вот тут наконец, я нашел правильные команды кузни http://forge.jboss.org/document/hands-on-lab
====

= Кузня, а ведь удобно. (JBoss Forge)
:hp-tags: полезняшки, черновик

Пробую по книжке покачаться до беспрерывной интеграции http://bit.ly/1XLMRZZ[Continuous Enterprise Development in Java _by Andrew Lee Rubinger, Aslak Knutsen_] . И вот там используется кузня. Столько рутины уже автоматизировано. Ведь удобно. Надо покопать дальше. Тут ведь и тестирование интеграционное удобнее. Ну т.е. расписано как сделать.

*Что понравилось:*

 . Описываешь почти человеческим языком
 . Инкрементальное описание проекта
 . Довольно тонкая настройка
 . Выбор реализаций ифреймворков
 . Хорошая подсказка по <TAB>, по ней в основном и учусь.
 . По проекту гуляешь как по структуре каталогов в системе, те половина команд уже получается знаешь.

*Не понравилось:*
_По сколько учусь по книге, то книга устарела. Но и официальный сайт тоже устарел. Приходится идти почти в слепую. В книге описывается версия 1 или 2, на сайте версия 3. То что скачалось jboss IDE там используется 3.0.1 кажется. И оно отличается от версии 3, отсутствуют некоторые свойства._

 . Хоть я и выбрал scaffolding faces 2.2, когда сгенерировались вьюхи, там используется JSTL! Хотя и BalusC и официальный Oracle, кажется, уже говорят в фейсах забудьте про JSTL. Там своё уже есть, то и используйте.

[NOTE]
====
Вот тут наконец, я нашел правильные команды кузни http://forge.jboss.org/document/hands-on-lab
====


Internal link typo

Internal link typo

= Gateway
:page-sidebar: apim_sidebar
:page-permalink: apim_installguide_gateway.html
:page-folder: apim/installation-guide

== System Requirements

=== JDK

Gravitee.io Gateway requires at least Java 8. Before you install Gravitee.io Gateway, please check your Java version :

[source,bash]
----
java -version
echo $JAVA_HOME
----

NOTE: You can download the latest JDK from the http://www.oracle.com/technetwork/java/javase/downloads/index.html[Oracle Java SE Download Site].

=== Datastore

Default Gravitee.io Gateway distribution requires MongoDB 3.x to store management and configuration data and Elasticsearch 2.x to store
reporting / analytics.

NOTE: You can download MongoDB 3.x from the https://www.mongodb.org/downloads#production[MongoDB Download Site]
and Elasticsearch 2.x from the https://www.elastic.co/downloads/elasticsearch[Elastic Download Site]

WARNING: Gravitee.io is not yet compatible with Elasticsearch 5.x. See https://github.com/gravitee-io/issues/issues/387[ES 5.x support issue].

== Installing from the ZIP archive

Binaries are available from https://gravitee.io/downloads/full-stack/latest/[Downloads page] or via https://dl.bintray.com/gravitee-io/release/GRAVITEEIO-VERSION/graviteeio-full-GRAVITEEIO-VERSION.zip[Bintray].

[source,bash]
[subs="attributes"]
$ curl -L https://dl.bintray.com/gravitee-io/release/GRAVITEEIO-VERSION/:graviteeio-full-GRAVITEEIO-VERSION.zip -o gravitee-standalone-distribution-GRAVITEEIO-VERSION.zip

Once file has been downloaded, you just have to unpack it in the right place.

[source,bash]
[subs="attributes"]
$ unzip gravitee-standalone-distribution-GRAVITEEIO-VERSION.zip

And you can simply start up the gateway as follow:

[source,bash]
[subs="attributes"]
$ cd graviteeio-gateway-GRAVITEEIO-VERSION
$ ./bin/gravitee

If everything goes well, you should see this kind of logs:

[source,bash]
[subs="attributes"]
...
20:55:42.097 [gravitee] INFO  i.g.g.s.vertx.VertxEmbeddedContainer - Starting Vertx container and deploy Gravitee Verticles
20:55:42.108 [gravitee] INFO  i.g.g.s.v.GraviteeVerticleFactory - Creating a new instance of Gravitee Verticle
20:55:42.167 [gravitee] INFO  i.g.g.standalone.node.GatewayNode - Gravitee.io - Gateway [id: 9c31b9cc-f779-4f2d-b1b9-ccf779df2df5 - version: GRAVITEEIO-VERSION (build: XXXX) revision#XXXX] started in 3871 ms.
...

By default, the gateway is listening on port *8082* and can be accessed from: _http://localhost:8082_

HTTP port can be <<apim_installguide_configuration.adoc#http_server, configured>> if necessary.

== Directory structure

After successfully installed Gravitee.io Gateway, the `graviteeio-gateway` directory looks like this:

[width="100%",cols="20%,80%",frame="topbot",options="header"]
|======================
|Folder    |Description
|bin       |Startup/shutdown scripts
|config    |<<apim_installguide_configuration.adoc#gravitee-gateway-configuration, Configuration>> folder (application, logs and cache configuration)
|lib       |Libraries (gravitee.io libraries and third parties library)
|logs      |Gateway log files
|plugins   |Gateway <<apim_overview_plugins.adoc#, plugins>>
|======================

= Gateway
:page-sidebar: apim_sidebar
:page-permalink: apim_installguide_gateway.html
:page-folder: apim/installation-guide

== System Requirements

=== JDK

Gravitee.io Gateway requires at least Java 8. Before you install Gravitee.io Gateway, please check your Java version :

[source,bash]
----
java -version
echo $JAVA_HOME
----

NOTE: You can download the latest JDK from the http://www.oracle.com/technetwork/java/javase/downloads/index.html[Oracle Java SE Download Site].

=== Datastore

Default Gravitee.io Gateway distribution requires MongoDB 3.x to store management and configuration data and Elasticsearch 2.x to store
reporting / analytics.

NOTE: You can download MongoDB 3.x from the https://www.mongodb.org/downloads#production[MongoDB Download Site]
and Elasticsearch 2.x from the https://www.elastic.co/downloads/elasticsearch[Elastic Download Site]

WARNING: Gravitee.io is not yet compatible with Elasticsearch 5.x. See https://github.com/gravitee-io/issues/issues/387[ES 5.x support issue].

== Installing from the ZIP archive

Binaries are available from https://gravitee.io/downloads/full-stack/latest/[Downloads page] or via https://dl.bintray.com/gravitee-io/release/GRAVITEEIO-VERSION/graviteeio-full-GRAVITEEIO-VERSION.zip[Bintray].

[source,bash]
[subs="attributes"]
$ curl -L https://dl.bintray.com/gravitee-io/release/GRAVITEEIO-VERSION/:graviteeio-full-GRAVITEEIO-VERSION.zip -o gravitee-standalone-distribution-GRAVITEEIO-VERSION.zip

Once file has been downloaded, you just have to unpack it in the right place.

[source,bash]
[subs="attributes"]
$ unzip gravitee-standalone-distribution-GRAVITEEIO-VERSION.zip

And you can simply start up the gateway as follow:

[source,bash]
[subs="attributes"]
$ cd graviteeio-gateway-GRAVITEEIO-VERSION
$ ./bin/gravitee

If everything goes well, you should see this kind of logs:

[source,bash]
[subs="attributes"]
...
20:55:42.097 [gravitee] INFO  i.g.g.s.vertx.VertxEmbeddedContainer - Starting Vertx container and deploy Gravitee Verticles
20:55:42.108 [gravitee] INFO  i.g.g.s.v.GraviteeVerticleFactory - Creating a new instance of Gravitee Verticle
20:55:42.167 [gravitee] INFO  i.g.g.standalone.node.GatewayNode - Gravitee.io - Gateway [id: 9c31b9cc-f779-4f2d-b1b9-ccf779df2df5 - version: GRAVITEEIO-VERSION (build: XXXX) revision#XXXX] started in 3871 ms.
...

By default, the gateway is listening on port *8082* and can be accessed from: _http://localhost:8082_

HTTP port can be <<apim_installguide_configuration.adoc#http_server, configured>> if necessary.

== Directory structure

After successfully installed Gravitee.io Gateway, the `graviteeio-gateway` directory looks like this:

[width="100%",cols="20%,80%",frame="topbot",options="header"]
|======================
|Folder    |Description
|bin       |Startup/shutdown scripts
|config    |<<apim_installguide_configuration.adoc#gravitee-gateway-configuration, Configuration>> folder (application, logs and cache configuration)
|lib       |Libraries (gravitee.io libraries and third parties library)
|logs      |Gateway log files
|plugins   |Gateway <<apim_overview_plugins.adoc, plugins>>
|======================


Add some more asciidoc pros

Add some more asciidoc pros

== Pros

* Multiline support (table cells, list elements, etc)
* Code references
* Styling without html
* Github support
* Conversion to other formats

== Cons

* Vim support is worse
* Source blocks are harder to write
* Bulleted lists are spaced more apart https://github.com/asciidoctor/asciidoctor/issues/1087

== Notes

* Vim highlighting and link following
* Jekyll plugin necessary

== Pros

* Multiline support (table cells, list elements, etc)
* Code references
* Styling without html

== Cons

* Vim support is worse
* Source blocks are harder to write
* Bulleted lists are spaced more apart https://github.com/asciidoctor/asciidoctor/issues/1087

== Notes

* Vim highlighting and link following
* Jekyll plugin necessary