NMS-6687: some German Ordnungswahn

NMS-6687: some German Ordnungswahn

Cyrille

=== SshMonitor

The SSH monitor tests the availability of a SSH service.
During the poll an attempt is made to connect on the specified port. If the connection request is successful, then the service is considered up.
Optionaly, the banner line generated by the service may be parsed and compared against a pattern before the service is considered up.

==== Monitor facts

[options="autowidth"]
|===
| Class Name     | `org.opennms.netmgt.poller.monitors.SshMonitor`
| Remote Enabled | true
|===

==== Configuration and Usage

.Monitor specific parameters for the SshMonitor
[options="header, autowidth"]
|===
| Parameter       | Description                                                                    | Required | Default value
| `banner`        | Regular expression to be matched against the service's banner.                 | optional | `-`
| `client-banner` | The client banner that OpenNMS will use to identify itself on the service.     | optional | `SSH-1.99-OpenNMS_1.5`
| `match`         | Regular expression to be matched against the service's banner. +
                    Deprecated, please use the `banner` parameter instead. +
                    Note that this parameter takes precedence over the `banner` parameter, though. | optional | `-`
| `port`          | TCP port to which SSH connection shall be tried.                               | optional | `22`
| `retry`         | Number of attempts to establish the SSH connnection.                           | optional | `0`
| `timeout`       | Timeout in milliseconds for SSH connection establishment.                      | optional | `3000`
|===

==== Examples

[source, xml]
----
<service name="SSH" interval="300000" user-defined="false" status="on">
  <parameter key="retry" value="1"/>
  <parameter key="banner" value="SSH"/>
  <parameter key="client-banner" value="OpenNMS poller"/>
  <parameter key="timeout" value="5000"/>
  <parameter key="rrd-repository" value="/var/lib/opennms/rrd/response"/>
  <parameter key="rrd-base-name" value="ssh"/>
  <parameter key="ds-name" value="ssh"/>
</service>
<monitor service="SSH" class-name="org.opennms.netmgt.poller.monitors.SshMonitor"/>
----

=== SshMonitor

The SSH monitor tests the availability of a SSH service. +
During the poll an attempt is made to connect on the specified port. If the connection request is successful, then the service is considered up. +
Optionaly, the banner line generated by the service may be parsed and compared against a pattern before the service is considered up.

==== Monitor facts

[options="autowidth"]
|===
| Class Name | `org.opennms.netmgt.poller.monitors.SshMonitor`
| Remote Enabled | true
|===

==== Configuration and Usage

.Monitor specific parameters for the SshMonitor
[options="header, autowidth"]
|===
| Parameter | Description                                    | Required | Default value
| `banner` | Regular expression to be matched against the service's banner. | optional | `-`
| `client-banner` | The client banner that OpenNMS will use to identify itself on the service. | optional | `SSH-1.99-OpenNMS_1.5`
| `match` | Regular expression to be matched against the service's banner. +
            Deprecated, please use the `banner` parameter instead. +
            Note that this parameter takes precedence over the `banner` parameter, though. | optional | `-`
| `port` | TCP port to which SSH connection shall be tried. | optional | `22`
| `retry` | Number of attempts to establish the SSH connnection. | optional | `0`
| `timeout` | Timeout in milliseconds for SSH connection establishment. | optional | `3000`
|===

==== Examples

[source, xml]
----
<service name="SSH" interval="300000" user-defined="false" status="on">
  <parameter key="retry" value="1"/>
  <parameter key="banner" value="SSH"/>
  <parameter key="client-banner" value="OpenNMS poller"/>
  <parameter key="timeout" value="5000"/>
  <parameter key="rrd-repository" value="/var/lib/opennms/rrd/response"/>
  <parameter key="rrd-base-name" value="ssh"/>
  <parameter key="ds-name" value="ssh"/>
</service>
<monitor service="SSH" class-name="org.opennms.netmgt.poller.monitors.SshMonitor"/>
----


Beginning document for Rollbar

Beginning document for Rollbar

= Error Tracking with RollBar

:imagesdir: https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/aws

== Single-Tier and Multi-Tier Implementations

Error Tracking is an important part of managing your Kill
Bill system. When errors occur, whether due to system bugs or user mistakes, error tracking enables you to analyze what went wrong and develop ways to avoid similar errors in the future.

Your application may log errors along with many other events, but log files are often huge and it is not easy to extract the information needed for error analysis. Several third-party tools are available to help with this task. One popular tool is https://rollbar.com/[Rollbar]. This
package offers error extraction and analysis at very low cost for your Kill Bill implementation.

Rollbar can be integrated with several types of Kill Bill installations. In this guide we discuss the use of Rollbar to track errors produced
by two types of implementations on Amazon Web Services (AWS):
single-tier and multi-tier. With the latest Amazon Machine Image (AMI)
for Kill Bill, it is very easy to process the Kill Bill logs using
Rollbar and work with them in the way that best suits your needs.

== Check Your Kill Bill Version

We assume that you have a working Kill Bill implementation running on
AWS, using either the
https://docs.killbill.io/latest/aws-singletier.html[Single Tier] or
https://docs.killbill.io/latest/aws-multitier.html[Multitier]
installation options. The single-tier option runs Kill Bill, Kaui, the
MariaDB database, and the nginx load balancer on a single AWS EC2
instance. This is suitable for quick deployment and for testing and
development. The multi-tier option runs Kill Bill and Kaui on two or more
separate EC2 instances, and uses an AWS RDS database manager along with
an AWS load balancer. This is an attractive option for many production
uses.

You should be running Kill Bill version 2021.9 or later. This version
can be configured to provide its full collection of Kill Bill metrics to
New Relic (and several other analysis tools). If you open the Kill Bill
admin page in your browser, it should show that you are
running the "Kill Bill Premium edition":

image::metrics-kb-admin.png[align=center]

If you see this page you are ready to go. If not, you should upgrade
your installation.

While you are on this page, if you want to see all the metrics that Kill
Bill has to offer, just add the path `/1.0/metrics` to the URL. Have fun!
If you find these hard to understand, though, maybe New Relic can help.

== Set Up New Relic

You may already be familiar with New Relic. If not, this section will
explain how to get started.

First, go to the https://www.newrelic.com/[New Relic website]. New Relic
offers a free account as long as your usage does not exceed certain limits. Provide a name and email address to sign up.

You should see the New Relic main page. To get back to this page at a future time you can click the words *New Relic One* in the upper left corner.

To set up New Relic to manage the metrics available from Kill Bill, there
are just two steps: (1) install the New Relic agent in Kill Bill, and (2)
edit a configuration file to enable the transfer of the complete Kill Bill metrics.

== Install the Agent

The first step in integrating an analysis tool (like New Relic) and a
source of data to analyze (like Kill Bill) is to set up a means to get
the source to send its data to the analyzer. New Relic does this by
installing the *New Relic Agent* in the system producing the data.

1. In the main New Relic page, select the button labeled *Add Some Data*. If this button does not appear, select *+ Add More Data* in the upper right corner.
2. An overlay pane should appear. At the top of this pane select *Guided Install*.
3. The next pane is headed *Installation Plan*. Make sure the *Auto-Discovery* tab is selected, then choose *Linux*.
4. The next pane summarizes what you have selected. Click on *Begin Installation*. You will see the following page:

image::metrics-newrelic-installation.png[align=center]

[start=5]
. In the box containing the install command, click *Copy Command*. The command will be copied to your clipboard.

[NOTE]
This command includes the API key assigned to you by
New Relic. This authorizes the agent to do its job. This is your *user* API Key, and should not be confused with the key you will use in the next step.

[start=6]
. To install the agent:

.. Login to your EC2 instance.
.. Paste the saved install command to the Ubuntu command line.
.. Press Enter. The installation should begin.

You will be presented with a list of options to install, as shown below. An additional option, Infrastructure Agent, is always installed.

[start=7]
. Press Enter to select all of the options.

image::metrics-newrelic-options.png[align=center]

You will be presented with several questions including default answers.

[start=8]
. Press Enter after each question to select the defaults.

Finally, you will be asked for the MySQL password.

[start=9]
. Type `root`.

If all goes well, each installation should report `success`.

[NOTE]
*Note:* If you are using the multi-tier installation, you will have multiple EC2
instances. The agent should be installed separately for each one.

== Test the Installation

. Return to the New Relic main page.
. Select *Browse Data* from the top menu.
. Select *Metrics* from the dropdown.

You should see a
long list of metrics! These are coming from your instances, but they
only describe the Ubuntu environment itself. You do not yet have the
Kill Bill metrics. To fix this, proceed to the next section.

== Set Up the Authorization

To authorize the sending of the Kill Bill metrics, it is necessary to
edit two lines in this file:

 ```
 /var/lib/tomcat/bin/setenv2.sh
 ```

This file contains configuration information for `tomcat`, which manages the
KillBill web applications.

This is a small file. The two lines to be edited are:

```
-Dcom.killbill.newrelic.enable=false
-Dcom.killbill.newrelic.apiKey=
```

These should be changed to:

```
-Dcom.killbill.newrelic.enable=true
-Dcom.killbill.newrelic.apiKey=Your-API-Key
```

The API key to be added is called the *Insights Insert Key.* This is *not* the same as the user API Key contained in the command you
used to install the agent.

To find the Insights Insert Key:

1. Close any overlay panes on the New Relic page by clicking on the `X` in the upper right corner.
2. Click the symbol at the far upper right to open your account menu, then select *API keys*.
3. On the page that appears, select *Insights Insert keys* at the lower right.
4. In the *Insert Keys* column on the left, under the word *key* at the bottom, click *Show*.
5. Manually copy the key to your clipboard, then paste it to the configuration file.

After editing the file, go to your AWS EC2 dashboard and *reboot the
instance* so the new configuration file will be read. If you have more
than one instance, follow the same procedure for each one.

Now return to the *Metrics/Summary* page. After a short delay, you
should see a lot more metrics; well over 1,000 in your list.

Congratulations. Your New Relic integration is complete!

== Using New Relic

The New Relic site has lots of https://docs.newrelic.com/docs/[documentation], so we won't
repeat any of that here. We will just suggest a few quick steps to get
started:

1. Close any overlay panes on the New Relic page by clicking on the `X` in the upper right corner.
2. Select *Browse Data* in the menu and *Metrics* in the submenu. A list of available metrics will appear on the left.
3. Select some metrics to see the graph (chart) they produce. Identify the ones you would like to see together in a dashboard.
4. To create a dashboard, close the metrics page, select *Dashboards* in the menu, and click *+ Create a Dashboard*.
5. Select *Create New Dashboard*, give it a name, and click *Create*.

You can add charts to your dashboard for any metrics you choose. The charts can be edited, deleted, and rearranged. Your dashboard will appear under the *Dashboards* menu item. Have fun and good luck!

