|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# A script that builds a single ACK service controller for an AWS service API |
| 4 | + |
| 5 | +set -eo pipefail |
| 6 | + |
| 7 | +SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" |
| 8 | +ROOT_DIR="$SCRIPTS_DIR/.." |
| 9 | +BIN_DIR="$ROOT_DIR/bin" |
| 10 | + |
| 11 | +source "$SCRIPTS_DIR/lib/common.sh" |
| 12 | +source "$SCRIPTS_DIR/lib/k8s.sh" |
| 13 | + |
| 14 | +check_is_installed controller-gen "You can install controller-gen with the helper scripts/install-controller-gen.sh" |
| 15 | + |
| 16 | +if ! k8s_controller_gen_version_equals "$CONTROLLER_TOOLS_VERSION"; then |
| 17 | + echo "FATAL: Existing version of controller-gen "`controller-gen --version`", required version is $CONTROLLER_TOOLS_VERSION." |
| 18 | + echo "FATAL: Please uninstall controller-gen and install the required version with scripts/install-controller-gen.sh." |
| 19 | + exit 1 |
| 20 | +fi |
| 21 | + |
| 22 | +ACK_GENERATE_CACHE_DIR=${ACK_GENERATE_CACHE_DIR:-"~/.cache/aws-controllers-k8s"} |
| 23 | +# The ack-generate code generator is in a separate source code repository, |
| 24 | +# typically at $GOPATH/src/github.com/aws-controllers-k8s/code-generator |
| 25 | +DEFAULT_ACK_GENERATE_BIN_PATH="$ROOT_DIR/bin/ack-generate" |
| 26 | +ACK_GENERATE_BIN_PATH=${ACK_GENERATE_BIN_PATH:-$DEFAULT_ACK_GENERATE_BIN_PATH} |
| 27 | +ACK_GENERATE_API_VERSION=${ACK_GENERATE_API_VERSION:-"v1alpha1"} |
| 28 | +ACK_GENERATE_CONFIG_PATH=${ACK_GENERATE_CONFIG_PATH:-""} |
| 29 | +DEFAULT_TEMPLATES_DIR="$ROOT_DIR/templates" |
| 30 | +TEMPLATES_DIR=${TEMPLATES_DIR:-$DEFAULT_TEMPLATES_DIR} |
| 31 | + |
| 32 | +USAGE=" |
| 33 | +Usage: |
| 34 | + $(basename "$0") <service> |
| 35 | +
|
| 36 | +<service> should be an AWS service API aliases that you wish to build -- e.g. |
| 37 | +'s3' 'sns' or 'sqs' |
| 38 | +
|
| 39 | +Environment variables: |
| 40 | + ACK_GENERATE_CACHE_DIR Overrides the directory used for caching AWS API |
| 41 | + models used by the ack-generate tool. |
| 42 | + Default: $ACK_GENERATE_CACHE_DIR |
| 43 | + ACK_GENERATE_BIN_PATH: Overrides the path to the the ack-generate binary. |
| 44 | + Default: $ACK_GENERATE_BIN_PATH |
| 45 | + ACK_GENERATE_API_VERSION: Overrides the version of the Kubernetes API objects |
| 46 | + generated by the ack-generate apis command. If not |
| 47 | + specified, and the service controller has been |
| 48 | + previously generated, the latest generated API |
| 49 | + version is used. If the service controller has yet |
| 50 | + to be generated, 'v1alpha1' is used. |
| 51 | + ACK_GENERATE_CONFIG_PATH: Specify a path to the generator config YAML file to |
| 52 | + instruct the code generator for the service. |
| 53 | + Default: services/{SERVICE}/generator.yaml |
| 54 | + K8S_RBAC_ROLE_NAME: Name of the Kubernetes Role to use when generating |
| 55 | + the RBAC manifests for the custom resource |
| 56 | + definitions. |
| 57 | + Default: $K8S_RBAC_ROLE_NAME |
| 58 | +" |
| 59 | + |
| 60 | +if [ $# -ne 1 ]; then |
| 61 | + echo "ERROR: $(basename "$0") only accepts a single parameter" 1>&2 |
| 62 | + echo "$USAGE" |
| 63 | + exit 1 |
| 64 | +fi |
| 65 | + |
| 66 | +if [ ! -f $ACK_GENERATE_BIN_PATH ]; then |
| 67 | + if is_installed "ack-generate"; then |
| 68 | + ACK_GENERATE_BIN_PATH=$(which "ack-generate") |
| 69 | + else |
| 70 | + echo "ERROR: Unable to find an ack-generate binary. |
| 71 | +Either set the ACK_GENERATE_BIN_PATH to a valid location or |
| 72 | +run: |
| 73 | + |
| 74 | + make build-ack-generate |
| 75 | + |
| 76 | +from the root directory or install ack-generate using: |
| 77 | +
|
| 78 | + go get -u github.com/aws-controllers-k8s/code-generator/cmd/ack-generate" 1>&2 |
| 79 | + exit 1; |
| 80 | + fi |
| 81 | +fi |
| 82 | +SERVICE=$(echo "$1" | tr '[:upper:]' '[:lower:]') |
| 83 | + |
| 84 | +# Source code for the controller will be in a separate repo, typically in |
| 85 | +# $GOPATH/src/github.com/aws-controllers-k8s/$AWS_SERVICE-controller/ |
| 86 | +DEFAULT_SERVICE_CONTROLLER_SOURCE_PATH="$ROOT_DIR/../$SERVICE-controller" |
| 87 | +SERVICE_CONTROLLER_SOURCE_PATH=${SERVICE_CONTROLLER_SOURCE_PATH:-$DEFAULT_SERVICE_CONTROLLER_SOURCE_PATH} |
| 88 | + |
| 89 | +if [[ ! -d $SERVICE_CONTROLLER_SOURCE_PATH ]]; then |
| 90 | + echo "Error evaluating SERVICE_CONTROLLER_SOURCE_PATH environment variable:" 1>&2 |
| 91 | + echo "$SERVICE_CONTROLLER_SOURCE_PATH is not a directory." 1>&2 |
| 92 | + echo "${USAGE}" |
| 93 | + exit 1 |
| 94 | +fi |
| 95 | + |
| 96 | +K8S_RBAC_ROLE_NAME=${K8S_RBAC_ROLE_NAME:-"ack-$SERVICE-controller"} |
| 97 | + |
| 98 | +# If there's a generator.yaml in the service's directory and the caller hasn't |
| 99 | +# specified an override, use that. |
| 100 | +if [ -z "$ACK_GENERATE_CONFIG_PATH" ]; then |
| 101 | + if [ -f "$SERVICE_CONTROLLER_SOURCE_PATH/generator.yaml" ]; then |
| 102 | + ACK_GENERATE_CONFIG_PATH="$SERVICE_CONTROLLER_SOURCE_PATH/generator.yaml" |
| 103 | + fi |
| 104 | +fi |
| 105 | + |
| 106 | +ag_args="$SERVICE -o $SERVICE_CONTROLLER_SOURCE_PATH --templates-dir $TEMPLATES_DIR" |
| 107 | +if [ -n "$ACK_GENERATE_CACHE_DIR" ]; then |
| 108 | + ag_args="$ag_args --cache-dir $ACK_GENERATE_CACHE_DIR" |
| 109 | +fi |
| 110 | + |
| 111 | +apis_args="apis $ag_args" |
| 112 | +if [ -n "$ACK_GENERATE_API_VERSION" ]; then |
| 113 | + apis_args="$apis_args --version $ACK_GENERATE_API_VERSION" |
| 114 | +fi |
| 115 | + |
| 116 | +if [ -n "$ACK_GENERATE_CONFIG_PATH" ]; then |
| 117 | + ag_args="$ag_args --generator-config-path $ACK_GENERATE_CONFIG_PATH" |
| 118 | + apis_args="$apis_args --generator-config-path $ACK_GENERATE_CONFIG_PATH" |
| 119 | +fi |
| 120 | + |
| 121 | +echo "Building Kubernetes API objects for $SERVICE" |
| 122 | +$ACK_GENERATE_BIN_PATH $apis_args |
| 123 | +if [ $? -ne 0 ]; then |
| 124 | + exit 2 |
| 125 | +fi |
| 126 | + |
| 127 | +config_output_dir="$SERVICE_CONTROLLER_SOURCE_PATH/config/" |
| 128 | + |
| 129 | +pushd $SERVICE_CONTROLLER_SOURCE_PATH/apis/$ACK_GENERATE_API_VERSION 1>/dev/null |
| 130 | + |
| 131 | +echo "Generating deepcopy code for $SERVICE" |
| 132 | +controller-gen object:headerFile=$TEMPLATES_DIR/boilerplate.txt paths=./... |
| 133 | + |
| 134 | +echo "Generating custom resource definitions for $SERVICE" |
| 135 | +# Latest version of controller-gen (master) is required for following two reasons |
| 136 | +# a) support for pointer values in map https://github.com/kubernetes-sigs/controller-tools/pull/317 |
| 137 | +# b) support for float type (allowDangerousTypes) https://github.com/kubernetes-sigs/controller-tools/pull/449 |
| 138 | +controller-gen crd:allowDangerousTypes=true paths=./... output:crd:artifacts:config=$config_output_dir/crd/bases |
| 139 | + |
| 140 | +popd 1>/dev/null |
| 141 | + |
| 142 | +echo "Building service controller for $SERVICE" |
| 143 | +controller_args="controller $ag_args" |
| 144 | +$ACK_GENERATE_BIN_PATH $controller_args |
| 145 | +if [ $? -ne 0 ]; then |
| 146 | + exit 2 |
| 147 | +fi |
| 148 | + |
| 149 | +pushd $SERVICE_CONTROLLER_SOURCE_PATH/pkg/resource 1>/dev/null |
| 150 | + |
| 151 | +echo "Generating RBAC manifests for $SERVICE" |
| 152 | +controller-gen rbac:roleName=$K8S_RBAC_ROLE_NAME paths=./... output:rbac:artifacts:config=$config_output_dir/rbac |
| 153 | +# controller-gen rbac outputs a ClusterRole definition in a |
| 154 | +# $config_output_dir/rbac/role.yaml file. We have some other standard Role |
| 155 | +# files for a reader and writer role, so here we rename the `role.yaml` file to |
| 156 | +# `cluster-role-controller.yaml` to better reflect what is in that file. |
| 157 | +mv $config_output_dir/rbac/role.yaml $config_output_dir/rbac/cluster-role-controller.yaml |
| 158 | + |
| 159 | +popd 1>/dev/null |
| 160 | + |
| 161 | +echo "Running gofmt against generated code for $SERVICE" |
| 162 | +gofmt -w "$SERVICE_CONTROLLER_SOURCE_PATH" |
0 commit comments