Repository: kubermatic/machine-controller
Pull request #1402 (2022-08-11 14:18:12)

Anexia: extend disk configuration
**What this PR does / why we need it**:

This extends the configuration for disks in provider Anexia. The important bit is the now-configurable disk performance type, but the config was revamped a bit to allow configuring multiple disks in the future.

As a side-effect, this PR also fixes CI for Anexia by disabling OperatingSystemManager for now as it is not yet supported.

**Special notes for your reviewer**:

In the first commit I did some cleanup of the config structs. This inflates the PR diff a bit, but it's separate commits at least.

The API changes are currently backwards compatible, so no "action required" needed for now.

**Optional Release Note**:
<!--
Write your release note:
1. Enter your extended release note in the below block. If the PR requires additional action from users switching to the new release, include the string "action required".
2. If no release note is required, just write "NONE".
-->
```release-note
Allow configuring the disk performance type for provider Anexia
```


kubermatic-bot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubermatic/machine-controller/pull/1402#" title="Author self-approved">LittleFox94</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **ahmedwaleedmalik** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @ahmedwaleedmalik` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubermatic%2Fmachine-controller).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubermatic/machine-controller/blob/master/OWNERS)**
- **[pkg/cloudprovider/provider/OWNERS](https://github.com/kubermatic/machine-controller/blob/master/pkg/cloudprovider/provider/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["ahmedwaleedmalik"]} -->
kubermatic-bot: Hi @LittleFox94. Thanks for your PR.

I'm waiting for a [kubermatic](https://github.com/orgs/kubermatic/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://github.com/orgs/kubermatic/people) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=kubermatic%2Fmachine-controller).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>

LittleFox94: CodeClimate isn't too happy about the new `resolveConfig`, has too many return statements. I think it's ok though, as the reason for this function to exist is resolving the config values and return errors when any are missing - in the end much like `Validate`
ahmedwaleedmalik: /ok-to-test
kubermatic-bot: @LittleFox94: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-lint | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-lint/1558002334464741376) | true | `/test pull-machine-controller-lint`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-lint | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-lint/1558002334464741376) | true | `/test pull-machine-controller-lint`
pull-machine-controller-e2e-ubuntu-upgrade | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558002323811209216) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-lint | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-lint/1558002334464741376) | true | `/test pull-machine-controller-lint`
pull-machine-controller-e2e-ubuntu-upgrade | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558002323811209216) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack-project-auth | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558002331121881088) | true | `/test pull-machine-controller-e2e-openstack-project-auth`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-lint | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-lint/1558002334464741376) | true | `/test pull-machine-controller-lint`
pull-machine-controller-e2e-ubuntu-upgrade | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558002323811209216) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack-project-auth | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558002331121881088) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-openstack | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558002330295603200) | true | `/test pull-machine-controller-e2e-openstack`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-ubuntu-upgrade | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558002323811209216) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558002330295603200) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-openstack-project-auth | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558012803405582336) | true | `/test pull-machine-controller-e2e-openstack-project-auth`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack | d0d76e106dbd03697f165d9100a9b0fa9d24c18a | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558002330295603200) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-openstack-project-auth | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558012803405582336) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558012796019412992) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack-project-auth | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558012803405582336) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558012796019412992) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558012802566721536) | true | `/test pull-machine-controller-e2e-openstack`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
LittleFox94: /test pull-machine-controller-e2e-anexia
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack-project-auth | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558012803405582336) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558012796019412992) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558012802566721536) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-anexia | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-anexia/1558026014238445568) | true | `/test pull-machine-controller-e2e-anexia`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
LittleFox94: Hm, e2e test for Anexia fails due to not supporting OperatingSystemManager

what would be needed to support it? Should I add a commit to fixing CI by adding environment variable `OPERATING_SYSTEM_MANAGER=false` to prow config for anexia?
ahmedwaleedmalik: > what would be needed to support it? Should I add a commit to fixing CI by adding environment variable OPERATING_SYSTEM_MANAGER=false to prow config for anexia?

Yes please, Anexia is not supported with OSM at the moment.
ahmedwaleedmalik: /retest
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-ubuntu-upgrade | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558012796019412992) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-kubermatic-machine-controller-validate-prow-yaml | c2516ee8c5c011c531851b4006b67abb74526acf | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-kubermatic-machine-controller-validate-prow-yaml/1558033691899334656) | true | `/test pull-kubermatic-machine-controller-validate-prow-yaml`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
LittleFox94: /test pull-machine-controller-e2e-anexia
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-ubuntu-upgrade | dd9709672c5e6bc17771cdb744b5ac7847cfb820 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558012796019412992) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1558034421636927488) | true | `/test pull-machine-controller-e2e-kubevirt`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1558034421636927488) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558034415936868352) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1558034421636927488) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558034415936868352) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558034423327232000) | true | `/test pull-machine-controller-e2e-openstack-project-auth`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1558034421636927488) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558034415936868352) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558034423327232000) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558034422475788288) | true | `/test pull-machine-controller-e2e-openstack`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1558034421636927488) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558034415936868352) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558034423327232000) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558034422475788288) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-vsphere | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-vsphere/1558034424858152960) | true | `/test pull-machine-controller-e2e-vsphere`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
LittleFox94: all of those failures are timeouts again
LittleFox94: But since I only touched code for Anexia provider and that test went through, I'd say this can be merged anyway?
ahmedwaleedmalik: Just ignore those failures. I'll review this PR today hopefully.
LittleFox94: Alright, thank you :)
ahmedwaleedmalik: /retest
kubermatic-bot: LGTM label has been added.  <details>Git tree hash: a1fbc7897ee3daa9a2163eb31234db44efe34be0</details>
kubermatic-bot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubermatic/machine-controller/pull/1402#pullrequestreview-1072280813" title="Approved">ahmedwaleedmalik</a>*, *<a href="https://github.com/kubermatic/machine-controller/pull/1402#" title="Author self-approved">LittleFox94</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubermatic%2Fmachine-controller).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubermatic/machine-controller/blob/master/OWNERS)~~ [ahmedwaleedmalik]
- ~~[pkg/cloudprovider/provider/OWNERS](https://github.com/kubermatic/machine-controller/blob/master/pkg/cloudprovider/provider/OWNERS)~~ [ahmedwaleedmalik]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
ahmedwaleedmalik: 
/test pull-machine-controller-e2e-anexia


kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558034415936868352) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558034423327232000) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1558034422475788288) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-vsphere | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-vsphere/1558034424858152960) | true | `/test pull-machine-controller-e2e-vsphere`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559068190393241600) | true | `/test pull-machine-controller-e2e-kubevirt`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558034415936868352) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1558034423327232000) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559068190393241600) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559068190451961856) | true | `/test pull-machine-controller-e2e-openstack`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1558034415936868352) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559068190393241600) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559068190451961856) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559068190493904896) | true | `/test pull-machine-controller-e2e-openstack-project-auth`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559068190393241600) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559068190451961856) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559068190493904896) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559068190347104256) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-triage-bot: /retest
This bot automatically retries jobs that failed/flaked on approved PRs