= Managing Metrics with New Relic

:imagesdir: https://github.com/killbill/killbill-docs/raw/v3/userguide/assets/aws

== Single-Tier and Multi-Tier Implementations

Measurements and metrics are an important part of managing your Kill
Bill system to be sure that performance is optimized and any problems
can be detected early. Kill Bill collects over 1,300 metrics to show you
every conceivable view of your system's behavior.

Several third-party tools are available to manage and display metrics of
this type. One popular tool is https://www.newrelic.com/[New Relic]. This
package offers a low-cost option to monitor and display whatever metrics
you may find useful from the Kill Bill collection, including metrics
that show the performance and resource use of Kill Bill and Kaui
themselves, and metrics describing the infrastructure on which these
systems run.

New Relic can be integrated with several types of Kill Bill installations. In this guide we discuss the use of New Relic to manage metrics produced
by two types of implementations on Amazon Web Services (AWS):
single-tier and multi-tier. With the latest Amazon Machine Image (AMI)
for Kill Bill, it is very easy to direct the Kill Bill metrics to
New Relic and work with them in the way that best suits your needs.

== Check Your Kill Bill Version

We assume that you have a working Kill Bill implementation running on
AWS, using either the
https://docs.killbill.io/latest/aws-singletier.html[Single Tier] or
https://docs.killbill.io/latest/aws-multitier.html[Multitier]
installation options. The single-tier option runs Kill Bill, Kaui, the
MariaDB database, and the nginx load balancer on a single AWS EC2
instance. This is suitable for quick deployment and for testing and
development. The multi-tier option runs Kill Bill and Kaui on two or more
separate EC2 instances, and uses an AWS RDS database manager along with
an AWS load balancer. This is an attractive option for many production
uses.

You should be running Kill Bill version 2021.9 or later. This version
can be configured to provide its full collection of Kill Bill metrics to
New Relic (and several other analysis tools). If you open the Kill Bill
admin page in your browser, it should show that you are
running the "Kill Bill Premium edition":

image::metrics-kb-admin.png[align=center]

If you see this page you are ready to go. If not, you should upgrade
your installation.

While you are on this page, if you want to see all the metrics that Kill
Bill has to offer, just add the path `/1.0/metrics` to the URL. Have fun!
If you find these hard to understand, though, maybe New Relic can help.

== Set Up New Relic

You may already be familiar with New Relic. If not, this section will
explain how to get started.

First, go to the https://www.newrelic.com/[New Relic website]. New Relic
offers a free account as long as your usage does not exceed certain limits. Provide a name and email address to sign up.

You should see the New Relic main page. To get back to this page at a future time you can click the words *New Relic One* in the upper left corner.

To set up New Relic to manage the metrics available from Kill Bill, there
are just two steps: (1) install the New Relic agent in Kill Bill, and (2)
edit a configuration file to enable the transfer of the complete Kill Bill metrics.

== Install the Agent

The first step in integrating an analysis tool (like New Relic) and a
source of data to analyze (like Kill Bill) is to set up a means to get
the source to send its data to the analyzer. New Relic does this by
installing the *New Relic Agent* in the system producing the data.

1. In the main New Relic page, select the button labeled *Add Some Data*. If this button does not appear, select *+ Add More Data* in the upper right corner.
2. An overlay pane should appear. At the top of this pane select *Guided Install*.
3. The next pane is headed *Installation Plan*. Make sure the *Auto-Discovery* tab is selected, then choose *Linux*.
4. The next pane summarizes what you have selected. Click on *Begin Installation*. You will see the following page:

image::metrics-newrelic-installation.png[align=center]

[start=5]
. In the box containing the install command, click *Copy Command*. The command will be copied to your clipboard.

[NOTE]
This command includes the API key assigned to you by
New Relic. This authorizes the agent to do its job. This is your *user* API Key, and should not be confused with the key you will use in the next step.

[start=6]
. To install the agent:

.. Login to your EC2 instance.
.. Paste the saved install command to the Ubuntu command line.
.. Press Enter. The installation should begin.

You will be presented with a list of options to install, as shown below. An additional option, Infrastructure Agent, is always installed.

[start=7]
. Press Enter to select all of the options.

image::metrics-newrelic-options.png[align=center]

You will be presented with several questions including default answers.

[start=8]
. Press Enter after each question to select the defaults.

Finally, you will be asked for the MySQL password.

[start=9]
. Type `root`.

If all goes well, each installation should report `success`.

[NOTE]
*Note:* If you are using the multi-tier installation, you will have multiple EC2
instances. The agent should be installed separately for each one.

== Test the Installation

. Return to the New Relic main page.
. Select *Browse Data* from the top menu.
. Select *Metrics* from the dropdown.

You should see a
long list of metrics! These are coming from your instances, but they
only describe the Ubuntu environment itself. You do not yet have the
Kill Bill metrics. To fix this, proceed to the next section.

== Set Up the Authorization

To authorize the sending of the Kill Bill metrics, it is necessary to
edit two lines in this file:

 ```
 /var/lib/tomcat/bin/setenv2.sh
 ```

This file contains configuration information for `tomcat`, which manages the
KillBill web applications.

This is a small file. The two lines to be edited are:

```
-Dcom.killbill.newrelic.enable=false
-Dcom.killbill.newrelic.apiKey=
```

These should be changed to:

```
-Dcom.killbill.newrelic.enable=true
-Dcom.killbill.newrelic.apiKey=Your-API-Key
```

The API key to be added is called the *Insights Insert Key.* This is *not* the same as the user API Key contained in the command you
used to install the agent.

To find the Insights Insert Key:

1. Close any overlay panes on the New Relic page by clicking on the `X` in the upper right corner.
2. Click the symbol at the far upper right to open your account menu, then select *API keys*.
3. On the page that appears, select *Insights Insert keys* at the lower right.
4. In the *Insert Keys* column on the left, under the word *key* at the bottom, click *Show*.
5. Manually copy the key to your clipboard, then paste it to the configuration file.

After editing the file, go to your AWS EC2 dashboard and *reboot the
instance* so the new configuration file will be read. If you have more
than one instance, follow the same procedure for each one.

Now return to the *Metrics/Summary* page. After a short delay, you
should see a lot more metrics; well over 1,000 in your list.

Congratulations. Your New Relic integration is complete!

== Using New Relic

The New Relic site has lots of https://docs.newrelic.com/docs/[documentation], so we won't
repeat any of that here. We will just suggest a few quick steps to get
started:

1. Close any overlay panes on the New Relic page by clicking on the `X` in the upper right corner.
2. Select *Browse Data* in the menu and *Metrics* in the submenu. A list of available metrics will appear on the left.
3. Select some metrics to see the graph (chart) they produce. Identify the ones you would like to see together in a dashboard.
4. To create a dashboard, close the metrics page, select *Dashboards* in the menu, and click *+ Create a Dashboard*.
5. Select *Create New Dashboard*, give it a name, and click *Create*.

You can add charts to your dashboard for any metrics you choose. The charts can be edited, deleted, and rearranged. Your dashboard will appear under the *Dashboards* menu item. Have fun and good luck!


