This PR wants to add the configuration to set up dual-stack compute engine instance with an external IPv6 address.
I made manual testing with a GCP project.
Manual testing
Set up
I created a test environment on GCP.
More info :arrow_down:
I created a GSA (google service account) with the good roles (more details [here](https://github.com/jenkinsci/google-compute-engine-plugin/blob/develop/docs/Home.md#iam-credentials)) then I generated a private key to use this GSA in the plugin.
```bash
export PROJECT_ID="MY_GCP_PROJECT_ID"
export REGION="MY_REGION"
export ZONE="MY_ZONE"
gcloud auth login
gcloud config set project ${PROJECT_ID}
export SA_NAME="my-sa-name"
export SA_DESC="my-sa-desc"
# https://cloud.google.com/iam/docs/service-accounts-create#iam-service-accounts-create-gcloud
gcloud iam service-accounts create ${SA_NAME} \
--description="${SA_DESC}" \
--display-name="${SA_NAME}"
# https://cloud.google.com/compute/docs/access/iam
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/compute.instanceAdmin"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/compute.networkAdmin"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="iam/compute.serviceAccountUser"
# check GSA roles
gcloud projects get-iam-policy ${PROJECT_ID} \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
# https://cloud.google.com/iam/docs/keys-create-delete
export KEY_FILE="${SA_NAME}-private-key.json"
gcloud iam service-accounts keys create "${KEY_FILE}" \
--iam-account="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
```
I also created a network and a subnetwork with dual-stack mode.
```bash
# create network
export NETWORK_NAME="my-network"
gcloud compute networks create ${NETWORK_NAME} --project=${PROJECT_ID} --subnet-mode=custom --mtu=1460 --bgp-routing-mode=regional
gcloud compute networks list
# this one don't seem to be required
export FIREWALL_ALLOW_ALL_NAME="my-firewall-allow-all-custom"
gcloud compute firewall-rules create ${FIREWALL_ALLOW_ALL_NAME} --project=${PROJECT_ID} --network=projects/${PROJECT_ID}/global/networks/${NETWORK_NAME} --description="Allows connection from any source to any instance on the network using custom protocols." --direction=INGRESS --priority=65534 --source-ranges=10.0.0.0/24 --action=ALLOW --rules=all
# this one is a single-stack subnetwork, not required for our tests
export SINGLE_STACK_SUBNETWORK_NAME="my-single-stack-subnetwork"
gcloud compute networks subnets create ${SINGLE_STACK_SUBNETWORK_NAME} --project=${PROJECT_ID} --range=10.0.0.0/16 --stack-type=IPV4_ONLY --region=${REGION} --network=${NETWORK_NAME}
# this one is a dual-stack subnetwork
export DUAL_STACK_SUBNETWORK_NAME="my-dual-stack-bis-subnetwork"
gcloud compute networks subnets create ${DUAL_STACK_SUBNETWORK_NAME} --project=${PROJECT_ID} --range=10.2.0.0/16 --stack-type=IPV4_IPV6 --ipv6-access-type=EXTERNAL --network=${NETWORK_NAME} --region=${REGION}
```
In the plugin, I created a Cloud configuration from the GSA private JSON key.
In the _Machine Configuration_ I used an `e2-standard-4` machine type with the networks I created then I played with the new options I added:
![image](https://github.com/jenkinsci/google-compute-engine-plugin/assets/24521660/affa2fe1-d46c-43a5-8ba0-bba06686f473)
Testing
You'll find the tests I did below with the subnetwork configured in dual-mode (IPV4_IPV6).
plugin configuration
GCP configuration
telnet ADDRESS 22
plugin SSH connection
IPV4_only with IPV4 external address
OK :green_circle:
IPv4: OK :green_circle:
OK :green_circle: (IPv4 address used)
IPV4_IPV6 with IPv4 external address
NOK but it's normal :green_circle: (IPv6 address is mandatory on network interface dual-stack mode)
IPv4: OK :green_circle: / IPv6: NOK :orange_circle: (Network Unreachable)
NOK :orange_circle: (IPv6 has the priority on IPv4 and is unreachable)
IPV4_IPV6 with both IPv4 and IPv6 external addresses
OK :green_circle:
IPv4: OK :green_circle: / IPv6: NOK :orange_circle: (Network Unreachable)
NOK :orange_circle: (IPv6 has the priority on IPv4 and is unreachable)
IPV4_IPV6 with IPv6 external address
OK :green_circle: (IPv4 is not mandatory on network interface dual-stack mode compared to IPv6)
IPv6: NOK :orange_circle: (Network Unreachable)
NOK :orange_circle: (IPv6 is unreachable)
IPV4_IPv6 without any external addresses
NOK but it's normal :green_circle: (IPv6 address is mandatory on network interface dual-stack mode)
IPv6: NOK :orange_circle: (Network Unreachable)
NOK :orange_circle: (IPv6 is unreachable)
:information_source:
The :orange_circle: are only related to my local network configuration. I can't access IPv6 for now but I'm currently trying to configure it (my ISP needs to provide IPv6 address and I need to configure my local router to use DHCPv6). Other than that, the GCP configuration works well. :tada:
Testing done
### Submitter checklist
- [x] Make sure you are opening from a **topic/feature/bugfix branch** (right side) and not your main branch!
- [x] Ensure that the pull request title represents the desired changelog entry
- [x] Please describe what you did
- [ ] Link to relevant issues in GitHub or Jira
- [x] Link to relevant pull requests, esp. upstream and downstream changes
- [ ] Ensure you have provided tests - that demonstrates feature works or fixes the issue
This PR wants to add the configuration to set up dual-stack compute engine instance with an external IPv6 address.
I made manual testing with a GCP project.
Manual testing
Set up
I created a test environment on GCP.
More info :arrow_down:
I created a GSA (google service account) with the good roles (more details [here](https://github.com/jenkinsci/google-compute-engine-plugin/blob/develop/docs/Home.md#iam-credentials)) then I generated a private key to use this GSA in the plugin. ```bash export PROJECT_ID="MY_GCP_PROJECT_ID" export REGION="MY_REGION" export ZONE="MY_ZONE" gcloud auth login gcloud config set project ${PROJECT_ID} export SA_NAME="my-sa-name" export SA_DESC="my-sa-desc" # https://cloud.google.com/iam/docs/service-accounts-create#iam-service-accounts-create-gcloud gcloud iam service-accounts create ${SA_NAME} \ --description="${SA_DESC}" \ --display-name="${SA_NAME}" # https://cloud.google.com/compute/docs/access/iam gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/compute.instanceAdmin" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/compute.networkAdmin" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="iam/compute.serviceAccountUser" # check GSA roles gcloud projects get-iam-policy ${PROJECT_ID} \ --flatten="bindings[].members" \ --format='table(bindings.role)' \ --filter="bindings.members:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" # https://cloud.google.com/iam/docs/keys-create-delete export KEY_FILE="${SA_NAME}-private-key.json" gcloud iam service-accounts keys create "${KEY_FILE}" \ --iam-account="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" ``` I also created a network and a subnetwork with dual-stack mode. ```bash # create network export NETWORK_NAME="my-network" gcloud compute networks create ${NETWORK_NAME} --project=${PROJECT_ID} --subnet-mode=custom --mtu=1460 --bgp-routing-mode=regional gcloud compute networks list # this one don't seem to be required export FIREWALL_ALLOW_ALL_NAME="my-firewall-allow-all-custom" gcloud compute firewall-rules create ${FIREWALL_ALLOW_ALL_NAME} --project=${PROJECT_ID} --network=projects/${PROJECT_ID}/global/networks/${NETWORK_NAME} --description="Allows connection from any source to any instance on the network using custom protocols." --direction=INGRESS --priority=65534 --source-ranges=10.0.0.0/24 --action=ALLOW --rules=all # this one is a single-stack subnetwork, not required for our tests export SINGLE_STACK_SUBNETWORK_NAME="my-single-stack-subnetwork" gcloud compute networks subnets create ${SINGLE_STACK_SUBNETWORK_NAME} --project=${PROJECT_ID} --range=10.0.0.0/16 --stack-type=IPV4_ONLY --region=${REGION} --network=${NETWORK_NAME} # this one is a dual-stack subnetwork export DUAL_STACK_SUBNETWORK_NAME="my-dual-stack-bis-subnetwork" gcloud compute networks subnets create ${DUAL_STACK_SUBNETWORK_NAME} --project=${PROJECT_ID} --range=10.2.0.0/16 --stack-type=IPV4_IPV6 --ipv6-access-type=EXTERNAL --network=${NETWORK_NAME} --region=${REGION} ``` In the plugin, I created a Cloud configuration from the GSA private JSON key. In the _Machine Configuration_ I used an `e2-standard-4` machine type with the networks I created then I played with the new options I added: ![image](https://github.com/jenkinsci/google-compute-engine-plugin/assets/24521660/affa2fe1-d46c-43a5-8ba0-bba06686f473)
Testing
You'll find the tests I did below with the subnetwork configured in dual-mode (IPV4_IPV6).
IPV4_IPV6 with IPv4 external addressIPV4_IPv6 without any external addresses:information_source: The :orange_circle: are only related to my local network configuration. I can't access IPv6 for now but I'm currently trying to configure it (my ISP needs to provide IPv6 address and I need to configure my local router to use DHCPv6). Other than that, the GCP configuration works well. :tada:
Testing done