Review the [full test history](https://prow.loodse.com/pr-history/?org=kubermatic&repo=machine-controller&pr=1402)

Silence the bot with an `/lgtm cancel` or `/hold` comment for consistent failures.
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559068190451961856) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559068190493904896) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559068190347104256) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559098129578463232) | true | `/test pull-machine-controller-e2e-kubevirt`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559068190451961856) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559068190347104256) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559098129578463232) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559098129674932224) | true | `/test pull-machine-controller-e2e-openstack-project-auth`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559068190451961856) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559098129578463232) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559098129674932224) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559098129519742976) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559098129578463232) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559098129674932224) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559098129519742976) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559098129628794880) | true | `/test pull-machine-controller-e2e-openstack`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-triage-bot: /retest
This bot automatically retries jobs that failed/flaked on approved PRs

Review the [full test history](https://prow.loodse.com/pr-history/?org=kubermatic&repo=machine-controller&pr=1402)

Silence the bot with an `/lgtm cancel` or `/hold` comment for consistent failures.
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559098129674932224) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559098129519742976) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559098129628794880) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559128292496248832) | true | `/test pull-machine-controller-e2e-kubevirt`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559098129674932224) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559098129628794880) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559128292496248832) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559128292441722880) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559098129674932224) | true | `/test pull-machine-controller-e2e-openstack-project-auth`
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559128292496248832) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559128292441722880) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559128292554969088) | true | `/test pull-machine-controller-e2e-openstack`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
kubermatic-bot: @LittleFox94: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-machine-controller-e2e-kubevirt | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-kubevirt/1559128292496248832) | true | `/test pull-machine-controller-e2e-kubevirt`
pull-machine-controller-e2e-ubuntu-upgrade | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-ubuntu-upgrade/1559128292441722880) | true | `/test pull-machine-controller-e2e-ubuntu-upgrade`
pull-machine-controller-e2e-openstack | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack/1559128292554969088) | true | `/test pull-machine-controller-e2e-openstack`
pull-machine-controller-e2e-openstack-project-auth | c50948efd125289bb8e85bd812536b255efbcb12 | [link](https://public-prow.loodse.com/view/gs/prow-dev-public-data/pr-logs/pull/kubermatic_machine-controller/1402/pull-machine-controller-e2e-openstack-project-auth/1559128292613689344) | true | `/test pull-machine-controller-e2e-openstack-project-auth`

[Full PR test history](https://public-prow.loodse.com/pr-history?org=kubermatic&repo=machine-controller&pr=1402)

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/.prow/provider-anexia.yaml b/.prow/provider-anexia.yaml
index 96a7ab09..807b1adf 100644
--- a/.prow/provider-anexia.yaml
+++ b/.prow/provider-anexia.yaml
@@ -32,6 +32,10 @@ presubmits:
             - "./hack/ci/run-e2e-tests.sh"
           args:
             - "TestAnexiaProvisioningE2E"
+          env:
+            # OperatingSystemManager does not yet support Anexia
+            - name: OPERATING_SYSTEM_MANAGER
+              value: "false"
           securityContext:
             privileged: true
           resources:
diff --git a/docs/cloud-provider.md b/docs/cloud-provider.md
index c18284f4..75a06564 100644
--- a/docs/cloud-provider.md
+++ b/docs/cloud-provider.md
@@ -152,7 +152,8 @@ tags:
 ### machine.spec.providerConfig.cloudProviderSpec
 
 ```yaml
-serviceAccount: "<< GOOGLE_SERVICE_ACCOUNT >>"
+# The service account needs to be base64-encoded.
+serviceAccount: "<< GOOGLE_SERVICE_ACCOUNT_BASE64 >>"
 # See https://cloud.google.com/compute/docs/regions-zones/
 zone: "europe-west3-a"
 # See https://cloud.google.com/compute/docs/machine-types
@@ -302,8 +303,8 @@ tags:
 
 ### machine.spec.providerConfig.cloudProviderSpec
 ```yaml
-# kubeconfig to access KubeVirt cluster
-kubeconfig: '<< KUBECONFIG >>'
+# base64-encoded kubeconfig to access KubeVirt cluster
+kubeconfig: '<< KUBECONFIG_BASE64 >>'
 # KubeVirt namespace
 namespace: kube-system
 # kubernetes storage class
diff --git a/examples/anexia-machinedeployment.yaml b/examples/anexia-machinedeployment.yaml
index 156cfd21..f5210a44 100644
--- a/examples/anexia-machinedeployment.yaml
+++ b/examples/anexia-machinedeployment.yaml
@@ -36,7 +36,15 @@ spec:
             locationID: "<< ANEXIA_LOCATION_ID >>"
             cpus: 2
             memory: 2048
-            diskSize: 60
+
+            # only a single disk is currently supported, but support for multiple disks is planned already
+            disks:
+            - size: 60
+              performanceType: ENT6
+
+            # You may have this old disk config attribute in your config - please migrate to the disks attribute.
+            # For now it is still recognized though.
+            #diskSize: 60
           # Flatcar is the only supported operating system
           operatingSystem: "flatcar"
           operatingSystemSpec:
diff --git a/examples/gce-machinedeployment.yaml b/examples/gce-machinedeployment.yaml
index 37c8eecb..c7ab56ff 100644
--- a/examples/gce-machinedeployment.yaml
+++ b/examples/gce-machinedeployment.yaml
@@ -6,8 +6,13 @@ metadata:
   name: machine-controller-gce
   namespace: kube-system
 type: Opaque
-stringData:
-  serviceAccount: "<< GOOGLE_SERVICE_ACCOUNT >>"
+data:
+  # The base64 encoding here is only to satisfy Kubernetes'
+  # Secret storage and to prevent multiline string replacement
+  # issues if we used stringData here (because the GCP SA is
+  # a multiline JSON string).
+  serviceAccount: "<< GOOGLE_SERVICE_ACCOUNT_BASE64 >>"
+
 ---
 apiVersion: "cluster.k8s.io/v1alpha1"
 kind: MachineDeployment
diff --git a/examples/kubevirt-machinedeployment.yaml b/examples/kubevirt-machinedeployment.yaml
index a40b9570..c7d959a2 100644
--- a/examples/kubevirt-machinedeployment.yaml
+++ b/examples/kubevirt-machinedeployment.yaml
@@ -28,9 +28,9 @@ spec:
           cloudProviderSpec:
             auth:
               kubeconfig:
-                # Can also be set via the env var 'KUBEVIRT_KUBECONFIG' on the machine-controller
-                # If specified directly, this value should be a base64 encoded kubeconfig in either yaml or json format.
-                value: "<< KUBECONFIG >>"
+                # Can also be set via the env var 'KUBEVIRT_KUBECONFIG' on the machine-controller.
+                # If instead specified directly, this value should be a base64 encoded kubeconfig.
+                value: "<< KUBECONFIG_BASE64 >>"
             virtualMachine:
               template:
                 cpus: "1"
diff --git a/pkg/cloudprovider/provider/anexia/provider.go b/pkg/cloudprovider/provider/anexia/provider.go
index 7d451e84..da8718cb 100644
--- a/pkg/cloudprovider/provider/anexia/provider.go
+++ b/pkg/cloudprovider/provider/anexia/provider.go
@@ -37,7 +37,6 @@ import (
 	cloudprovidererrors "github.com/kubermatic/machine-controller/pkg/cloudprovider/errors"
 	"github.com/kubermatic/machine-controller/pkg/cloudprovider/instance"
 	anxtypes "github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/anexia/types"
-	"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/anexia/utils"
 	cloudprovidertypes "github.com/kubermatic/machine-controller/pkg/cloudprovider/types"
 	"github.com/kubermatic/machine-controller/pkg/providerconfig"
 	providerconfigtypes "github.com/kubermatic/machine-controller/pkg/providerconfig/types"
@@ -54,10 +53,37 @@ const (
 	ProvisionedType = "Provisioned"
 )
 
+var (
+	// ErrConfigDiskSizeAndDisks is returned when the config has both DiskSize and Disks set, which is unsupported.
+	ErrConfigDiskSizeAndDisks = errors.New("both the deprecated DiskSize and new Disks attribute are set")
+
+	// ErrMultipleDisksNotYetImplemented is returned when multiple disks are configured.
+	ErrMultipleDisksNotYetImplemented = errors.New("multiple disks configured, but this feature is not yet implemented")
+)
+
 type provider struct {
 	configVarResolver *providerconfig.ConfigVarResolver
 }
 
+// resolvedDisk contains the resolved values from types.RawDisk.
+type resolvedDisk struct {
+	anxtypes.RawDisk
+
+	PerformanceType string
+}
+
+// resolvedConfig contains the resolved values from types.RawConfig.
+type resolvedConfig struct {
+	anxtypes.RawConfig
+
+	Token      string
+	VlanID     string
+	LocationID string
+	TemplateID string
+
+	Disks []resolvedDisk
+}
+
 func (p *provider) Create(ctx context.Context, machine *clusterv1alpha1.Machine, data *cloudprovidertypes.ProviderData, userdata string) (instance instance.Instance, retErr error) {
 	status := getProviderStatus(machine)
 	klog.V(3).Infof(fmt.Sprintf("'%s' has status %#v", machine.Name, status))
@@ -70,10 +96,10 @@ func (p *provider) Create(ctx context.Context, machine *clusterv1alpha1.Machine,
 		return nil, fmt.Errorf("unable to get provider config: %w", err)
 	}
 
-	ctx = utils.CreateReconcileContext(ctx, utils.ReconcileContext{
+	ctx = createReconcileContext(ctx, reconcileContext{
 		Status:       &status,
 		UserData:     userdata,
-		Config:       config,
+		Config:       *config,
 		ProviderData: data,
 		Machine:      machine,
 	})
@@ -108,7 +134,7 @@ func (p *provider) Create(ctx context.Context, machine *clusterv1alpha1.Machine,
 }
 
 func waitForVM(ctx context.Context, client anxclient.Client) error {
-	reconcileContext := utils.GetReconcileContext(ctx)
+	reconcileContext := getReconcileContext(ctx)
 	api := vsphere.NewAPI(client)
 	var identifier string
 	err := wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
@@ -135,7 +161,7 @@ func waitForVM(ctx context.Context, client anxclient.Client) error {
 }
 
 func provisionVM(ctx context.Context, client anxclient.Client) error {
-	reconcileContext := utils.GetReconcileContext(ctx)
+	reconcileContext := getReconcileContext(ctx)
 	vmAPI := vsphere.NewAPI(client)
 
 	ctx, cancel := context.WithTimeout(ctx, anxtypes.CreateRequestTimeout)
@@ -164,12 +190,15 @@ func provisionVM(ctx context.Context, client anxclient.Client) error {
 			reconcileContext.Machine.Name,
 			config.CPUs,
 			config.Memory,
-			config.DiskSize,
+			config.Disks[0].Size,
 			networkInterfaces,
 		)
 
+		vm.DiskType = config.Disks[0].PerformanceType
+
 		vm.Script = base64.StdEncoding.EncodeToString([]byte(reconcileContext.UserData))
 
+		// We generate a fresh SSH key but will never actually use it - we just want a valid public key to disable password authentication for our fresh VM.
 		sshKey, err := ssh.NewKey()
 		if err != nil {
 			return newError(common.CreateMachineError, "failed to generate ssh key: %v", err)
@@ -220,7 +249,7 @@ func provisionVM(ctx context.Context, client anxclient.Client) error {
 }
 
 func getIPAddress(ctx context.Context, client anxclient.Client) (string, error) {
-	reconcileContext := utils.GetReconcileContext(ctx)
+	reconcileContext := getReconcileContext(ctx)
 	status := reconcileContext.Status
 
 	// only use IP if it is still unbound
@@ -228,6 +257,7 @@ func getIPAddress(ctx context.Context, client anxclient.Client) (string, error)
 		klog.Info("reusing already provisioned ip", "IP", status.ReservedIP)
 		return status.ReservedIP, nil
 	}
+
 	klog.Info(fmt.Sprintf("Creating a new IP for machine %q", reconcileContext.Machine.Name))
 	addrAPI := anxaddr.NewAPI(client)
 	config := reconcileContext.Config
@@ -251,7 +281,7 @@ func getIPAddress(ctx context.Context, client anxclient.Client) (string, error)
 }
 
 func isAlreadyProvisioning(ctx context.Context) bool {
-	status := utils.GetReconcileContext(ctx).Status
+	status := getReconcileContext(ctx).Status
 	condition := meta.FindStatusCondition(status.Conditions, ProvisionedType)
 	lastChange := condition.LastTransitionTime.Time
 	const reasonInProvisioning = "InProvisioning"
@@ -278,50 +308,85 @@ func ensureConditions(status *anxtypes.ProviderStatus) {
 	}
 }
 
-func (p *provider) getConfig(provSpec clusterv1alpha1.ProviderSpec) (*anxtypes.Config, *providerconfigtypes.Config, error) {
-	if provSpec.Value == nil {
-		return nil, nil, fmt.Errorf("machine.spec.providerSpec.value is nil")
+func (p *provider) resolveConfig(config anxtypes.RawConfig) (*resolvedConfig, error) {
+	var err error
+	ret := resolvedConfig{
+		RawConfig: config,
 	}
-	pconfig, err := providerconfigtypes.GetConfig(provSpec)
+
+	ret.Token, err = p.configVarResolver.GetConfigVarStringValueOrEnv(config.Token, anxtypes.AnxTokenEnv)
 	if err != nil {
-		return nil, nil, err
+		return nil, fmt.Errorf("failed to get 'token': %w", err)
 	}
 
-	if pconfig.OperatingSystemSpec.Raw == nil {
-		return nil, nil, errors.New("operatingSystemSpec in the MachineDeployment cannot be empty")
+	ret.LocationID, err = p.configVarResolver.GetConfigVarStringValue(config.LocationID)
+	if err != nil {
+		return nil, fmt.Errorf("failed to get 'locationID': %w", err)
 	}
 
-	rawConfig, err := anxtypes.GetConfig(*pconfig)
+	ret.TemplateID, err = p.configVarResolver.GetConfigVarStringValue(config.TemplateID)
 	if err != nil {
-		return nil, nil, err
+		return nil, fmt.Errorf("failed to get 'templateID': %w", err)
 	}
 
-	c := anxtypes.Config{}
-	c.Token, err = p.configVarResolver.GetConfigVarStringValueOrEnv(rawConfig.Token, anxtypes.AnxTokenEnv)
+	ret.VlanID, err = p.configVarResolver.GetConfigVarStringValue(config.VlanID)
 	if err != nil {
-		return nil, nil, fmt.Errorf("failed to get 'token': %w", err)
+		return nil, fmt.Errorf("failed to get 'vlanID': %w", err)
+	}
+
+	if config.DiskSize != 0 {
+		if len(config.Disks) != 0 {
+			return nil, ErrConfigDiskSizeAndDisks
+		}
+
+		klog.Warningf("Configuration uses the deprecated DiskSize attribute, please migrate to the Disks array instead.")
+
+		config.Disks = []anxtypes.RawDisk{
+			{
+				Size: config.DiskSize,
+			},
+		}
+		config.DiskSize = 0
 	}
 
-	c.CPUs = rawConfig.CPUs
-	c.Memory = rawConfig.Memory
-	c.DiskSize = rawConfig.DiskSize
+	ret.Disks = make([]resolvedDisk, len(config.Disks))
+
+	for idx, disk := range config.Disks {
+		ret.Disks[idx].RawDisk = disk
 
-	c.LocationID, err = p.configVarResolver.GetConfigVarStringValue(rawConfig.LocationID)
+		ret.Disks[idx].PerformanceType, err = p.configVarResolver.GetConfigVarStringValue(disk.PerformanceType)
+		if err != nil {
+			return nil, fmt.Errorf("failed to get 'performanceType' of disk %v: %w", idx, err)
+		}
+	}
+
+	return &ret, nil
+}
+
+func (p *provider) getConfig(provSpec clusterv1alpha1.ProviderSpec) (*resolvedConfig, *providerconfigtypes.Config, error) {
+	if provSpec.Value == nil {
+		return nil, nil, fmt.Errorf("machine.spec.providerSpec.value is nil")
+	}
+	pconfig, err := providerconfigtypes.GetConfig(provSpec)
 	if err != nil {
-		return nil, nil, fmt.Errorf("failed to get 'locationID': %w", err)
+		return nil, nil, err
+	}
+
+	if pconfig.OperatingSystemSpec.Raw == nil {
+		return nil, nil, errors.New("operatingSystemSpec in the MachineDeployment cannot be empty")
 	}
 
-	c.TemplateID, err = p.configVarResolver.GetConfigVarStringValue(rawConfig.TemplateID)
+	rawConfig, err := anxtypes.GetConfig(*pconfig)
 	if err != nil {
-		return nil, nil, fmt.Errorf("failed to get 'templateID': %w", err)
+		return nil, nil, fmt.Errorf("error parsing provider config: %w", err)
 	}
 
-	c.VlanID, err = p.configVarResolver.GetConfigVarStringValue(rawConfig.VlanID)
+	resolvedConfig, err := p.resolveConfig(*rawConfig)
 	if err != nil {
-		return nil, nil, fmt.Errorf("failed to get 'vlanID': %w", err)
+		return nil, nil, fmt.Errorf("error resolving config: %w", err)
 	}
 
-	return &c, pconfig, nil
+	return resolvedConfig, pconfig, nil
 }
 
 // New returns an Anexia provider.
@@ -349,8 +414,18 @@ func (p *provider) Validate(_ context.Context, machinespec clusterv1alpha1.Machi
 		return errors.New("cpu count is missing")
 	}
 
-	if config.DiskSize == 0 {
-		return errors.New("disk size is missing")
+	if len(config.Disks) == 0 {
+		return errors.New("no disks configured")
+	}
+
+	if len(config.Disks) > 1 {
+		return ErrMultipleDisksNotYetImplemented
+	}
+
+	for _, disk := range config.Disks {
+		if disk.Size == 0 {
+			return errors.New("disk size is missing")
+		}
 	}
 
 	if config.Memory == 0 {
diff --git a/pkg/cloudprovider/provider/anexia/utils/utils.go b/pkg/cloudprovider/provider/anexia/reconcile_context.go
similarity index 70%
rename from pkg/cloudprovider/provider/anexia/utils/utils.go
rename to pkg/cloudprovider/provider/anexia/reconcile_context.go
index 51a2a549..dea3577c 100644
--- a/pkg/cloudprovider/provider/anexia/utils/utils.go
+++ b/pkg/cloudprovider/provider/anexia/reconcile_context.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package utils
+package anexia
 
 import (
 	"context"
@@ -26,24 +26,25 @@ import (
 
 type contextKey byte
 
-const MachineReconcileContextKey contextKey = 0
+const machineReconcileContextKey contextKey = 0
 
-type ReconcileContext struct {
+type reconcileContext struct {
 	Machine      *v1alpha1.Machine
 	Status       *anxtypes.ProviderStatus
 	UserData     string
-	Config       *anxtypes.Config
+	Config       resolvedConfig
 	ProviderData *cloudprovidertypes.ProviderData
 }
 
-func CreateReconcileContext(ctx context.Context, cc ReconcileContext) context.Context {
-	return context.WithValue(ctx, MachineReconcileContextKey, cc)
+func createReconcileContext(ctx context.Context, cc reconcileContext) context.Context {
+	return context.WithValue(ctx, machineReconcileContextKey, cc)
 }
 
-func GetReconcileContext(ctx context.Context) ReconcileContext {
-	rawContext := ctx.Value(MachineReconcileContextKey)
-	if recContext, ok := rawContext.(ReconcileContext); ok {
+func getReconcileContext(ctx context.Context) reconcileContext {
+	rawContext := ctx.Value(machineReconcileContextKey)
+	if recContext, ok := rawContext.(reconcileContext); ok {
 		return recContext
 	}
-	return ReconcileContext{}
+
+	return reconcileContext{}
 }
diff --git a/pkg/cloudprovider/provider/anexia/types/types.go b/pkg/cloudprovider/provider/anexia/types/types.go
index dd0faca8..25547e9d 100644
--- a/pkg/cloudprovider/provider/anexia/types/types.go
+++ b/pkg/cloudprovider/provider/anexia/types/types.go
@@ -46,14 +46,26 @@ var StatusUpdateFailed = cloudprovidererrors.TerminalError{
 	Message: "Unable to update the machine status",
 }
 
+// RawDisk specifies a single disk, with some values maybe being fetched from secrets.
+type RawDisk struct {
+	Size            int                                 `json:"size"`
+	PerformanceType providerconfigtypes.ConfigVarString `json:"performanceType"`
+}
+
+// RawConfig contains all the configuration values for VMs to create, with some values maybe being fetched from secrets.
 type RawConfig struct {
 	Token      providerconfigtypes.ConfigVarString `json:"token,omitempty"`
 	VlanID     providerconfigtypes.ConfigVarString `json:"vlanID"`
 	LocationID providerconfigtypes.ConfigVarString `json:"locationID"`
 	TemplateID providerconfigtypes.ConfigVarString `json:"templateID"`
-	CPUs       int                                 `json:"cpus"`
-	Memory     int                                 `json:"memory"`
-	DiskSize   int                                 `json:"diskSize"`
+
+	CPUs   int `json:"cpus"`
+	Memory int `json:"memory"`
+
+	// Deprecated, use Disks instead.
+	DiskSize int `json:"diskSize"`
+
+	Disks []RawDisk `json:"disks"`
 }
 
 type ProviderStatus struct {
@@ -65,16 +77,6 @@ type ProviderStatus struct {
 	Conditions       []v1.Condition `json:"conditions,omitempty"`
 }
 
-type Config struct {
-	Token      string
-	VlanID     string
-	LocationID string
-	TemplateID string
-	CPUs       int
-	Memory     int
-	DiskSize   int
-}
-
 func GetConfig(pconfig providerconfigtypes.Config) (*RawConfig, error) {
 	rawConfig := &RawConfig{}
 
diff --git a/pkg/cloudprovider/provider/gce/config.go b/pkg/cloudprovider/provider/gce/config.go
index cacea48e..934adca0 100644
--- a/pkg/cloudprovider/provider/gce/config.go
+++ b/pkg/cloudprovider/provider/gce/config.go
@@ -226,17 +226,23 @@ func newConfig(resolver *providerconfig.ConfigVarResolver, spec v1alpha1.Provide
 // postprocessServiceAccount processes the service account and creates a JWT configuration
 // out of it.
 func (cfg *config) postprocessServiceAccount() error {
-	sa, err := base64.StdEncoding.DecodeString(cfg.serviceAccount)
-	if err != nil {
-		return fmt.Errorf("failed to decode base64 service account: %w", err)
+	sa := cfg.serviceAccount
+
+	// safely decode the service account, in case we did not read the value
+	// from a "known-safe" location (like the MachineDeployment), but from
+	// an environment variable.
+	decoded, err := base64.StdEncoding.DecodeString(cfg.serviceAccount)
+	if err == nil {
+		sa = string(decoded)
 	}
+
 	sam := map[string]string{}
-	err = json.Unmarshal(sa, &sam)
+	err = json.Unmarshal([]byte(sa), &sam)
 	if err != nil {
 		return fmt.Errorf("failed unmarshalling service account: %w", err)
 	}
 	cfg.projectID = sam["project_id"]
-	cfg.jwtConfig, err = google.JWTConfigFromJSON(sa, compute.ComputeScope)
+	cfg.jwtConfig, err = google.JWTConfigFromJSON([]byte(sa), compute.ComputeScope)
 	if err != nil {
 		return fmt.Errorf("failed preparing JWT: %w", err)
 	}
diff --git a/pkg/cloudprovider/provider/gce/types/types.go b/pkg/cloudprovider/provider/gce/types/types.go
index c1b059d8..0ac0f333 100644
--- a/pkg/cloudprovider/provider/gce/types/types.go
+++ b/pkg/cloudprovider/provider/gce/types/types.go
@@ -30,6 +30,7 @@ import (
 // CloudProviderSpec contains the specification of the cloud provider taken
 // from the provider configuration.
 type CloudProviderSpec struct {
+	// ServiceAccount must be base64-encoded.
 	ServiceAccount               providerconfigtypes.ConfigVarString  `json:"serviceAccount,omitempty"`
 	Zone                         providerconfigtypes.ConfigVarString  `json:"zone"`
 	MachineType                  providerconfigtypes.ConfigVarString  `json:"machineType"`


Test patch:
diff --git a/pkg/cloudprovider/provider/anexia/provider_test.go b/pkg/cloudprovider/provider/anexia/provider_test.go
index 8592f576..b26d29f3 100644
--- a/pkg/cloudprovider/provider/anexia/provider_test.go
+++ b/pkg/cloudprovider/provider/anexia/provider_test.go
@@ -33,7 +33,6 @@ import (
 	"github.com/kubermatic/machine-controller/pkg/apis/cluster/v1alpha1"
 	clusterv1alpha1 "github.com/kubermatic/machine-controller/pkg/apis/cluster/v1alpha1"
 	anxtypes "github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/anexia/types"
-	"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/anexia/utils"
 	cloudprovidertypes "github.com/kubermatic/machine-controller/pkg/cloudprovider/types"
 
 	"k8s.io/apimachinery/pkg/api/meta"
@@ -58,13 +57,13 @@ func TestAnexiaProvider(t *testing.T) {
 		testhelper.Mux.HandleFunc("/api/vsphere/v1/search/by_name.json", createSearchHandler(t, waitUntilVMIsFound))
 
 		providerStatus := anxtypes.ProviderStatus{}
-		ctx := utils.CreateReconcileContext(context.Background(), utils.ReconcileContext{
+		ctx := createReconcileContext(context.Background(), reconcileContext{
 			Machine: &v1alpha1.Machine{
 				ObjectMeta: metav1.ObjectMeta{Name: "TestMachine"},
 			},
 			Status:   &providerStatus,
 			UserData: "",
-			Config:   &anxtypes.Config{},
+			Config:   resolvedConfig{},
 
 			ProviderData: &cloudprovidertypes.ProviderData{
 				Update: func(m *clusterv1alpha1.Machine, mod ...cloudprovidertypes.MachineModifier) error {
@@ -150,19 +149,27 @@ func TestAnexiaProvider(t *testing.T) {
 		})
 
 		providerStatus := anxtypes.ProviderStatus{}
-		ctx := utils.CreateReconcileContext(context.Background(), utils.ReconcileContext{
+		ctx := createReconcileContext(context.Background(), reconcileContext{
 			Machine: &v1alpha1.Machine{
 				ObjectMeta: metav1.ObjectMeta{Name: "TestMachine"},
 			},
 			Status:   &providerStatus,
 			UserData: "",
-			Config: &anxtypes.Config{
+			Config: resolvedConfig{
 				VlanID:     "VLAN-ID",
 				LocationID: "LOCATION-ID",
 				TemplateID: "TEMPLATE-ID",
-				CPUs:       5,
-				Memory:     5,
-				DiskSize:   5,
+				Disks: []resolvedDisk{
+					{
+						RawDisk: anxtypes.RawDisk{
+							Size: 5,
+						},
+					},
+				},
+				RawConfig: anxtypes.RawConfig{
+					CPUs:   5,
+					Memory: 5,
+				},
 			},
 			ProviderData: &cloudprovidertypes.ProviderData{
 				Update: func(m *clusterv1alpha1.Machine, mods ...cloudprovidertypes.MachineModifier) error {
@@ -186,10 +193,10 @@ func TestAnexiaProvider(t *testing.T) {
 				},
 			},
 		}
-		ctx := utils.CreateReconcileContext(context.Background(), utils.ReconcileContext{
+		ctx := createReconcileContext(context.Background(), reconcileContext{
 			Status:       &providerStatus,
 			UserData:     "",
-			Config:       nil,
+			Config:       resolvedConfig{},
 			ProviderData: nil,
 		})
 
@@ -214,7 +221,7 @@ func TestAnexiaProvider(t *testing.T) {
 			ReservedIP: "",
 			IPState:    "",
 		}
-		ctx := utils.CreateReconcileContext(context.Background(), utils.ReconcileContext{Status: providerStatus})
+		ctx := createReconcileContext(context.Background(), reconcileContext{Status: providerStatus})
 
 		t.Run("with unbound reserved IP", func(t *testing.T) {
 			expectedIP := "8.8.8.8"
@@ -230,42 +237,79 @@ func TestAnexiaProvider(t *testing.T) {
 func TestValidate(t *testing.T) {
 	t.Parallel()
 
+	// this generates a full config and allows hooking into it to e.g. remove a value
+	hookableConfig := func(hook func(*anxtypes.RawConfig)) anxtypes.RawConfig {
+		config := anxtypes.RawConfig{
+			CPUs: 1,
+
+			Memory: 2,
+
+			Disks: []anxtypes.RawDisk{
+				{Size: 5, PerformanceType: newConfigVarString("ENT6")},
+			},
+
+			Token:      newConfigVarString("test-token"),
+			VlanID:     newConfigVarString("test-vlan"),
+			LocationID: newConfigVarString("test-location"),
+			TemplateID: newConfigVarString("test-template"),
+		}
+
+		if hook != nil {
+			hook(&config)
+		}
+
+		return config
+	}
+
 	var configCases []ConfigTestCase
 	configCases = append(configCases,
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{},
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.Token.Value = "" }),
 			Error:  errors.New("token is missing"),
 		},
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{Token: newConfigVarString("TEST-TOKEN")},
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.CPUs = 0 }),
 			Error:  errors.New("cpu count is missing"),
 		},
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{Token: newConfigVarString("TEST-TOKEN"), CPUs: 1},
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.Disks = []anxtypes.RawDisk{} }),
+			Error:  errors.New("no disks configured"),
+		},
+		ConfigTestCase{
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.DiskSize = 10 }),
+			Error:  ErrConfigDiskSizeAndDisks,
+		},
+		ConfigTestCase{
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.Disks = append(c.Disks, anxtypes.RawDisk{Size: 10}) }),
+			Error:  ErrMultipleDisksNotYetImplemented,
+		},
+		ConfigTestCase{
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.Disks[0].Size = 0 }),
 			Error:  errors.New("disk size is missing"),
 		},
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{Token: newConfigVarString("TEST-TOKEN"), CPUs: 1, DiskSize: 5},
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.Memory = 0 }),
 			Error:  errors.New("memory size is missing"),
 		},
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{Token: newConfigVarString("TEST-TOKEN"), CPUs: 1, DiskSize: 5, Memory: 5},
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.LocationID.Value = "" }),
 			Error:  errors.New("location id is missing"),
 		},
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{Token: newConfigVarString("TEST-TOKEN"), CPUs: 1, DiskSize: 5, Memory: 5,
-				LocationID: newConfigVarString("TLID")},
-			Error: errors.New("template id is missing"),
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.TemplateID.Value = "" }),
+			Error:  errors.New("template id is missing"),
 		},
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{Token: newConfigVarString("TEST-TOKEN"), CPUs: 1, DiskSize: 5, Memory: 5,
-				LocationID: newConfigVarString("LID"), TemplateID: newConfigVarString("TID")},
-			Error: errors.New("vlan id is missing"),
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.VlanID.Value = "" }),
+			Error:  errors.New("vlan id is missing"),
 		},
 		ConfigTestCase{
-			Config: anxtypes.RawConfig{Token: newConfigVarString("TEST-TOKEN"), CPUs: 1, DiskSize: 5, Memory: 5,
-				LocationID: newConfigVarString("LID"), TemplateID: newConfigVarString("TID"), VlanID: newConfigVarString("VLAN")},
-			Error: nil,
+			Config: hookableConfig(func(c *anxtypes.RawConfig) { c.DiskSize = 10; c.Disks = []anxtypes.RawDisk{} }),
+			Error:  nil,
+		},
+		ConfigTestCase{
+			Config: hookableConfig(nil),
+			Error:  nil,
 		},
 	)
 
@@ -273,7 +317,9 @@ func TestValidate(t *testing.T) {
 	for _, testCase := range getSpecsForValidationTest(t, configCases) {
 		err := provider.Validate(context.Background(), testCase.Spec)
 		if testCase.ExpectedError != nil {
-			testhelper.AssertEquals(t, testCase.ExpectedError.Error(), err.Error())
+			if !errors.Is(err, testCase.ExpectedError) {
+				testhelper.AssertEquals(t, testCase.ExpectedError.Error(), err.Error())
+			}
 		} else {
 			testhelper.AssertEquals(t, testCase.ExpectedError, err)
 		}
diff --git a/test/e2e/provisioning/all_e2e_test.go b/test/e2e/provisioning/all_e2e_test.go
index c19c979c..eb13c126 100644
--- a/test/e2e/provisioning/all_e2e_test.go
+++ b/test/e2e/provisioning/all_e2e_test.go
@@ -20,6 +20,7 @@ package provisioning
 
 import (
 	"context"
+	"encoding/base64"
 	"flag"
 	"fmt"
 	"os"
@@ -293,12 +294,23 @@ func TestKubevirtProvisioningE2E(t *testing.T) {
 	selector := OsSelector("ubuntu", "centos", "flatcar", "rockylinux")
 
 	params := []string{
-		fmt.Sprintf("<< KUBECONFIG >>=%s", kubevirtKubeconfig),
+		fmt.Sprintf("<< KUBECONFIG_BASE64 >>=%s", safeBase64Encoding(kubevirtKubeconfig)),
 	}
 
 	runScenarios(t, selector, params, kubevirtManifest, fmt.Sprintf("kubevirt-%s", *testRunIdentifier))
 }
 
+// safeBase64Encoding takes a value and encodes it with base64
+// if it is not already encoded.
+func safeBase64Encoding(value string) string {
+	// If there was no error, the original value was already encoded.
+	if _, err := base64.StdEncoding.DecodeString(value); err == nil {
+		return value
+	}
+
+	return base64.StdEncoding.EncodeToString([]byte(value))
+}
+
 func TestOpenstackProvisioningE2E(t *testing.T) {
 	t.Parallel()
 
@@ -708,8 +720,9 @@ func TestGCEProvisioningE2E(t *testing.T) {
 	// Act. GCE does not support CentOS.
 	selector := OsSelector("ubuntu")
 	params := []string{
-		fmt.Sprintf("<< GOOGLE_SERVICE_ACCOUNT >>=%s", googleServiceAccount),
+		fmt.Sprintf("<< GOOGLE_SERVICE_ACCOUNT_BASE64 >>=%s", safeBase64Encoding(googleServiceAccount)),
 	}
+
 	runScenarios(t, selector, params, GCEManifest, fmt.Sprintf("gce-%s", *testRunIdentifier))
 }
 
diff --git a/test/e2e/provisioning/testdata/machinedeployment-gce.yaml b/test/e2e/provisioning/testdata/machinedeployment-gce.yaml
index a2d9eb4d..5fb0a6c8 100644
--- a/test/e2e/provisioning/testdata/machinedeployment-gce.yaml
+++ b/test/e2e/provisioning/testdata/machinedeployment-gce.yaml
@@ -24,8 +24,9 @@ spec:
             - "<< YOUR_PUBLIC_KEY >>"
           cloudProvider: "gce"
           cloudProviderSpec:
-            # If empty, can be set via GOOGLE_SERVICE_ACCOUNT env var
-            serviceAccount: "<< GOOGLE_SERVICE_ACCOUNT >>"
+            # If empty, can be set via GOOGLE_SERVICE_ACCOUNT env var. The environment variable
+            # should be plaintext. The value in the cloudProviderSpec however must be base64-encoded.
+            serviceAccount: "<< GOOGLE_SERVICE_ACCOUNT_BASE64 >>"
             # See https://cloud.google.com/compute/docs/regions-zones/
             zone: "europe-west3-a"
             # See https://cloud.google.com/compute/docs/machine-types
diff --git a/test/e2e/provisioning/testdata/machinedeployment-kubevirt.yaml b/test/e2e/provisioning/testdata/machinedeployment-kubevirt.yaml
index 29a42da2..5c66b562 100644
--- a/test/e2e/provisioning/testdata/machinedeployment-kubevirt.yaml
+++ b/test/e2e/provisioning/testdata/machinedeployment-kubevirt.yaml
@@ -28,7 +28,7 @@ spec:
           cloudProviderSpec:
             auth:
               kubeconfig:
-                value: '<< KUBECONFIG >>'
+                value: '<< KUBECONFIG_BASE64 >>'
             virtualMachine:
               template:
                 cpus: "1"