Docs be explicit on how to turn off deprecated auditing (#37316)

Just be explicit about turning off the deprecated audit log appender
because we really want people to turn it off.

[role="xpack"]
[[audit-log-output]]
=== Logfile audit output

The `logfile` audit output is the default output for auditing. It writes data to
the `<clustername>_audit.log` file in the logs directory. To maintain
compatibility with releases prior to 6.5.0, a `<clustername>_access.log` file
is also generated. They differ in the output format but the contents
are similar. For systems that are not ingesting the audit file for search or
analytics it is strongly recommended to keep only the newer format.

To turn off the deprecated output format, you can disable the logger in the
`log4j2.properties` file:

[source, properties]
--------------------------------------------------
# change info to off
# logger.xpack_security_audit_deprecated_logfile.level = info
logger.xpack_security_audit_deprecated_logfile.level = off
--------------------------------------------------

Alternatively, use the
{ref}/cluster-update-settings.html[cluster update settings API] to dynamically
configure the logger:

[source,js]
--------------------------------------------------
PUT /_cluster/settings
{
  "persistent": {
    "logger.org.elasticsearch.xpack.security.audit.logfile.DeprecatedLoggingAuditTrail": "off"
  }
}
--------------------------------------------------
// CONSOLE

NOTE: If you overwrite the `log4j2.properties` and do not specify appenders for
any of the audit trails, audit events are forwarded to the root appender, which
by default points to the `elasticsearch.log` file.

[float]
[[audit-log-entry-format]]
=== Log entry format

The log entries in the `<clustername>_audit.log` file have the following format:

- Each log entry is a one line JSON document and each one is printed on a separate line.
- The fields of a log entry are ordered. However, if a field does not have a value it
  will not be printed. The precise line pattern, together with the complete field
  order, are specified in the `log4j2.properties` config file.
- The log entry does not contain nested inner JSON objects, i.e. the doc is flat.
- The field names follow a dotted notation to flatten inner objects.
- A field's value can be a string, a number or an array of strings.
- A field's value, a request body as well, will be escaped as per the JSON RFC 4627.

There is a list of <<audit-event-types, audit event types>> specifying the
set of fields for each sog entry type.

[float]
[[deprecated-audit-log-entry-format]]
=== Deprecated log entry format

The log entries in the `<clustername>_access.log` file have the following format:

[source,txt]
----------------------------------------------------------------------------
[<timestamp>] [<local_node_info>] [<layer>] [<entry_type>] <attribute_list>
----------------------------------------------------------------------------

`<timestamp>`       ::      When the event occurred. You can configure the
                            timestamp format in `log4j2.properties`.
`<local_node_info>` ::      Information about the local node that generated
                            the log entry. You can control what node information
                            is included by configuring the
                            {ref}/auditing-settings.html#node-audit-settings[local node info settings].
`<layer>`           ::      The layer from which this event originated:
                            `rest`, `transport` or `ip_filter`.
`<entry_type>`      ::       The type of event that occurred: `anonymous_access_denied`,
                            `authentication_failed`, `access_denied`, `access_granted`,
                            `connection_granted`, `connection_denied`.
`<attribute_list>`  ::      A comma-separated list of key-value pairs that contain
                            data pertaining to the event. Formatted as
                            `attr1=[val1], attr2=[val2]`. See <<audit-event-attributes,
                            Audit Entry Attributes>> for the attributes that can be included
                            for each type of event.

[float]
[[audit-log-settings]]
=== Logfile output settings

The events and some other information about what gets logged can be
controlled using settings in the `elasticsearch.yml` file. See
{ref}/auditing-settings.html#event-audit-settings[Audited Event Settings] and
{ref}/auditing-settings.html#node-audit-settings[Local Node Info Settings].

IMPORTANT: No filtering is performed when auditing, so sensitive data may be
audited in plain text when including the request body in audit events.

[[logging-file]]
You can also configure how the logfile is written in the `log4j2.properties`
file located in `ES_PATH_CONF`. By default, audit information is appended to the
`<clustername>_audit.log` file located in the standard Elasticsearch `logs` directory
(typically located at `$ES_HOME/logs`). The file rolls over on a daily basis.
The deprecated logfile audit format (`<clustername>_access.log`) can be disabled
from the same `log4j2.properties` file (hint: look for the comment
instructing to set the log level to `off`). The deprecated format is a duplication
of information that is in place to assure backwards compatibility. If you are
not strict about the audit format it is strongly recommended to only use the
`<clustername>_audit.log` log appender.

[float]
[[audit-log-ignore-policy]]
=== Logfile audit events ignore policies

The comprehensive audit trail is necessary to ensure accountability. It offers tremendous
value during incident response and can even be required for demonstrating compliance.

The drawback of an audited system is represented by the inevitable performance penalty incurred.
In all truth, the audit trail spends _I/O ops_ that are not available anymore for the user's queries.
Sometimes the verbosity of the audit trail may become a problem that the event type restrictions,
<<audit-log-settings, defined by `include` and `exclude`>>, will not alleviate.

*Audit events ignore policies* are a finer way to tune the verbosity of the audit trail.
These policies define rules that match audit events which will be _ignored_ (read as: not printed).
Rules match on the values of attributes of audit events and complement the <<audit-log-settings, include/exclude>> method.
Imagine the corpus of audit events and the policies chopping off unwanted events.

IMPORTANT: When utilizing audit events ignore policies you are acknowledging potential
accountability gaps that could render illegitimate actions undetectable.
Please take time to review these policies whenever your system architecture changes.

A policy is a named set of filter rules. Each filter rule applies to a single event attribute,
one of the `users`, `realms`, `roles` or `indices` attributes. The filter rule defines
a list of {ref}/query-dsl-regexp-query.html#regexp-syntax[Lucene regexp], *any* of which has to match the value of the audit
event attribute for the rule to match.
A policy matches an event if *all* the rules comprising it match the event.
An audit event is ignored, therefore not printed, if it matches *any* policy. All other
non-matching events are printed as usual.

All policies are defined under the `xpack.security.audit.logfile.events.ignore_filters`
settings namespace. For example, the following policy named _example1_ matches
events from the _kibana_ or _admin_user_ principals **and** operating over indices of the
wildcard form _app-logs*_:

[source,yaml]
----------------------------
xpack.security.audit.logfile.events.ignore_filters:
  example1:
    users: ["kibana", "admin_user"]
    indices: ["app-logs*"]
----------------------------

An audit event generated by the _kibana_ user and operating over multiple indices
, some of which do not match the indices wildcard, will not match.
As expected, operations generated by all other users (even operating only on indices that
match the _indices_ filter) will not match this policy either.

Audit events of different types may have <<audit-event-attributes, different attributes>>.
If an event does not contain an attribute for which some policy defines filters, the
event will not match the policy.
For example, the following policy named _example2_, will never match `authentication_success` or
`authentication_failed` events, irrespective of the user's roles, because these
event schemas do not contain the `role` attribute:

[source,yaml]
----------------------------
xpack.security.audit.logfile.events.ignore_filters:
  example2:
    roles: ["admin", "ops_admin_*"]
----------------------------

Likewise, any events of users with multiple roles, some of which do not match the
regexps will not match this policy.

For completeness, although practical use cases should be sparse, a filter can match
a missing attribute of an event, using the empty string ("") or the empty list ([]).
For example, the following policy will match events that do not have the `indices`
attribute (`anonymous_access_denied`, `authentication_success` and other types) as well
as events over the _next_ index.

[source,yaml]
----------------------------
xpack.security.audit.logfile.events.ignore_filters:
  example3:
    indices: ["next", ""]
----------------------------

[role="xpack"]
[[audit-log-output]]
=== Logfile audit output

The `logfile` audit output is the default output for auditing. It writes data to
the `<clustername>_audit.log` file in the logs directory. To maintain
compatibility with releases prior to 6.5.0, a `<clustername>_access.log` file
is also generated. They differ in the output format but the contents
are similar. For systems that are not ingesting the audit file for search or
analytics it is strongly recommended to only keep the newer format.
Turning off the deprecated output format can be achieved by disabling the logger
in the `log4j2.properties` file (hint: there is a config comment
about it).
For more information, see {ref}/logging.html#configuring-logging-levels[configuring-logging].

[float]
[[audit-log-entry-format]]
=== Log entry format

The log entries in the `<clustername>_audit.log` file have the following format:

- Each log entry is a one line JSON document and each one is printed on a separate line.
- The fields of a log entry are ordered. However, if a field does not have a value it
  will not be printed. The precise line pattern, together with the complete field
  order, are specified in the `log4j2.properties` config file.
- The log entry does not contain nested inner JSON objects, i.e. the doc is flat.
- The field names follow a dotted notation to flatten inner objects.
- A field's value can be a string, a number or an array of strings.
- A field's value, a request body as well, will be escaped as per the JSON RFC 4627.

There is a list of <<audit-event-types, audit event types>> specifying the
set of fields for each sog entry type.

[float]
[[deprecated-audit-log-entry-format]]
=== Deprecated log entry format

The log entries in the `<clustername>_access.log` file have the following format:

[source,txt]
----------------------------------------------------------------------------
[<timestamp>] [<local_node_info>] [<layer>] [<entry_type>] <attribute_list>
----------------------------------------------------------------------------

`<timestamp>`       ::      When the event occurred. You can configure the
                            timestamp format in `log4j2.properties`.
`<local_node_info>` ::      Information about the local node that generated
                            the log entry. You can control what node information
                            is included by configuring the
                            {ref}/auditing-settings.html#node-audit-settings[local node info settings].
`<layer>`           ::      The layer from which this event originated:
                            `rest`, `transport` or `ip_filter`.
`<entry_type>`      ::       The type of event that occurred: `anonymous_access_denied`,
                            `authentication_failed`, `access_denied`, `access_granted`,
                            `connection_granted`, `connection_denied`.
`<attribute_list>`  ::      A comma-separated list of key-value pairs that contain
                            data pertaining to the event. Formatted as
                            `attr1=[val1], attr2=[val2]`. See <<audit-event-attributes,
                            Audit Entry Attributes>> for the attributes that can be included
                            for each type of event.

[float]
[[audit-log-settings]]
=== Logfile output settings

The events and some other information about what gets logged can be
controlled using settings in the `elasticsearch.yml` file. See
{ref}/auditing-settings.html#event-audit-settings[Audited Event Settings] and
{ref}/auditing-settings.html#node-audit-settings[Local Node Info Settings].

IMPORTANT: No filtering is performed when auditing, so sensitive data may be
audited in plain text when including the request body in audit events.

[[logging-file]]
You can also configure how the logfile is written in the `log4j2.properties`
file located in `ES_PATH_CONF`. By default, audit information is appended to the
`<clustername>_audit.log` file located in the standard Elasticsearch `logs` directory
(typically located at `$ES_HOME/logs`). The file rolls over on a daily basis.
The deprecated logfile audit format (`<clustername>_access.log`) can be disabled
from the same `log4j2.properties` file (hint: look for the comment
instructing to set the log level to `off`). The deprecated format is a duplication
of information that is in place to assure backwards compatibility. If you are
not strict about the audit format it is strongly recommended to only use the
`<clustername>_audit.log` log appender.

[float]
[[audit-log-ignore-policy]]
=== Logfile audit events ignore policies

The comprehensive audit trail is necessary to ensure accountability. It offers tremendous
value during incident response and can even be required for demonstrating compliance.

The drawback of an audited system is represented by the inevitable performance penalty incurred.
In all truth, the audit trail spends _I/O ops_ that are not available anymore for the user's queries.
Sometimes the verbosity of the audit trail may become a problem that the event type restrictions,
<<audit-log-settings, defined by `include` and `exclude`>>, will not alleviate.

*Audit events ignore policies* are a finer way to tune the verbosity of the audit trail.
These policies define rules that match audit events which will be _ignored_ (read as: not printed).
Rules match on the values of attributes of audit events and complement the <<audit-log-settings, include/exclude>> method.
Imagine the corpus of audit events and the policies chopping off unwanted events.

IMPORTANT: When utilizing audit events ignore policies you are acknowledging potential
accountability gaps that could render illegitimate actions undetectable.
Please take time to review these policies whenever your system architecture changes.

A policy is a named set of filter rules. Each filter rule applies to a single event attribute,
one of the `users`, `realms`, `roles` or `indices` attributes. The filter rule defines
a list of {ref}/query-dsl-regexp-query.html#regexp-syntax[Lucene regexp], *any* of which has to match the value of the audit
event attribute for the rule to match.
A policy matches an event if *all* the rules comprising it match the event.
An audit event is ignored, therefore not printed, if it matches *any* policy. All other
non-matching events are printed as usual.

All policies are defined under the `xpack.security.audit.logfile.events.ignore_filters`
settings namespace. For example, the following policy named _example1_ matches
events from the _kibana_ or _admin_user_ principals **and** operating over indices of the
wildcard form _app-logs*_:

[source,yaml]
----------------------------
xpack.security.audit.logfile.events.ignore_filters:
  example1:
    users: ["kibana", "admin_user"]
    indices: ["app-logs*"]
----------------------------

An audit event generated by the _kibana_ user and operating over multiple indices
, some of which do not match the indices wildcard, will not match.
As expected, operations generated by all other users (even operating only on indices that
match the _indices_ filter) will not match this policy either.

Audit events of different types may have <<audit-event-attributes, different attributes>>.
If an event does not contain an attribute for which some policy defines filters, the
event will not match the policy.
For example, the following policy named _example2_, will never match `authentication_success` or
`authentication_failed` events, irrespective of the user's roles, because these
event schemas do not contain the `role` attribute:

[source,yaml]
----------------------------
xpack.security.audit.logfile.events.ignore_filters:
  example2:
    roles: ["admin", "ops_admin_*"]
----------------------------

Likewise, any events of users with multiple roles, some of which do not match the
regexps will not match this policy.

For completeness, although practical use cases should be sparse, a filter can match
a missing attribute of an event, using the empty string ("") or the empty list ([]).
For example, the following policy will match events that do not have the `indices`
attribute (`anonymous_access_denied`, `authentication_success` and other types) as well
as events over the _next_ index.

[source,yaml]
----------------------------
xpack.security.audit.logfile.events.ignore_filters:
  example3:
    indices: ["next", ""]
----------------------------


Remove javadoc syntax

Remove javadoc syntax

== Rewrite Configuration Manual

There are many types of configuration objects in link:../[Rewrite], so we will take a few moments to define a few of the core terms before continuing to more advanced topics. Most of the core objects can be found in the +org.ocpsoft.rewrite.config+ package, while Servlet specific objects can be found in the +org.ocpsoft.rewrite.servlet.config+ package.

=== Download and install

Before continuing on to learn about configuring Rewrite, make sure that you have already followed the link:./install[installation guide]. This will ensure that Rewrite is successfully set up in your application.

=== The terminology

It may be helpful to review the following terms, many of which will make frequent appearances in this documentation.

ConfigurationProvider:: An object that provides +Configuration+ instances to the Rewrite framework; these may be created and registered as necessary. If not using link:./annotations/index[Rewrite Annotations], or other extensions, you must have at least one registered +ConfigurationProvider+ or Rewrite will not have any effect.

Configuration:: A collection of +Rule+ objects that are processed in order until the system has determined the current inbound or oubound Rewrite event has been handled. Configurations may be provided by extensions, cached for performance, or built dynamically at run-time.

ConfigurationBuilder:: This is likely the object you will interact with most when configuring the Rewrite system. Start with a +ConfigurationBuilder+ in each situation where you find yourself in need of a +Configuration+ object; this class may be used to add pre-constructed, or contruct custom +Rule+ instances for Rewrite.

Condition:: Defines a requirement that must be met in order for rule evaluation to return true. You may create custom +Condition+ implementations. If creating custom implementations, you should likely extend +DefaultConditionBuilder+, which  adds logical operators +.and()+, +.or()+, and +.not()+.

Operation:: Defines behavior to be performed after evaluation a +Rewrite+ event. These objects may be as simple or as complex as desired, ranging from simple logging to request forwarding. Typically +Operation+ instances may be chained to achieve more complex tasks. If creating custom umplementations, you should likely extend +DefaultOperationBuilder+, which adds logical chaining via +.and()+.

Parameter:: Specifies a fragment of an HTTP request that may be referenced in both +Condition+ and +Operation+ instances. Parameters are defined using the +.where()+ method of the +ConfigurationBuilder+, which is available once the first +Rule+ (with conditions or operations) has been added.

Rule:: A pre-constructed combination of +Condition+ and +Operation+ instances. You should use a +Rule+ when simple composition of +Condition+ and +Operation+ instances in a +ConfigurationBuilder+ is too difficult to achieve the desired functionality.

=== Activate Development Mode
By default, Rewrite uses a +ConfigurationCacheProvider+ that stores your configuration in the +ServletContext+ as an application-wide caching medium. This means, by default, all registered +ConfigurationProvider+ instances will be loaded once upon application startup, and never again.

To disable the default caching mechanism, and enable configuration reloading on each request, add the following servlet context init parameter to web.xml:

[source,xml]
----
<context-param>
   <param-name>org.ocpsoft.rewrite.config.CONFIG_RELOADING</param-name>
   <param-value>true</param-value>
</context-param>
----
Make sure to disable this option before deploying to production, since larger and more complex configurations may take some time to re-load.

=== Start using Rewrite rules

Now that you have Rewrite installed, and understand the basic terms, let's start writing some rules. We will start with a simple example: logging an inbound request URL to the server console.

First, open the +ConfigurationProvider+ you defined during link:install[installation] and add the desired logging statement using the +.addRule()+ method of +ConfigurationBuilder+.

[source,java]
.Log an inbound request to the server console
----
public class ApplicationConfigurationProvider extends HttpConfigurationProvider
{

   @Override
   public Configuration getConfiguration(ServletContext context)
   {
      return ConfigurationBuilder.begin()
               .addRule()
               .when(Direction.isInbound().and(Path.matches("/{path}")))
               .perform(Log.message(Level.INFO, "Client requested path: {path}"))
               .where("path").matches(".*");
   }

}
----

By default, parameters defined within the +Path+ condition match all characters except for forward slash "+/+". To change this, we must configure the parameter manually. Once complete, our rule matches any inbound request, with any number of path segments.

TIP: Parameter configuration can be used any time when parameters have been specified using the +ConfigurationBuilder+.

[source,console]
.Log output
----
INFO [org.ocpsoft.config.Log] Client requested path: /foo
INFO [org.ocpsoft.config.Log] Client requested path: /foo/bar
...
----

[NOTE]
====
If you attempt to configure a parameter that does not exist, you will quickly find out upon application startup; your deployment will halt on exception:

[source,console]
----
.where("foo").matches(".*");
...
java.lang.IllegalArgumentException: No such parameter [ foo ] exists.
----
====

==== A closer look

Now that we have written a rule that uses a few different +Operation+ and +Condition+ objects, lets take a look at how the interaction works - we will break down the entire rule:

[source,java]
----
ConfigurationBuilder.begin()
   .addRule()
   .when(Direction.isInbound().and(Path.matches("/{path}")))
   .perform(Log.message(Level.INFO, "Client requested path: {path}"))
   .where("path").matches(".*");
----

===== The breakdown
+ConfigurationBuilder.begin().addRule()+:: Begins a new fluent +Configuration+ object and adds a fluent +Rule+

`.when(Direction.isInbound().and(Path.matches("/{path}")))`:: Specifies that the rule should match only on inbound requests, and only when the request path matches the pattern `/[^/]+`, which is specified by our use of the parameter `{path}`

`.perform(Log.message(Level.INFO, "Client requested path: {path}"))`:: Specify the +Operation+ to be performed when all conditions are met. Operations may be chained using the +.and()+ method available on most operation instances.

`.where("path").matches(".*")`:: Configures the +Parameter+ named "+path+", and specifies that it must match the link:http://ocpsoft.org/opensource/guide-to-regular-expressions-in-java-part-1/[regular expression] pattern "+.*+"

==== Add another operation

Now say we wish to forward each inbound request to a Servlet or JSP that will handle the request and render a response for the client. We can achieve this by adding the +Forward+ operation to the set of operations to be performed when all rule conditions have been met. Forwards are purely internal operations, and the client browser URL will not be updated.

[source,java]
----
ConfigurationBuilder.begin()
   .addRule()
   .when(Direction.isInbound().and(Path.matches("/{path}")))
   .perform(Log.message(Level.INFO, "Client requested path: {path}")
              .and(Forward.to("/Servlet?path={path}")))
   .where("path").matches(".*");
----

Notice that we have specified a new Operation: +Forward.to("/Servlet?path={path}")+; this will again re-use the "+path+" parameter. The example below demonstrates how an inbound request will be forwarded to an inbound resource.

TIP: Operations are performed in the order in which they are added to the rule, so make sure that breaking operations such as +Forward+, +Redirect+, +Substitute+, and +Lifecycle+ are added last, or your +Operation+ may not be performed.

== Rewrite Configuration Manual

There are many types of configuration objects in link:../[Rewrite], so we will take a few moments to define a few of the core terms before continuing to more advanced topics. Most of the core objects can be found in the +org.ocpsoft.rewrite.config+ package, while Servlet specific objects can be found in the +org.ocpsoft.rewrite.servlet.config+ package.

=== Download and install

Before continuing on to learn about configuring Rewrite, make sure that you have already followed the link:./install[installation guide]. This will ensure that Rewrite is successfully set up in your application.

=== The terminology

It may be helpful to review the following terms, many of which will make frequent appearances in this documentation.

ConfigurationProvider:: An object that provides +Configuration+ instances to the Rewrite framework; these may be created and registered as necessary. If not using link:./annotations/index[Rewrite Annotations], or other extensions, you must have at least one registered +ConfigurationProvider+ or Rewrite will not have any effect.

Configuration:: A collection of +Rule+ objects that are processed in order until the system has determined the current inbound or oubound Rewrite event has been handled. Configurations may be provided by extensions, cached for performance, or built dynamically at run-time.

ConfigurationBuilder:: This is likely the object you will interact with most when configuring the Rewrite system. Start with a +ConfigurationBuilder+ in each situation where you find yourself in need of a +Configuration+ object; this class may be used to add pre-constructed, or contruct custom +Rule+ instances for Rewrite.

Condition:: Defines a requirement that must be met in order for rule evaluation to return true. You may create custom +Condition+ implementations. If creating custom implementations, you should likely extend +DefaultConditionBuilder+, which  adds logical operators +.and()+, +.or()+, and +.not()+.

Operation:: Defines behavior to be performed after evaluation a +Rewrite+ event. These objects may be as simple or as complex as desired, ranging from simple logging to request forwarding. Typically +Operation+ instances may be chained to achieve more complex tasks. If creating custom umplementations, you should likely extend +DefaultOperationBuilder+, which adds logical chaining via +.and()+.

Parameter:: Specifies a fragment of an HTTP request that may be referenced in both +Condition+ and +Operation+ instances. Parameters are defined using the +.where()+ method of the +ConfigurationBuilder+, which is available once the first +Rule+ (with conditions or operations) has been added.

Rule:: A pre-constructed combination of +Condition+ and +Operation+ instances. You should use a +Rule+ when simple composition of +Condition+ and +Operation+ instances in a +ConfigurationBuilder+ is too difficult to achieve the desired functionality.

=== Activate Development Mode
By default, Rewrite uses a +ConfigurationCacheProvider+ that stores your configuration in the +ServletContext+ as an application-wide caching medium. This means, by default, the +Configuration+ will be loaded once upon application startup, and never again.

To disable the default caching mechanism, and enable +Configuration+ reloading on each request, add the following servlet context init parameter to web.xml:

[source,xml]
----
<context-param>
   <param-name>org.ocpsoft.rewrite.config.CONFIG_RELOADING</param-name>
   <param-value>true</param-value>
</context-param>
----
Make sure to disable this option before deploying to production, since larger and more complex configurations may take some time to re-load.

=== Start using Rewrite rules

Now that you have Rewrite installed, and understand the basic terms, let's start writing some rules. We will start with a simple example: logging an inbound request URL to the server console.

First, open the +ConfigurationProvider+ you defined during link:install[installation] and add the desired logging statement using the +.addRule()+ method of +ConfigurationBuilder+.

[source,java]
.Log an inbound request to the server console
----
public class ApplicationConfigurationProvider extends HttpConfigurationProvider
{

   @Override
   public Configuration getConfiguration(ServletContext context)
   {
      return ConfigurationBuilder.begin()
               .addRule()
               .when(Direction.isInbound().and(Path.matches("/{path}")))
               .perform(Log.message(Level.INFO, "Client requested path: {path}"))
               .where("path").matches(".*");
   }

}
----

By default, parameters defined within the +Path+ condition match all characters except for forward slash "+/+". To change this, we must configure the parameter manually. Once complete, our rule matches any inbound request, with any number of path segments.

TIP: Parameter configuration can be used any time when parameters have been specified using the +ConfigurationBuilder+.

[source,console]
.Log output
----
INFO [org.ocpsoft.config.Log] Client requested path: /foo
INFO [org.ocpsoft.config.Log] Client requested path: /foo/bar
...
----

[NOTE]
====
If you attempt to configure a parameter that does not exist, you will quickly find out upon application startup; your deployment will halt on exception:

[source,console]
----
.where("foo").matches(".*");
...
java.lang.IllegalArgumentException: No such parameter [ foo ] exists.
----
====

==== A closer look

Now that we have written a rule that uses a few different +Operation+ and +Condition+ objects, lets take a look at how the interaction works - we will break down the entire rule:

[source,java]
----
ConfigurationBuilder.begin()
   .addRule()
   .when(Direction.isInbound().and(Path.matches("/{path}")))
   .perform(Log.message(Level.INFO, "Client requested path: {path}"))
   .where("path").matches(".*");
----

===== The breakdown
+ConfigurationBuilder.begin().addRule()+:: Begins a new fluent +Configuration+ object and adds a fluent +Rule+

`.when(Direction.isInbound().and(Path.matches("/{path}")))`:: Specifies that the rule should match only on inbound requests, and only when the request path matches the pattern `/[^/]+`, which is specified by our use of the parameter `{path}`

`.perform(Log.message(Level.INFO, "Client requested path: {path}"))`:: Specify the +Operation+ to be performed when all conditions are met. Operations may be chained using the +.and()+ method available on most operation instances.

`.where("path").matches(".*")`:: Configures the +Parameter+ named "+path+", and specifies that it must match the link:http://ocpsoft.org/opensource/guide-to-regular-expressions-in-java-part-1/[regular expression] pattern "+.*+"

==== Add another operation

Now say we wish to forward each inbound request to a Servlet or JSP that will handle the request and render a response for the client. We can achieve this by adding the +Forward+ operation to the set of operations to be performed when all rule conditions have been met. Forwards are purely internal operations, and the client browser URL will not be updated.

[source,java]
----
ConfigurationBuilder.begin()
   .addRule()
   .when(Direction.isInbound().and(Path.matches("/{path}")))
   .perform(Log.message(Level.INFO, "Client requested path: {path}")
              .and(Forward.to("/Servlet?path={path}")))
   .where("path").matches(".*");
----

Notice that we have specified a new Operation: +Forward.to("/Servlet?path={path}")+; this will again re-use the "+path+" parameter. The example below demonstrates how an inbound request will be forwarded to an inbound resource.

TIP: Operations are performed in the order in which they are added to the rule, so make sure that breaking operations such as +Forward+, +Redirect+, +Substitute+, and +Lifecycle+ are added last, or your +Operation+ may not be performed.


Update ios.adoc

Update ios.adoc

Broke long monospace into 2 lines.

= ios
:author:
:revnumber:
:revdate: 2016/03/17 20:48
:keywords: documentation, iOS, Mac, MacOS, deployment, platform
:relfileprefix: ../
:imagesdir: ..
ifdef::env-github,env-browser[:outfilesuffix: .adoc]

== iOS Deployment

To use iOS deployment you need a computer running MacOSX and a version of Xcode 4.0+ installed. To deploy to a device or the Apple App Store, you need an Apple developer account.

[WARNING]
====
Note that at the moment iOS deployment is in alpha state.
====

iOS deployment works via cross-compilation to native iOS ARM code, there is no virtual machine running on the device. The Avian JVM supports this feature while maintaining general compatibility to OpenJDK and JNI for native access. The minimum compatible iOS deployment target is 4.3.

[TIP]
====
To install the iOS deployment plugin, go to Tools→Plugins and under “Available plugins select the “iOS Support plugin.
====

=== Enabling iOS deployment

To enable iOS deployment, go to the project settings and under “Application→iOS select the “Enable iOS deployment checkbox, adapt the application ID and then press OK.

image:jme3/ios-deployment.png[ios-deployment.png,width="",height=""]

After enabling deployment, a new `ios` directory is created in the project root that contains a `project` and a `src` folder. The `ios/project` folder contains an Xcode project that you will use to build and run the final iOS application for both iPhone and iOS. The `ios/src` folder contains java and native source files for bridging iOS and native code, you can add .java and .m files with your own iOS code here.

[IMPORTANT]
====
When you enable iOS deployment for the first time or any time that the Avian library and OpenJDK is updated, they will be extracted to your SDK settings folder, wait until it has been extracted before building an iOS-enabled project.
====

=== Building the iOS binaries

The iOS binaries are automatically built when you have iOS deployment enabled and build your project in the jME3 SDK.

When the iOS binaries are built, all needed classes, including a complete copy of the OpenJDK7 classes are run through a proguard process that strips out the unnecessary classes for the project and optimizes the code for the platform. This happens without changing the naming structure so that reflection etc. still works. If necessary, adapt the proguard options in the ios properties file.

After the iOS classpath has been created the avian compiler is used to create a native .o file from the classpath for both arm (device) and i386 (simulator). Furthermore the other needed avian .o files are extracted and a library list is compiled which is referenced in the Xcode project.

If an error occurs about jni.h not being found, either install the SDK for 10.9 in XCode or set the header search path in the XCode project settings, in the default project thats +
`/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/` +
`SDKs/MacOSX10.9.sdk/System/Library/Frameworks/JavaVM.framework/Headers/`

=== Running and deploying the application

To run the application, open the Xcode project under `ios/project` in Xcode and press the run button. You can make changes to the UI and native invocation classes in the Xcode project as well. From here you can also deploy the application to your devices or the App Store.

[TIP]
====
Note that you should also adapt the project settings like application name and registration package in Xcode before deploying the final application.
====

=== Creating native and java code for iOS

To bridge between native and java code, JNI is used like in a normal java application. The `ios/src` folder is for Java and C/Obj-C source files that are specific to your iOS application. In these java files you have access to the full project classpath as well as the iOS-specific jME3 classes.

The JmeAppHarness.java class is initialized and called from native code through the default project and you can extend it to perform other native operations. It has a simple native popup method. The JmeAppHarness.m file contains the native method needed for that popup.

Effectively native code can reside in both the Xcode project and in the `ios/src` folder. To keep the dependencies clean and make code reusable you should try to put generic native code that does not depend on the Xcode project in the `ios/src` folder. You can also mix and match ARC and non-ARC code through this by converting the main project to use ARC and putting code with manual memory management in the `ios/src` folder.

Java code for iOS should be in the `ios/src` folder as well for clean separation, its also the only place where they will be compiled with a reference to the iOS specific jME classes. For information on how to connect your application code and device specific code, see the <<jme3/android#using_android_specific_functions,notes in the android deployment documentation>>.

= ios
:author:
:revnumber:
:revdate: 2016/03/17 20:48
:keywords: documentation, iOS, Mac, MacOS, deployment, platform
:relfileprefix: ../
:imagesdir: ..
ifdef::env-github,env-browser[:outfilesuffix: .adoc]

== iOS Deployment

To use iOS deployment you need a computer running MacOSX and a version of Xcode 4.0+ installed. To deploy to a device or the Apple App Store, you need an Apple developer account.

[WARNING]
====
Note that at the moment iOS deployment is in alpha state.
====

iOS deployment works via cross-compilation to native iOS ARM code, there is no virtual machine running on the device. The Avian JVM supports this feature while maintaining general compatibility to OpenJDK and JNI for native access. The minimum compatible iOS deployment target is 4.3.

[TIP]
====
To install the iOS deployment plugin, go to Tools→Plugins and under “Available plugins select the “iOS Support plugin.
====

=== Enabling iOS deployment

To enable iOS deployment, go to the project settings and under “Application→iOS select the “Enable iOS deployment checkbox, adapt the application ID and then press OK.

image:jme3/ios-deployment.png[ios-deployment.png,width="",height=""]

After enabling deployment, a new `ios` directory is created in the project root that contains a `project` and a `src` folder. The `ios/project` folder contains an Xcode project that you will use to build and run the final iOS application for both iPhone and iOS. The `ios/src` folder contains java and native source files for bridging iOS and native code, you can add .java and .m files with your own iOS code here.

[IMPORTANT]
====
When you enable iOS deployment for the first time or any time that the Avian library and OpenJDK is updated, they will be extracted to your SDK settings folder, wait until it has been extracted before building an iOS-enabled project.
====

=== Building the iOS binaries

The iOS binaries are automatically built when you have iOS deployment enabled and build your project in the jME3 SDK.

When the iOS binaries are built, all needed classes, including a complete copy of the OpenJDK7 classes are run through a proguard process that strips out the unnecessary classes for the project and optimizes the code for the platform. This happens without changing the naming structure so that reflection etc. still works. If necessary, adapt the proguard options in the ios properties file.

After the iOS classpath has been created the avian compiler is used to create a native .o file from the classpath for both arm (device) and i386 (simulator). Furthermore the other needed avian .o files are extracted and a library list is compiled which is referenced in the Xcode project.

If an error occurs about jni.h not being found, either install the SDK for 10.9 in XCode or set the header search path in the XCode project settings, in the default project thats +
`/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/JavaVM.framework/Headers/`

=== Running and deploying the application

To run the application, open the Xcode project under `ios/project` in Xcode and press the run button. You can make changes to the UI and native invocation classes in the Xcode project as well. From here you can also deploy the application to your devices or the App Store.

[TIP]
====
Note that you should also adapt the project settings like application name and registration package in Xcode before deploying the final application.
====

=== Creating native and java code for iOS

To bridge between native and java code, JNI is used like in a normal java application. The `ios/src` folder is for Java and C/Obj-C source files that are specific to your iOS application. In these java files you have access to the full project classpath as well as the iOS-specific jME3 classes.

The JmeAppHarness.java class is initialized and called from native code through the default project and you can extend it to perform other native operations. It has a simple native popup method. The JmeAppHarness.m file contains the native method needed for that popup.

Effectively native code can reside in both the Xcode project and in the `ios/src` folder. To keep the dependencies clean and make code reusable you should try to put generic native code that does not depend on the Xcode project in the `ios/src` folder. You can also mix and match ARC and non-ARC code through this by converting the main project to use ARC and putting code with manual memory management in the `ios/src` folder.

Java code for iOS should be in the `ios/src` folder as well for clean separation, its also the only place where they will be compiled with a reference to the iOS specific jME classes. For information on how to connect your application code and device specific code, see the <<jme3/android#using_android_specific_functions,notes in the android deployment documentation>>.


two additional fixes

two additional fixes

:filename: manual/02_install.adoc

= How to install docToolchain

include::feedback.adoc[]

== Get the tool

To start with docToolchain you need to get a copy of the current docToolchain repository.
The easiest way is to clone the repository without history and remove the `.git` folder:

.Linux with git clone
[source,bash]
----
git clone --recursive https://github.com/docToolchain/docToolchain.git <docToolchain home>
rm -rf .git
rm -rf resources/asciidoctor-reveal.js/.git
rm -rf resources/reveal.js/.git
----

`--recursive` option is required because the repository contains 2 submodules - `resources/asciidoctor-reveal.js` and `resources/reveal.js`.

Another way is to download the zipped git repository and rename it:

.Linux with download as zip
[source, bash]
----
wget https://github.com/docToolchain/docToolchain/archive/master.zip
unzip master.zip

# fetching dependencies

cd docToolchain-master/resources

rm -d reveal.js
wget https://github.com/hakimel/reveal.js/archive/tags/3.3.0.zip -O reveal.js.zip
unzip reveal.js.zip
mv reveal.js-tags-3.3.0 reveal.js

rm -d asciidoctor-reveal.js
wget https://github.com/asciidoctor/asciidoctor-reveal.js/archive/9667f5c.zip -O asciidoctor-reveal.js.zip
unzip asciidoctor-reveal.js.zip
mv asciidoctor-reveal.js-9667f5c5d926b3be48361d6d6413d3896954894c asciidoctor-reveal.js

mv docToolchain-master <docToolchain home>
----

If you work (like me) on a Windows environment, just download and unzip the https://github.com/docToolchain/docToolchain/archive/master.zip[repository] as well as its dependencies:
https://github.com/hakimel/reveal.js/archive/tags/3.3.0.zip[reveal.js] and
https://github.com/asciidoctor/asciidoctor-reveal.js/archive/9667f5c.zip[asciidoctor-reveal.js].

After unzipping, put the dependencies in `resources` folder, so that the structure is the same as on https://github.com/docToolchain/docToolchain/tree/master/resources[GitHub].

//[source]
//----
//(New-Object Net.WebClient).DownloadFile('https://github.com/docToolchain/docToolchain/archive/master.zip','master.zip')
//----

You can add <docToolchain home>/bin to your PATH or you can run doctoolchain with full path if you prefer.

== Initialize directory for documents

The next step after getting docToolchain is to initialize a directory where your documents live. In docToolchain this
directory is named "newDocDir" during initialization, or just "docDir" later on.

=== Existing documents

If you already have some existing documents in AsciiDoc format in your project, you need to put the configuration
file there to inform docToolchain what and how to process. You can do that manually by copying the contents of
template_config directory. You can also do that by running `initExisting` task.

.Linux initExisting example
[source, bash]
----
cd <docToolchain home>
./gradlew -b init.gradle initExisting -PnewDocDir=<your directory>
----

You need to open Config.groovy file and configure names of your files properly.
You may also change the PDF schema file to your taste.

=== arc42 from scratch

If you don't have existing documents yet, or if you need a fresh start, you can get the https://arc42.org[arc42] template in AsciiDoc
format. You can do that by manually downloading from https://arc42.org/download. You can also to that by running
`initArc42<language>` task. Currently supported languages are:

- DE - German
- EN - English
- ES - Spanish
- RU - Russian

.Linux initArc42EN example
[source, bash]
----
cd <docToolchain home>
./gradlew -b init.gradle initArc42EN -PnewDocDir=<newDocDir>
----

The Config.groovy file is then preconfigured to use the downloaded template.

IMPORTANT: there is currently https://github.com/docToolchain/docToolchain/issues/259[a bug] in the setup / configuration if you use this approach to install docToolchain. To workaround it, go to <docToolchain home> and set the `inputPath` property in `gradle.properties` to `.`. Alternativly, use the approach described in our https://docs-as-co.de/getstarted/tutorial2[tutorial].

TIP: Blog-Post: https://rdmueller.github.io/arc42/[Let's add Content!]

== Build

This should already be enough to start a first build.

By now, docToolchain should be installed as command line tool and the path to its `bin` folder should be on your path.
If you now switch to your freshly initialized <newDocDir>, you should be able to execute the following commands:

.Linux
[source, bash]
----
doctoolchain <docDir> generateHTML
doctoolchain <docDir> generatePDF
----

.Windows
[source]
----
doctoolchain.bat <docDir> generateHTML
doctoolchain.bat <docDir> generatePDF
----

<docDir> may be relative, e.g. ".", or absolute.

As a result, you will see the progress of your build together with some warnings which you can just ignore for the moment.

The first build generated some files within the `<docDir>/build`:

[source]
----
build
|-- html5
|   |-- arc42-template.html
|   `-- images
|       |-- 05_building_blocks-EN.png
|       |-- 08-Crosscutting-Concepts-Structure-EN.png
|       `-- arc42-logo.png
`-- pdf
    |-- arc42-template.pdf
    `-- images
        |-- 05_building_blocks-EN.png
        |-- 08-Crosscutting-Concepts-Structure-EN.png
        `-- arc42-logo.png
----

*Congratulations!* if you see the same folder structure, you just managed to render the standard arc42 template as html and pdf!

If you didn't get the right output, please raise an issue on https://github.com/docToolchain/docToolchain/issues[github]

TIP: Blog-Posts: https://rdmueller.github.io/enterprise-edition/[Behind the great Firewall], https://rdmueller.github.io/enterprise-edition2/[Enterprise AsciiDoctor]

== Publish to Confluence

In addition to `Config.groovy` there is also a `scripts/ConfluenceConfig.groovy` file. If you are not using Confluence
you can remove it. If you use Confluence, then you need to open this file and adapt to your environment.
You can also create multiple copies of that file. For example you can have `ConfluenceConfig.groovy` for publishing
official pages, and `MyConfluenceConfig.groovy` with a different Confluence space for reviews.

The paths to those configuration files can be provided by giving -P option to doctoolchain, for example:

[source, bash]
----
# Uses scripts/ConfluenceConfig.groovy by default
doctoolchain <docDir> publishToConfluence --no-daemon -q

# Uses scripts/MyConfluenceConfig.groovy
doctoolchain <docDir> publishToConfluence -PconfluenceConfigFile=scripts/MyConfluenceConfig.groovy --no-daemon -q
----

:filename: manual/02_install.adoc

= How to install docToolchain

include::feedback.adoc[]

== Get the tool

To start with docToolchain you need to get a copy of the current docToolchain repository.
The easiest way is to clone the repository without history and remove the `.git` folder:

.Linux with git clone
[source,bash]
----
git clone --recursive https://github.com/docToolchain/docToolchain.git <docToolchain home>
rm -rf .git
rm -rf resources/asciidoctor-reveal.js/.git
rm -rf resources/reveal.js/.git
----

`--recursive` option is required because the repository contains 2 submodules - `resources/asciidoctor-reveal.js` and `resources/reveal.js`.

Another way is to download the zipped git repository and rename it:

.Linux with download as zip
[source, bash]
----
wget https://github.com/docToolchain/docToolchain/archive/master.zip
unzip master.zip

# fetching dependencies

cd docToolchain-master/resources

rm -d reveal.js
wget https://github.com/hakimel/reveal.js/archive/tags/3.3.0.zip -O reveal.js.zip
unzip reveal.js.zip
mv reveal.js-tags-3.3.0 reveal.js

rm -d asciidoctor-reveal.js
wget https://github.com/asciidoctor/asciidoctor-reveal.js/archive/9667f5c.zip -O asciidoctor-reveal.js.zip
unzip asciidoctor-reveal.js.zip
mv asciidoctor-reveal.js-9667f5c5d926b3be48361d6d6413d3896954894c asciidoctor-reveal.js

mv docToolchain-master <docToolchain home>
----

If you work (like me) on a Windows environment, just download and unzip the https://github.com/docToolchain/docToolchain/archive/master.zip[repository] as well as its dependencies:
https://github.com/hakimel/reveal.js/archive/tags/3.3.0.zip[reveal.js] and
https://github.com/asciidoctor/asciidoctor-reveal.js/archive/9667f5c.zip[asciidoctor-reveal.js].

After unzipping, put the dependencies in `resources` folder, so that the structure is the same as on https://github.com/docToolchain/docToolchain/tree/master/resources[GitHub].

//[source]
//----
//(New-Object Net.WebClient).DownloadFile('https://github.com/docToolchain/docToolchain/archive/master.zip','master.zip')
//----

You can add <docToolchain home>/bin to your PATH or you can run doctoolchain with full path if you prefer.

== Initialize directory for documents

The next step after getting docToolchain is to initialize a directory where your documents live. In docToolchain this
directory is named "newDocDir" during initialization, or just "docDir" later on.

=== Existing documents

If you already have some existing documents in AsciiDoc format in your project, you need to put the configuration
file there to inform docToolchain what and how to process. You can do that manually by copying the contents of
template_config directory. You can also do that by running `initExisting` task.

.Linux initExisting example
[source, bash]
----
cd <docToolchain home>
./gradlew -b init.gradle initExisting -PnewDocDir=<your directory>
----

You need to open Config.groovy file and configure names of your files properly.
You may also change the PDF schema file to your taste.

=== arc42 from scratch

If you don't have existing documents yet, or if you need a fresh start, you can get the https://arc42.org[arc42] template in AsciiDoc
format. You can do that by manually downloading from https://arc42.org/download. You can also to that by running
`initArc42<language>` task. Currently supported languages are:

- DE - German
- EN - English
- ES - Spanish
- RU - Russian

.Linux initArc42EN example
[source, bash]
----
cd <docToolchain home>
./gradlew -b init.gradle initArc42EN -PnewDocDir=<newDocDir>
----

The Config.groovy file is then preconfigured to use the downloaded template.

IMPORTANT: there is currently https://github.com/docToolchain/docToolchain/issues/259[a bug] in the setup / configuration if you use this approach to install docToolchain. To workaround it, go to <docToolchain home> and set the `inputPath` property in `gradle.properties` to `.`. Alternativly, use the approach described in our https://docs-as-co.de/getstarted/tutorial2[tutorial].

TIP: Blog-Post: https://rdmueller.github.io/arc42/[Let's add Content!]

== Build

This should already be enough to start a first build.

By now, docToolchain should be installed as command line tool and the path to its `bin` folder should be on your path.
If you now switch to your freshly initialized <newDocDir>, you should be able to execute the following commands:

.Linux
[source, bash]
----
doctoolchain <docDir> generateHTML
doctoolchain <docDir> generatePDF
----

.Windows
[source]
----
doctoolchain.bat <docDir> generateHTML
doctoolchain.bat <docDir> generatePDF
----

<docDir> may be relative, e.g. ".", or absolute.

As a result, you will see the progress of your build together with some warnings which you can just ignore for the moment.

The first build generated some files within the `<docDir>/build`:

[source]
----
build
|-- html5
|   |-- arc42-template.html
|   `-- images
|       |-- 05_building_blocks-EN.png
|       |-- 08-Crosscutting-Concepts-Structure-EN.png
|       `-- arc42-logo.png
`-- pdf
    |-- arc42-template.pdf
    `-- images
        |-- 05_building_blocks-EN.png
        |-- 08-Crosscutting-Concepts-Structure-EN.png
        `-- arc42-logo.png
----

*Congratulations!* if you see the same folder structure, you just managed to render the standard arc42 template as html and pdf!

If you didn't get the right output, please raise an issue on https://github.com/docToolchain/docToolchain/issues[github]

TIP: Blog-Posts: https://rdmueller.github.io/enterprise-edition/[Behind the great Firewall], https://rdmueller.github.io/enterprise-edition2/[Enterprise AsciiDoctor]

== Publish to Confluence

In addition to `Config.groovy` there is also a `scripts/ConfluenceConfig.groovy` file. If you are not using Confluence
you can remove it. If you use Confluence, then you need to open this file and adapt to your environment.
You can also create multiple copies of that file. For example you can have `ConfluenceConfig.groovy` for publishing
official pages, and `MyConfluenceConfig.groovy` with a different Confluence space for reviews.

The paths to those configuration files can be provided by giving -P option to doctoolchain, for example:

[source, bash]
----
# Uses scripts/ConfluenceConfig.groovy by default
bin/doctoolchain <docDir> publishToConfluence --no-daemon -q

# Uses scripts/MyConfluenceConfig.groovy
bin/doctoolchain <docDir> publishToConfluence -PconfluenceConfigFile=scripts/MyConfluenceConfig.groovy --no-daemon -q
----


BZ-1857151: Added a paragraph about shared VPC with link

[id="installing-gcp-user-infra-vpc"]
= Installing a cluster with shared VPC on user-provisioned infrastructure in GCP by using Deployment Manager templates
include::modules/common-attributes.adoc[]
:context: installing-gcp-user-infra-vpc

toc::[]

In {product-title} version {product-version}, you can install a cluster into a shared Virtual Private Cloud (VPC) on Google Cloud Platform (GCP) that uses infrastructure that you provide. In this context, a cluster installed into a shared VPC is a cluster that is configured to use a VPC from a project different from where the cluster is being deployed.

A shared VPC enables an organization to connect resources from multiple projects to a common VPC network. You can communicate within the organization securely and efficiently by using internal IPs from that network. For more information about shared VPC, see link:https://cloud.google.com/vpc/docs/shared-vpc[Shared VPC overview] in the GCP documentation.

The steps for performing a user-provided infrastructure installation into a shared VPC are outlined here. Several
link:https://cloud.google.com/deployment-manager/docs[Deployment Manager] templates are provided to assist in
completing these steps or to help model your own. You are also free to create
the required resources through other methods.

[IMPORTANT]
====
The steps for performing a user-provisioned infrastructure installation are provided as an example only. Installing a cluster with infrastructure you provide requires knowledge of the cloud provider and the installation process of {product-title}. Several Deployment Manager templates are provided to assist in completing these steps or to help model your own. You are also free to create the required resources through other methods; the templates are just an example.
====

== Prerequisites

* Review details about the
xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update]
processes.
* If you use a firewall and plan to use telemetry, you must
xref:../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configure the firewall to allow the sites] that your cluster requires access to.
* If you do not allow the system to manage identity and access management (IAM),
then a cluster administrator can
xref:../../installing/installing_gcp/manually-creating-iam-gcp.adoc#manually-creating-iam-gcp[manually
create and maintain IAM credentials]. Manual mode can also be used in
environments where the cloud IAM APIs are not reachable.
+
[NOTE]
====
Be sure to also review this site list if you are configuring a proxy.
====

