Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Release/v2/preview to main #73

Merged
merged 17 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ on:
push:
branches:
- main
- 'release/*'
- 'release/**'
pull_request:
branches:
- main
- 'release/*'
- 'release/**'

jobs:
build:
Expand All @@ -25,6 +25,7 @@ jobs:
- name: Run Test
run: |
echo 'Install evntest tool'
GOBIN=$GITHUB_WORKSPACE go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
ENVTEST_VERSION=release-0.16
GOBIN=$GITHUB_WORKSPACE go install sigs.k8s.io/controller-runtime/tools/setup-envtest@$ENVTEST_VERSION
echo 'Run tests'
KUBEBUILDER_ASSETS=$($GITHUB_WORKSPACE/setup-envtest use 1.19 -p path) CGO_ENABLED=0 go test ./... -coverprofile cover.out
30 changes: 30 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: golangci-lint
on:
push:
branches:
- main
- 'release/**'
pull_request:
branches:
- main
- 'release/**'

permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.22.6
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.59
args: --timeout 10m
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build the manager binary
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.22-cbl-mariner2.0 as builder
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.22-cbl-mariner2.0 AS builder

ARG MODULE_VERSION
WORKDIR /workspace
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,7 @@ $(CONTROLLER_GEN): $(LOCALBIN)
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
$(ENVTEST): $(LOCALBIN)
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest

