Skip to content

Commit

Permalink
Merge branch 'main' into tests/add-more-domain-account-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua Reed committed Jun 10, 2022
2 parents b4e72b0 + f467654 commit de6f708
Show file tree
Hide file tree
Showing 40 changed files with 3,327 additions and 226 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ cloud-config
*.swp
*.swo
*~
examples/*
hack/tools/share/*
9 changes: 2 additions & 7 deletions OWNERS
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
approvers:
- pmotyka
- maxdrib
- vignesh-goutham
- jweite-amazon
- mrog
- rejoshed
- wongni
- rohityadavcloud
- davidjumani
345 changes: 128 additions & 217 deletions README.md

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions common.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2020 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include $(ROOT_DIR_RELATIVE)/versions.mk

# Ensure Make is run with bash shell as some syntax below is bash-specific
SHELL:=bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
MAKEFLAGS += --no-builtin-rules

TOOLS_DIR := $(ROOT_DIR_RELATIVE)/hack/tools
TOOLS_DIR_DEPS := $(TOOLS_DIR)/go.sum $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/Makefile
TOOLS_BIN_DIR := $(TOOLS_DIR)/bin
UID := $(shell id -u)
GID := $(shell id -g)

rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))

# Hosts running SELinux need :z added to volume mounts
SELINUX_ENABLED := $(shell cat /sys/fs/selinux/enforce 2> /dev/null || echo 0)

ifeq ($(SELINUX_ENABLED),1)
DOCKER_VOL_OPTS?=:z
endif

.DEFAULT_GOAL:=help

# Use GOPROXY environment variable if set
GOPROXY := $(shell go env GOPROXY)
ifeq ($(GOPROXY),)
GOPROXY := https://proxy.golang.org
endif
export GOPROXY

$(TOOLS_BIN_DIR)/%: $(TOOLS_DIR_DEPS)
make -C $(TOOLS_DIR) $(subst $(TOOLS_DIR)/,,$@)

## --------------------------------------
## Help
## --------------------------------------

help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
2 changes: 2 additions & 0 deletions docs/book/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# book file
book
40 changes: 40 additions & 0 deletions docs/book/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2020 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ROOT_DIR_RELATIVE := ../..
include $(ROOT_DIR_RELATIVE)/common.mk

# Directories.
MDBOOK := $(TOOLS_BIN_DIR)/mdbook
MDBOOK_EMBED := $(TOOLS_BIN_DIR)/mdbook-embed
MDBOOK_RELEASELINK := $(TOOLS_BIN_DIR)/mdbook-releaselink
MDBOOK_TABULATE := $(TOOLS_BIN_DIR)/mdbook-tabulate
BOOK_SRCS := $(call rwildcard,.,*.*)

OS := $(shell go env GOOS)
ARCH := $(shell go env GOARCH)
PATH := $(abspath $(TOOLS_BIN_DIR)):$(PATH)
export PATH

.PHONY: build
build: $(BOOK_SRCS) $(MDBOOK) $(MDBOOK_EMBED) $(MDBOOK_RELEASELINK) $(MDBOOK_TABULATE) ## Build the book
$(MDBOOK) build

.PHONY: serve
serve: $(MDBOOK) $(MDBOOK_EMBED) $(MDBOOK_RELEASELINK) $(MDBOOK_TABULATE) ## Run a local webserver with the compiled book
$(MDBOOK) serve

.PHONY: clean
clean:
rm -rf book
20 changes: 20 additions & 0 deletions docs/book/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[book]
authors = ["The Cluster API Provider CloudStack Maintainers"]
language = "en"
multilingual = false
src = "src"
title = "The Cluster API Provider CloudStack Book"

[output.html]
curly-quotes = true
git-repository-url = "https://sigs.k8s.io/cluster-api-provider-cloudstack"
no-section-label = true

[preprocessor.tabulate]
command = "mdbook-tabulate"

[preprocessor.embed]
command = "mdbook-embed"

[preprocessor.releaselink]
command = "mdbook-releaselink"
15 changes: 15 additions & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Summary

- [Introduction](introduction.md)
- [Getting Started](getting-started.md)
- [Configuration](clustercloudstack/configuration.md)
- [Topics](topics/index.md)
- [Move From Bootstrap](topics/mover.md)
- [TroubleShooting](topics/troubleshooting.md)
- [Custom Images](topics/custom-images.md)
- [SSH Access To Nodes](topics/ssh-access.md)
- [Unstacked etcd](topics/unstacked-etcd.md)
- [Developer Guide](development/index.md)
- [Development With Tilt](development/tilt.md)
- [Building CAPC](development/building.md)
- [E2E Tests](development/e2e.md)
226 changes: 226 additions & 0 deletions docs/book/src/clustercloudstack/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# Required configuration

The cluster configuration file can be generated by using [`clusterctl generate cluster`][clusterctl-generate-cluster] command.
This command actually uses [the template file][template-file] and replace the values surrounded by `${}` with environment variables. You have to set all required environment variables in advance. The following sections explain some more details about what should be configured.

Note: You can use [the template file][template-file] by manually replacing values.

```bash
clusterctl generate cluster capi-quickstart \
--kubernetes-version v1.21.3 \
--control-plane-machine-count=1 \
--worker-machine-count=1 \
> capi-quickstart.yaml
```

In order to fetch the configuration parameters via the terminal, please install [cmk][cmk-download] and [jq][jq-download]

## Cluster Level Configurations

These configurations are passed while defining the `CloudStackCluster` and apply to the entire cluster.

### Zone

The Zone must be exposed as an environment variable `CLOUDSTACK_ZONE_NAME` and is a mandatory parameter.
As of now, only advanced zones without security groups is supported.

The list of zones can be fetched using the cmk cli as follows :
```
cmk list zones listall=true | jq '.zone[] | {name, id}'
```

### Network

The network must be exposed as an environment variable `CLOUDSTACK_NETWORK_NAME` and is a mandatory parameter.
As of now, only isolated and shared networks are supported.
If the specified network does not exist, a new isolated network will be created.

The list of networks for the specific zone can be fetched using the cmk cli as follows :
```
cmk list networks listall=true zoneid=<zoneid> | jq '.network[] | {name, id, type}'
```


### Endpoint

The endpoint of the workload cluster. It can either be an IP or an FQDN which is resolvable from the management cluster

If on an isolated network, and the endpoint is an IP, it must be an IP in the Public IP range.
The necessary Firewall and LoadBalancing rules will be automatically created on Apache CloudStack for the specified IP.

If on a shared network, and the endpoint is an IP, it must belong to the shared network range and not allocated to any other resource on CloudStack.

The Endpoint is exposed in two parts, as the `CLUSTER_ENDPOINT_IP` and `CLUSTER_ENDPOINT_PORT` environment variables.

The list of Public IPs for the specific zone can be fetched using the cmk cli as follows :
```
cmk list publicipaddresses listall=true zoneid=<zone-id> forvirtualnetwork=true allocatedonly=false | jq '.publicipaddress[] | select(.state == "Free" or .state == "Reserved") | .ipaddress'
```

## Machine Level Configurations

These configurations are passed while defining the `CloudStackMachine`. They can differ based on the MachineSet mapped to it.

### Service Offerings

The service offerings for the Control Plane Nodes are specified by the `CLOUDSTACK_CONTROL_PLANE_MACHINE_OFFERING` environment variable.
It must have a minimum of 2GB RAM and 2 vCPU

The service offerings for the Worker Nodes are specified by the `CLOUDSTACK_WORKER_MACHINE_OFFERING` environment variable.


The list of Service offerings for the specific zone can be fetched using the cmk cli as follows :
```
cmk list serviceofferings listall=true zoneid=<zone-id> cpunumber=2 memory=2048 | jq '.serviceoffering[] | {name, id}'
```

### Virtual Machine Template

We currently depend on an up-to-date version of cloud-init otherwise the operating system choice is yours.
The kubeadm bootstrap provider we're using also depends on some pre-installed software like a container runtime, kubelet, kubeadm, etc.
For an examples how to build such an image take a look at [CloudStack CAPI Images][cloudstack-capi-images].

Prebuilt images can be found [here][prebuilt-images]

The image can be referenced by exposing it as an environment variable `CLOUDSTACK_TEMPLATE_NAME`.

The list of Templates for the specific zone can be fetched using the cmk cli as follows :
```
cmk list templates zoneid=<zone-id> templatefilter=executable | jq '.template[] | {name, id}'
```


# Optional Configurations

## Cluster Level Configurations

These configurations are passed while defining the `CloudStackCluster` and apply to the entire cluster.

### Account

The account in which the CAPC cluster resources are to be created. Please note that the credentials of the user passed to CAPC via the
`CLOUDSTACK_B64ENCODED_SECRET` must have access the the specified account.

The account can be specified by adding the `CloudStackCluster.spec.account` field in the yaml specification

The list of accounts can be fetched using the cmk cli as follows :
```
cmk list accounts listall=true | jq '.account[] | {name, id}'
```

> Please note that if the optional configurations of account and domainid are passed,
> the corresponding account must have access to the specified resources on CloudStack such as the
> Network, Public IP, VM Template, Service Offering, SSH Key, Affinity Group, etc
### Domain

The domain / subdomain in which the CAPC cluster resources are to be created. Please note that the credentials of the user passed to CAPC via the
`CLOUDSTACK_B64ENCODED_SECRET` must have access the the specified domain

The domain can be specified by adding the `CloudStackCluster.spec.domain` field in the yaml specification

The list of domains can be fetched using the cmk cli as follows :
```
cmk list domains listall=true | jq '.domain[] | {name, id, path}'
```

> Please note that if the optional configurations of account and domainid are passed,
> the corresponding account must have access to the specified resources on CloudStack such as the
> Network, Public IP, VM Template, Service Offering, SSH Key, Affinity Group, etc
## Machine Level Configurations

These configurations are passed while defining the `CloudStackMachine`. They can differ based on the MachineSet mapped.

### SSH KeyPair

The SSH key pair must be an existing key registered in Apache CloudStack and is exposed as the environment variable `CLOUDSTACK_SSH_KEY_NAME`.

The ssh keypair can be specified by adding the `CloudStackMachine.spec.sshKey` field in the yaml specification

The list of SSH Keypairs can be fetched using the cmk cli as follows :
```
cmk list sshkeypairs listall=true | jq '.sshkeypair[] | {name, id}'
```

If the user wishes to pass a public key not registered in CloudStack directly to the node, it can be done by adding the `KubeadmConfigTemplate.spec.template.spec.users`
spec in the cluster definition yaml. Eg:

```yaml
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
metadata:
name: ${CLUSTER_NAME}-md-0
spec:
template:
spec:
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
provider-id: "cloudstack:///'{{ ds.meta_data.instance_id }}'"
name: '{{ local_hostname }}'
users:
- name: ${OS_USERID}
sshAuthorizedKeys:
- ${SSH_KEY_MATERIAL}
sudo: ALL=(ALL) NOPASSWD:ALL
```
To learn how to configure the required network access in order to SSH into the node, please see [here](../topics/ssh-access.html)
### Affinity Groups
The nodes in the MachineDeployment mapped to a corresponding CloudStackMachine can have a specific host affinity or be assigned to affinity groups.
The affinity can either be specified `pro` (host affinity) or `anti` (host anti affinity) in the `CloudStackMachine.spec.affinity` field in the yaml specification and the required affinity groups will be created in CloudStack
If existing affinity groups in CloudStack wish to be used, the group IDs can be passed as a list in the `CloudStackMachine.spec.affinitygroupids` field in the yaml specification

The list of existing affinity groups can be fetched using the cmk cli as follows :
```
cmk list affinitygroups listall=true | jq '.affinitygroup[] | {name, id}'
```


### VM Details

These are arbitrary key value pairs which are passed as VM details while deploying the nodes.

The VM details can be specified by adding the `CloudStackMachine.spec.details` field in the yaml specification

## Log level

TODO / Maybe add feature ?

## Timeout settings

TODO / Add feature

# Apache CloudStack Credentials

1. Generate the API and Secret Key for your Apache CloudStack instance either via the UI (Accounts > User > API Key) or the `getUserKeys` API.

2. Create a file named `cloud-config`, substituting in your own environment's values
```
[Global]
api-url = <cloudstackApiUrl>
api-key = <cloudstackApiKey>
secret-key = <cloudstackSecretKey>
```

3. Run the following command to save the above Apache CloudStack connection info into an environment variable :
```
export CLOUDSTACK_B64ENCODED_SECRET=$(base64 -w0 -i cloud-config)
```

4. Once exported, the management cluster can be initialized with Apache CloudStack as the underlying infrastructure provider
```
clusterctl init --infrastructure cloudstack
```

<!-- References -->

[cloudstack-capi-images]: https://image-builder.sigs.k8s.io/capi/providers/cloudstack.html
[clusterctl-generate-cluster]: https://cluster-api.sigs.k8s.io/user/quick-start.html#generating-the-cluster-configuration
[cmk-download]: https://github.com/apache/cloudstack-cloudmonkey/releases/
[jq-download]: https://stedolan.github.io/jq/
[prebuilt-images]: http://packages.shapeblue.com/cluster-api-provider-cloudstack/images/
[template-file]: https://github.com/kubernetes-sigs/cluster-api-provider-cloudstack/blob/main/templates/cluster-template.yaml
Loading

0 comments on commit de6f708

Please sign in to comment.