[id="csr-management-gcp-vpc"]
== Certificate signing requests management

Because your cluster has limited access to automatic machine management when you
use infrastructure that you provision, you must provide a mechanism for approving
cluster certificate signing requests (CSRs) after installation. The
`kube-controller-manager` only approves the kubelet client CSRs. The
`machine-approver` cannot guarantee the validity of a serving certificate
that is requested by using kubelet credentials because it cannot confirm that
the correct machine issued the request. You must determine and implement a
method of verifying the validity of the kubelet serving certificate requests
and approving them.

[id="installation-gcp-user-infra-config-project-vpc"]
== Configuring the GCP project that hosts your cluster

Before you can install {product-title}, you must configure a Google Cloud
Platform (GCP) project to host it.

include::modules/installation-gcp-project.adoc[leveloffset=+2]
include::modules/installation-gcp-enabling-api-services.adoc[leveloffset=+2]
include::modules/installation-gcp-limits.adoc[leveloffset=+2]
include::modules/installation-gcp-service-account.adoc[leveloffset=+2]
include::modules/installation-gcp-permissions.adoc[leveloffset=+3]
include::modules/installation-gcp-regions.adoc[leveloffset=+2]
include::modules/installation-gcp-install-cli.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-config-host-project-vpc.adoc[leveloffset=+1]
include::modules/installation-gcp-dns.adoc[leveloffset=+2]
include::modules/installation-creating-gcp-vpc.adoc[leveloffset=+2]
include::modules/installation-deployment-manager-vpc.adoc[leveloffset=+3]