.PHONY: lint
lint: ## Run linting tools.
golangci-lint run ./...
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ Documentation on how to use the Azure App Configuration Kubernetes Provider is a
+ [Use dynamic configuration in Azure Kubernetes Service](https://learn.microsoft.com/azure/azure-app-configuration/enable-dynamic-configuration-azure-kubernetes-service)
+ See [Kubernetes Provider Reference](https://learn.microsoft.com/azure/azure-app-configuration/reference-kubernetes-provider) for a complete list of features.

## Data collection

The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry by setting the `requestTracing.enabled=false` while installing the Azure App Configuration Kubernetes Provider. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Expand Down
1 change: 1 addition & 0 deletions api/v1/azureappconfigurationprovider_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ type AzureAppConfigurationProviderAuth struct {
type WorkloadIdentityParameters struct {
ManagedIdentityClientId *string `json:"managedIdentityClientId,omitempty"`
ManagedIdentityClientIdReference *ManagedIdentityReferenceParameters `json:"managedIdentityClientIdReference,omitempty"`
ServiceAccountName *string `json:"serviceAccountName,omitempty"`
}

// ManagedIdentityReferenceParameters defines the parameters for configmap reference
Expand Down
5 changes: 5 additions & 0 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions arc/conformance/plugin/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM mcr.microsoft.com/azure-cli:latest

RUN pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org pytest pytest-xdist filelock junit_xml kubernetes==24.2.0 azure.identity msrestazure azure-mgmt-hybridkubernetes azure-mgmt-kubernetesconfiguration==2.0.0
RUN wget https://storage.googleapis.com/kubernetes-release/release/$(wget -qO- https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
RUN chmod +x ./kubectl
RUN mv ./kubectl /usr/local/bin

COPY arc/conformance/plugin/arc_conformance.sh /arc/arc_conformance.sh
COPY arc/conformance/plugin/setup_failure_handler.py /arc/setup_failure_handler.py

RUN ["chmod", "+x", "/arc/arc_conformance.sh"]
ENTRYPOINT ["/arc/arc_conformance.sh"]
166 changes: 166 additions & 0 deletions arc/conformance/plugin/arc_conformance.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env bash

set -e

results_dir="${RESULTS_DIR:-/tmp/results}"

waitForArc() {
ready=false
max_retries=60
sleep_seconds=20

for i in $(seq 1 $max_retries)
do
status=$(helm ls -a -A -o json | jq '.[]|select(.name=="azure-arc").status' -r)
if [ "$status" == "deployed" ]; then
echo "helm release successful"
ready=true
break
elif [ "$status" == "failed" ]; then
echo "helm release failed"
break
else
echo "waiting for helm release to be successful. Status - ${status}. Attempt# $i of $max_retries"
sleep ${sleep_seconds}
fi
done

echo "$ready"
}

saveResult() {
# prepare the results for handoff to the Sonobuoy worker.
cd "${results_dir}"
# Sonobuoy worker expects a tar file.
tar czf results.tar.gz ./*
# Signal the worker by writing out the name of the results file into a "done" file.
printf "%s/results.tar.gz" "${results_dir}" > "${results_dir}"/done
}

# Ensure that we tell the Sonobuoy worker we are done regardless of results.
trap saveResult EXIT

# initial environment variables for the plugin
setEnviornmentVariables() {
export JUNIT_OUTPUT_FILEPATH=/tmp/results/
export IS_ARC_TEST=true
export CI_KIND_CLUSTER=true
}

# setup kubeconfig for conformance test
setupKubeConfig() {
KUBECTL_CONTEXT=azure-arc-appconfig-test
APISERVER=https://kubernetes.default.svc/
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt > ca.crt

kubectl config set-cluster ${KUBECTL_CONTEXT} \
--embed-certs=true \
--server=${APISERVER} \
--certificate-authority=./ca.crt 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py

kubectl config set-credentials ${KUBECTL_CONTEXT} --token="${TOKEN}" 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py

# Delete previous rolebinding if exists. And ignore the error if not found.
kubectl delete clusterrolebinding clusterconnect-binding --ignore-not-found
kubectl create clusterrolebinding clusterconnect-binding --clusterrole=cluster-admin --user="${OBJECT_ID}" 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py

kubectl config set-context ${KUBECTL_CONTEXT} \
--cluster=${KUBECTL_CONTEXT} \
--user=${KUBECTL_CONTEXT} \
--namespace=default 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py

kubectl config use-context ${KUBECTL_CONTEXT} 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py
echo "INFO: KubeConfig setup complete"
}

# validate enviorment variables
if [ -z "${TENANT_ID}" ]; then
echo "ERROR: parameter TENANT_ID is required." > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
fi

if [ -z "${SUBSCRIPTION_ID}" ]; then
echo "ERROR: parameter SUBSCRIPTION_ID is required." > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
fi

if [ -z "${AZURE_CLIENT_ID}" ]; then
echo "ERROR: parameter AZURE_CLIENT_ID is required." > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
fi

if [ -z "${AZURE_CLIENT_SECRET}" ]; then
echo "ERROR: parameter AZURE_CLIENT_SECRET is required." > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
fi

if [ -z "${CLUSTER_NAME}" ]; then
echo "ERROR: parameter CLUSTER_NAME is required." > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
fi

if [ -z "${CLUSTER_RG}" ]; then
echo "ERROR: parameter CLUSTER_RG is required." > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
fi

# OBJECT_ID is an id of the Service Principal created in conformance test subscription.
if [ -z "${OBJECT_ID}" ]; then
echo "ERROR: parameter OBJECT_ID is required." > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
fi

# add az cli extensions
az extension add --name k8s-extension

# login with service principal
az login --service-principal \
-u "${AZURE_CLIENT_ID}" \
-p "${AZURE_CLIENT_SECRET}" \
--tenant "${TENANT_ID}" 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py

az account set --subscription "${SUBSCRIPTION_ID}" 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py

# set environment variables
setEnviornmentVariables

# setup Kubeconfig
setupKubeConfig

# Wait for resources in ARC agents to come up
echo "INFO: Waiting for ConnectedCluster to come up"
waitSuccessArc="$(waitForArc)"
if [ "${waitSuccessArc}" == false ]; then
echo "helm release azure-arc failed" > "${results_dir}"/error
python3 /arc/setup_failure_handler.py
exit 1
else
echo "INFO: ConnectedCluster is available"
fi

# register the KubernetesConfiguration resource provider
az provider register --namespace Microsoft.KubernetesConfiguration

echo "INFO: Creating extension"
az k8s-extension create \
--name appconfigurationkubernetesprovider \
--extension-type Microsoft.AppConfiguration \
--cluster-name "${CLUSTER_NAME}" \
--resource-group "${CLUSTER_RG}" \
--cluster-type managedClusters \
--release-train preview 2> "${results_dir}"/error || python3 /arc/setup_failure_handler.py

# wait for provider pods
kubectl wait pod -n azappconfig-system --for=condition=Ready -l app.kubernetes.io/instance=azureappconfiguration.kubernetesprovider --timeout=5m

# clean up test resources
echo "INFO: cleaning up test resources"
az k8s-extension delete \
--name appconfigurationkubernetesprovider \
--resource-group "${CLUSTER_RG}" \
--cluster-type managedClusters \
--cluster-name "${CLUSTER_NAME}" \
--force \
--yes \
--no-wait
15 changes: 15 additions & 0 deletions arc/conformance/plugin/conformance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
sonobuoy-config:
driver: Job
plugin-name: azure-arc-app-config-provider
result-format: junit
spec:
image: mcr.microsoft.com/azure-app-configuration/extension-test-plugin:0.1.0
imagePullPolicy: Always
name: plugin
resources: {}
volumes:
- name: results
emptyDir: {}
volumeMounts:
- mountPath: /tmp/results
name: results
18 changes: 18 additions & 0 deletions arc/conformance/plugin/setup_failure_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import sys
from junit_xml import TestSuite, TestCase

# Reading error message from error file
with open('/tmp/results/error', 'r') as f:
error_message = f.read()

# Creating a junit report for setup failure
test_case = TestCase('azure_app_configuration_provider_conformance_setup', 'azure_app_configuration_provider_conformance_setup')
test_case.add_failure_info(error_message)
test_cases = [test_case]
test_suite = TestSuite("azure_app_configuration_provider_conformance", test_cases)

with open('/tmp/results/results.xml', 'w') as f:
TestSuite.to_file(f, [test_suite], prettyprint=False)

# Exit with non-zero return code
sys.exit(1)
3 changes: 3 additions & 0 deletions arc/conformance/plugin/version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"version":"0.1.0"
}
8 changes: 5 additions & 3 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"k8s.io/klog/v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

configproviderv1 "azappconfig/provider/api/v1"
"azappconfig/provider/internal/controller"
Expand Down Expand Up @@ -67,9 +68,10 @@ func main() {
ctrl.SetLogger(klog.NewKlogr())

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
Scheme: scheme,
Metrics: metricsserver.Options{
BindAddress: metricsAddr,
},
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "leader.elect.locker.azappconfig.io",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ spec:
- configMap
- key
type: object
serviceAccountName:
type: string
type: object
type: object
configuration:
Expand Down Expand Up @@ -208,6 +210,8 @@ spec:
- configMap
- key
type: object
serviceAccountName:
type: string
type: object
required:
- uri
Expand Down Expand Up @@ -239,6 +243,8 @@ spec:
- configMap
- key
type: object
serviceAccountName:
type: string
type: object
type: object
refresh:
Expand Down
4 changes: 4 additions & 0 deletions deploy/parameter/helm-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ imagePullSecrets: []
nameOverride: "appconfig-provider"
fullnameOverride: "az-appconfig-k8s-provider"

requestTracing:
enabled: true

workloadIdentity:
enabled: true
globalServiceAccountEnabled: false

serviceAccount:
# Specifies whether a service account should be created
Expand Down
2 changes: 1 addition & 1 deletion deploy/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Selector labels
app.kubernetes.io/name: {{ include "az-appconfig-k8s-provider.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
control-plane: controller-manager
{{- if eq .Values.workloadIdentity.enabled true }}
{{- if and (.Values.workloadIdentity.enabled) }}
azure.workload.identity/use: "true"
{{- end }}
{{- end }}
Expand Down
Loading
Loading