include::modules/installation-user-infra-generate.adoc[leveloffset=+1]

include::modules/installation-initializing-manual.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-shared-vpc-config-yaml.adoc[leveloffset=+2]

include::modules/installation-configure-proxy.adoc[leveloffset=+2]

//include::modules/installation-three-node-cluster.adoc[leveloffset=+2]

include::modules/installation-user-infra-generate-k8s-manifest-ignition.adoc[leveloffset=+2]
.Additional resources

[id="installation-gcp-user-infra-exporting-common-variables-vpc"]
== Exporting common variables

include::modules/installation-extracting-infraid.adoc[leveloffset=+2]
include::modules/installation-user-infra-exporting-common-variables.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-lb.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-ext-lb.adoc[leveloffset=+2]
include::modules/installation-deployment-manager-int-lb.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-private-dns.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-private-dns.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-firewall-rules-vpc.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-firewall-rules.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-iam-shared-vpc.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-iam-shared-vpc.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-rhcos.adoc[leveloffset=+1]

include::modules/installation-creating-gcp-bootstrap.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-bootstrap.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-control-plane.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-control-plane.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-wait-for-bootstrap.adoc[leveloffset=+1]

include::modules/installation-creating-gcp-worker.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-worker.adoc[leveloffset=+2]

include::modules/cli-installing-cli.adoc[leveloffset=+1]

include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1]

include::modules/installation-approve-csrs.adoc[leveloffset=+1]

include::modules/installation-gcp-user-infra-adding-ingress.adoc[leveloffset=+1]

[id="installation-gcp-user-infra-vpc-adding-firewall-rules"]
== Adding ingress firewall rules
The cluster requires several firewall rules. If you do not use a shared VPC, these rules are created by the ingress controller via the GCP cloud provider. When you use a shared VPC, you can either create cluster-wide firewall rules for all services now or create each rule based on events, when the cluster requests access. By creating each rule when the cluster requests access, you know exactly which firewall rules are required. By creating cluster-wide firewall rules, you can apply the same rule set across multiple clusters.

If you choose to create each rule based on events, you must create firewall rules after you provision the cluster and during the life of the cluster when the console notifies you that rules are missing. Events that are similar to the following event are displayed, and you must add the firewall rules that are required:

[source,terminal]
----
$ oc get events -n openshift-ingress --field-selector="reason=LoadBalancerManualChange"
----

.Example output
[source,terminal]
----
Firewall change required by security admin: `gcloud compute firewall-rules create k8s-fw-a26e631036a3f46cba28f8df67266d55 --network example-network --description "{\"kubernetes.io/service-name\":\"openshift-ingress/router-default\", \"kubernetes.io/service-ip\":\"35.237.236.234\"}\" --allow tcp:443,tcp:80 --source-ranges 0.0.0.0/0 --target-tags exampl-fqzq7-master,exampl-fqzq7-worker --project example-project`
----

If you encounter issues when creating these rule-based events, you can configure the cluster-wide firewall rules while your cluster is running.

include::modules/installation-creating-gcp-shared-vpc-cluster-wide-firewall-rules.adoc[leveloffset=+2]

//include::modules/installation-creating-gcp-shared-vpc-ingress-firewall-rules.adoc[leveloffset=+1]

include::modules/installation-gcp-user-infra-completing.adoc[leveloffset=+1]

== Next steps

* xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster].
* If necessary, you can
xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting].

[id="installing-gcp-user-infra-vpc"]
= Installing a cluster with shared VPC on user-provisioned infrastructure in GCP by using Deployment Manager templates
include::modules/common-attributes.adoc[]
:context: installing-gcp-user-infra-vpc

toc::[]

In {product-title} version {product-version}, you can install a cluster into a shared Virtual Private Cloud (VPC) on Google Cloud Platform (GCP) that uses infrastructure that you provide. In this context, a cluster installed into a shared VPC is a cluster that is configured to use a VPC from a project different from where the cluster is being deployed. For more information, see Google's documentation on link:https://cloud.google.com/vpc/docs/shared-vpc#shared_vpc_networks[shared VPC networks].

The steps for performing a user-provided infrastructure installation into a shared VPC are outlined here. Several
link:https://cloud.google.com/deployment-manager/docs[Deployment Manager] templates are provided to assist in
completing these steps or to help model your own. You are also free to create
the required resources through other methods.

[IMPORTANT]
====
The steps for performing a user-provisioned infrastructure installation are provided as an example only. Installing a cluster with infrastructure you provide requires knowledge of the cloud provider and the installation process of {product-title}. Several Deployment Manager templates are provided to assist in completing these steps or to help model your own. You are also free to create the required resources through other methods; the templates are just an example.
====

== Prerequisites

* Review details about the
xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update]
processes.
* If you use a firewall and plan to use telemetry, you must
xref:../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configure the firewall to allow the sites] that your cluster requires access to.
* If you do not allow the system to manage identity and access management (IAM),
then a cluster administrator can
xref:../../installing/installing_gcp/manually-creating-iam-gcp.adoc#manually-creating-iam-gcp[manually
create and maintain IAM credentials]. Manual mode can also be used in
environments where the cloud IAM APIs are not reachable.
+
[NOTE]
====
Be sure to also review this site list if you are configuring a proxy.
====

[id="csr-management-gcp-vpc"]
== Certificate signing requests management

Because your cluster has limited access to automatic machine management when you
use infrastructure that you provision, you must provide a mechanism for approving
cluster certificate signing requests (CSRs) after installation. The
`kube-controller-manager` only approves the kubelet client CSRs. The
`machine-approver` cannot guarantee the validity of a serving certificate
that is requested by using kubelet credentials because it cannot confirm that
the correct machine issued the request. You must determine and implement a
method of verifying the validity of the kubelet serving certificate requests
and approving them.

[id="installation-gcp-user-infra-config-project-vpc"]
== Configuring the GCP project that hosts your cluster

Before you can install {product-title}, you must configure a Google Cloud
Platform (GCP) project to host it.

include::modules/installation-gcp-project.adoc[leveloffset=+2]
include::modules/installation-gcp-enabling-api-services.adoc[leveloffset=+2]
include::modules/installation-gcp-limits.adoc[leveloffset=+2]
include::modules/installation-gcp-service-account.adoc[leveloffset=+2]
include::modules/installation-gcp-permissions.adoc[leveloffset=+3]
include::modules/installation-gcp-regions.adoc[leveloffset=+2]
include::modules/installation-gcp-install-cli.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-config-host-project-vpc.adoc[leveloffset=+1]
include::modules/installation-gcp-dns.adoc[leveloffset=+2]
include::modules/installation-creating-gcp-vpc.adoc[leveloffset=+2]
include::modules/installation-deployment-manager-vpc.adoc[leveloffset=+3]

include::modules/installation-user-infra-generate.adoc[leveloffset=+1]

include::modules/installation-initializing-manual.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-shared-vpc-config-yaml.adoc[leveloffset=+2]

include::modules/installation-configure-proxy.adoc[leveloffset=+2]

//include::modules/installation-three-node-cluster.adoc[leveloffset=+2]

include::modules/installation-user-infra-generate-k8s-manifest-ignition.adoc[leveloffset=+2]
.Additional resources

[id="installation-gcp-user-infra-exporting-common-variables-vpc"]
== Exporting common variables

include::modules/installation-extracting-infraid.adoc[leveloffset=+2]
include::modules/installation-user-infra-exporting-common-variables.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-lb.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-ext-lb.adoc[leveloffset=+2]
include::modules/installation-deployment-manager-int-lb.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-private-dns.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-private-dns.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-firewall-rules-vpc.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-firewall-rules.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-iam-shared-vpc.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-iam-shared-vpc.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-rhcos.adoc[leveloffset=+1]

include::modules/installation-creating-gcp-bootstrap.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-bootstrap.adoc[leveloffset=+2]

include::modules/installation-creating-gcp-control-plane.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-control-plane.adoc[leveloffset=+2]

include::modules/installation-gcp-user-infra-wait-for-bootstrap.adoc[leveloffset=+1]

include::modules/installation-creating-gcp-worker.adoc[leveloffset=+1]
include::modules/installation-deployment-manager-worker.adoc[leveloffset=+2]

include::modules/cli-installing-cli.adoc[leveloffset=+1]

include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1]

include::modules/installation-approve-csrs.adoc[leveloffset=+1]

include::modules/installation-gcp-user-infra-adding-ingress.adoc[leveloffset=+1]

[id="installation-gcp-user-infra-vpc-adding-firewall-rules"]
== Adding ingress firewall rules
The cluster requires several firewall rules. If you do not use a shared VPC, these rules are created by the ingress controller via the GCP cloud provider. When you use a shared VPC, you can either create cluster-wide firewall rules for all services now or create each rule based on events, when the cluster requests access. By creating each rule when the cluster requests access, you know exactly which firewall rules are required. By creating cluster-wide firewall rules, you can apply the same rule set across multiple clusters.

If you choose to create each rule based on events, you must create firewall rules after you provision the cluster and during the life of the cluster when the console notifies you that rules are missing. Events that are similar to the following event are displayed, and you must add the firewall rules that are required:

[source,terminal]
----
$ oc get events -n openshift-ingress --field-selector="reason=LoadBalancerManualChange"
----

.Example output
[source,terminal]
----
Firewall change required by security admin: `gcloud compute firewall-rules create k8s-fw-a26e631036a3f46cba28f8df67266d55 --network example-network --description "{\"kubernetes.io/service-name\":\"openshift-ingress/router-default\", \"kubernetes.io/service-ip\":\"35.237.236.234\"}\" --allow tcp:443,tcp:80 --source-ranges 0.0.0.0/0 --target-tags exampl-fqzq7-master,exampl-fqzq7-worker --project example-project`
----

If you encounter issues when creating these rule-based events, you can configure the cluster-wide firewall rules while your cluster is running.

include::modules/installation-creating-gcp-shared-vpc-cluster-wide-firewall-rules.adoc[leveloffset=+2]

//include::modules/installation-creating-gcp-shared-vpc-ingress-firewall-rules.adoc[leveloffset=+1]

include::modules/installation-gcp-user-infra-completing.adoc[leveloffset=+1]

== Next steps

* xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster].
* If necessary, you can
xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting].


chore(promise-and-array): 文章の繋がりが悪くなったのを修正

[[ch2-promise-and-array]]
== Promiseと配列

ここまでで、promiseオブジェクトが FulFilled または Rejected となった時の処理は <<promise.then,`.then`>> と <<promise.catch,`.catch`>> で登録出来る事を学びました。

一つのpromiseオブジェクトなら、そのpromiseオブジェクトに対して処理を書けば良いですが、
複数のpromiseオブジェクトが全てFulFilledとなった時の処理を書く場合はどうすればよいでしょうか?

例えば、A->B->C という感じで複数のXHR(非同期処理)を行った後に、何かをしたいという事例を考えてみます。

ちょっとイメージしにくいので、
まずは、通常のコールバックスタイルを使って複数のXHRを行う以下のようなコードを見てみます。

=== コールバックで複数の非同期処理

[source,js]
[[multiple-xhr-callback.js]]
.multiple-xhr-callback.js
----
include::embed/embed-multiple-xhr-callback.js[]
----

上記のコードを実際に実行して、XHRで取得した結果を得るには次のようになると思います。

[source,js]
----
main(function(error, results){
    console.log(results);
});
----

このコールバックスタイルでは幾つかの要素が出てきます。

* `JSON.parse` をそのまま使うと例外となるケースがあるためラップした`jsonParse`関数を使う
* 複数のXHRをそのまま書くとネストが深くなるため、`allRequest`というrequest関数を実行するものを利用する
* コールバック関数には `callback(error,value)` というNode.jsでよく見られる引数を渡す

`jsonParse` 関数を使うときに `bind` を使うことで、部分適応を使って無名関数を減らすようにしています。
(コールバックスタイルでも関数の処理などをちゃんと分離すれば、無名関数の使用も減らせると思います)

[source,js]
----
jsonParse.bind(null, callback);
// は以下のように置き換えるのと殆ど同じ
function(error,value){
    jsonParse(callback, error, value);
}
----

コールバックスタイルで書いたものを見ると以下のような点が気になります。

* 明示的な例外のハンドリングが必要
* ネストを深くしないために、requestを扱う関数が必要
* コールバックがたくさんでてくる

次は、`Promise#then` を使って同様の事をしてみたいと思います。

=== Promise#thenのみで複数の非同期処理

先に述べておきますが、`Promise.all` というこのような処理に適切なものがあるため、
ワザと `.then`の部分をクドく書いています。

<<promise.then,`.then`>> を使った場合は、コールバックスタイルと完全に同等というわけではないですが以下のように書けると思います。

[source,js]
[[multiple-xhr.js]]
----
include::embed/embed-multiple-xhr.js[]
----

上記のコードを実際に実行して、XHRで取得した結果を得るには次のようになると思います。

[source,js]
----
main().then(function (value) {
    console.log(value);
}).catch(function(error){
    console.log(error);
});
----

<<multiple-xhr-callback.js, コールバックスタイル>>と比較してみると次の事がわかります。

* `JSON.parse` をそのまま使っている
* `main()` はpromiseオブジェクトを返している
* エラーハンドリングは返ってきたpromiseオブジェクトに対して書いている

先ほども述べたように mainの `then` の部分がクドく感じます。

このような複数の非同期処理をまとめて扱う `Promise.all` と `Promise.race` という静的メソッドについて
学んでいきましょう。

[[ch2-promise-and-array]]
== Promiseと配列

先ほどの章では、promiseオブジェクトがresolve又はrejectされた時の処理は <<promise.then,`.then`>> と <<promise.catch,`.catch`>> を
使うことで行える事を学びました。

一つのpromiseオブジェクトなら、そのpromiseオブジェクトに対して処理を書けば良いですが、
複数のpromiseオブジェクトに処理を書く場合はどうすればよいでしょうか?

例えば、A->B->C という感じで複数のXHR(非同期処理)を行った後に、何かをしたいという事例を考えてみます。

ちょっとイメージしにくいので、
まずは、通常のコールバックスタイルを使って複数のXHRを行う以下のようなコードを見てみます。

=== コールバックで複数の非同期処理

[source,js]
[[multiple-xhr-callback.js]]
.multiple-xhr-callback.js
----
include::embed/embed-multiple-xhr-callback.js[]
----

上記のコードを実際に実行して、XHRで取得した結果を得るには次のようになると思います。

[source,js]
----
main(function(error, results){
    console.log(results);
});
----

このコールバックスタイルでは幾つかの要素が出てきます。

* `JSON.parse` をそのまま使うと例外となるケースがあるためラップした`jsonParse`関数を使う
* 複数のXHRをそのまま書くとネストが深くなるため、`allRequest`というrequest関数を実行するものを利用する
* コールバック関数には `callback(error,value)` というNode.jsでよく見られる引数を渡す

`jsonParse` 関数を使うときに `bind` を使うことで、部分適応を使って無名関数を減らすようにしています。
(コールバックスタイルでも関数の処理などをちゃんと分離すれば、無名関数の使用も減らせると思います)

[source,js]
----
jsonParse.bind(null, callback);
// は以下のように置き換えるのと殆ど同じ
function(error,value){
    jsonParse(callback, error, value);
}
----

コールバックスタイルで書いたものを見ると以下のような点が気になります。

* 明示的な例外のハンドリングが必要
* ネストを深くしないために、requestを扱う関数が必要
* コールバックがたくさんでてくる

次は、`Promise#then` を使って同様の事をしてみたいと思います。

=== Promise#thenのみで複数の非同期処理

先に述べておきますが、`Promise.all` というこのような処理に適切なものがあるため、
ワザと `.then`の部分をクドく書いています。

<<promise.then,`.then`>> を使った場合は、コールバックスタイルと完全に同等というわけではないですが以下のように書けると思います。

[source,js]
[[multiple-xhr.js]]
----
include::embed/embed-multiple-xhr.js[]
----

上記のコードを実際に実行して、XHRで取得した結果を得るには次のようになると思います。

[source,js]
----
main().then(function (value) {
    console.log(value);
}).catch(function(error){
    console.log(error);
});
----

<<multiple-xhr-callback.js, コールバックスタイル>>と比較してみると次の事がわかります。

* `JSON.parse` をそのまま使っている
* `main()` はpromiseオブジェクトを返している
* エラーハンドリングは返ってきたpromiseオブジェクトに対して書いている

先ほども述べたように mainの `then` の部分がクドく感じます。

このような複数の非同期処理をまとめて扱う `Promise.all` と `Promise.race` という静的メソッドについて
学んでいきましょう。