fix: enable automatic testing and refactor tests (#51)
Signed-off-by: matttrach <matt.trachier@suse.com>
This commit is contained in:
parent
051b959168
commit
5f3c4e9825
27
.envrc
27
.envrc
|
|
@ -4,17 +4,39 @@ nf () {
|
|||
nix --extra-experimental-features nix-command --extra-experimental-features flakes "$@"
|
||||
}
|
||||
|
||||
get_repo_basename() {
|
||||
basename "$(git rev-parse --show-toplevel)"
|
||||
}
|
||||
|
||||
get_profile() {
|
||||
basename="$(get_repo_basename)"
|
||||
echo "$HOME/.config/nix/profiles/$basename"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
echo "Cleaning Up..."
|
||||
nix-collect-garbage --delete-older-than 30d
|
||||
basename="$(get_repo_basename)"
|
||||
profile="$(get_profile)"
|
||||
if [ -z "$basename" ]; then echo "basename is empty"; exit 1; fi
|
||||
export NIX_PATH="$profile"
|
||||
export NIX_PROFILE="$profile"
|
||||
nix-env --profile "$profile" --delete-generations +3
|
||||
nix-env --profile "$profile" --list-generations
|
||||
}
|
||||
|
||||
if ! which "$0" | grep -q nix; then
|
||||
print 'Entering Environment...'
|
||||
basename="$(get_repo_basename)"
|
||||
profile="$(get_profile)"
|
||||
export NIX_PROFILE="$profile"
|
||||
|
||||
print 'Updating Nix Cache...'
|
||||
nf flake update
|
||||
|
||||
echo 'Installing Nix Profile...'
|
||||
nf profile install . --profile "$profile"
|
||||
nf profile list --profile "$profile"
|
||||
|
||||
print 'Starting...'
|
||||
# --impure allows Nix to reuse previously built paths
|
||||
# --ignore-environment ignores the environment variables and paths to tools not installed by nix
|
||||
|
|
@ -34,7 +56,8 @@ if ! which "$0" | grep -q nix; then
|
|||
--keep TERM \
|
||||
--keep XDG_DATA_DIRS \
|
||||
--keep NIX_SSL_CERT_FILE \
|
||||
. \
|
||||
--keep NIX_PROFILE \
|
||||
--profile "$profile" \
|
||||
--command bash -c "bash --rcfile .envrc"
|
||||
|
||||
print 'Exiting Dev Environment...'
|
||||
|
|
|
|||
|
|
@ -71,13 +71,15 @@ jobs:
|
|||
with:
|
||||
token: ${{secrets.GITHUB_TOKEN}}
|
||||
fetch-depth: 0
|
||||
- uses: aws-actions/configure-aws-credentials@v4
|
||||
- id: aws-creds
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
if: steps.release-please.outputs.pr
|
||||
with:
|
||||
role-to-assume: ${{env.AWS_ROLE}}
|
||||
role-session-name: ${{github.run_id}}
|
||||
aws-region: ${{env.AWS_REGION}}
|
||||
role-duration-seconds: 7200 # 2 hours
|
||||
output-credentials: true
|
||||
- name: install-nix
|
||||
run: |
|
||||
curl -L https://nixos.org/nix/install | sh
|
||||
|
|
@ -88,6 +90,9 @@ jobs:
|
|||
if: steps.release-please.outputs.pr
|
||||
shell: '/home/runner/.nix-profile/bin/nix develop --ignore-environment --extra-experimental-features nix-command --extra-experimental-features flakes --keep HOME --keep SSH_AUTH_SOCK --keep IDENTIFIER --keep GITHUB_TOKEN --keep GITHUB_OWNER --keep ZONE --keep AWS_ROLE --keep AWS_REGION --keep AWS_DEFAULT_REGION --keep AWS_ACCESS_KEY_ID --keep AWS_SECRET_ACCESS_KEY --keep AWS_SESSION_TOKEN --keep UPDATECLI_GPGTOKEN --keep UPDATECLI_GITHUB_TOKEN --keep UPDATECLI_GITHUB_ACTOR --keep GPG_SIGNING_KEY --keep NIX_SSL_CERT_FILE --keep NIX_ENV_LOADED --keep TERM --command bash -e {0}'
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ steps.aws-creds.outputs.aws-access-key-id }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ steps.aws-creds.outputs.aws-secret-access-key }}
|
||||
AWS_SESSION_TOKEN: ${{ steps.aws-creds.outputs.aws-session-token }}
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
GITHUB_OWNER: rancher
|
||||
IDENTIFIER: ${{github.run_id}}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,6 @@ These tools are not necessary, but they can make it much simpler to collaborate.
|
|||
|
||||
#### Automated Tests
|
||||
|
||||
Our continuous integration tests using the GitHub [ubuntu-latest runner](https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md) which has many different things installed and does not rely on Nix.
|
||||
Our continuous integration tests using the GitHub [ubuntu-latest runner](https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md), we then rely on Nix to deploy the additional dependencies.
|
||||
|
||||
It also has special integrations with AWS to allow secure authentication, see https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services for more information.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
# Deploy RKE2 Example
|
||||
|
||||
This basic example shows a normal path to deploying Rancher with a downstream RKE2 with IAC.
|
||||
|
||||
Because this is considered a normal deployment path it is useful when troubleshooting user issues that come up from time to time.
|
||||
However, due to the security concerns and the way we authenticate our automation it won't be automatically tested.
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
provider "aws" {
|
||||
default_tags {
|
||||
tags = {
|
||||
Id = local.identifier
|
||||
Owner = local.owner
|
||||
}
|
||||
}
|
||||
region = local.aws_region
|
||||
}
|
||||
|
||||
provider "acme" {
|
||||
server_url = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
}
|
||||
|
||||
provider "github" {}
|
||||
provider "kubernetes" {} # make sure you set the env variable KUBE_CONFIG_PATH to local_file_path (file_path variable)
|
||||
provider "helm" {} # make sure you set the env variable KUBE_CONFIG_PATH to local_file_path (file_path variable)
|
||||
|
||||
provider "rancher2" {
|
||||
alias = "authenticate"
|
||||
bootstrap = true
|
||||
api_url = "https://${local.domain}.${local.zone}"
|
||||
timeout = "300s"
|
||||
}
|
||||
|
||||
resource "rancher2_bootstrap" "authenticate" {
|
||||
provider = rancher2.authenticate
|
||||
initial_password = module.rancher.admin_password
|
||||
password = module.rancher.admin_password
|
||||
token_update = true
|
||||
token_ttl = 7200 # 2 hours
|
||||
}
|
||||
|
||||
provider "rancher2" {
|
||||
alias = "default"
|
||||
api_url = "https://${local.domain}.${local.zone}"
|
||||
token_key = rancher2_bootstrap.authenticate.token
|
||||
timeout = "300s"
|
||||
}
|
||||
|
||||
locals {
|
||||
identifier = var.identifier
|
||||
example = "basic"
|
||||
project_name = "tf-${substr(md5(join("-", [local.example, local.identifier])), 0, 5)}"
|
||||
username = local.project_name
|
||||
domain = local.project_name
|
||||
zone = var.zone
|
||||
key_name = var.key_name
|
||||
key = var.key
|
||||
owner = var.owner
|
||||
rke2_version = var.rke2_version
|
||||
local_file_path = var.file_path
|
||||
runner_ip = chomp(data.http.myip.response_body) # "runner" is the server running Terraform
|
||||
rancher_version = var.rancher_version
|
||||
rancher_helm_repository = "https://releases.rancher.com/server-charts/stable"
|
||||
cert_manager_version = "1.13.1"
|
||||
os = "sle-micro-60"
|
||||
aws_access_key_id = var.aws_access_key_id
|
||||
aws_secret_access_key = var.aws_secret_access_key
|
||||
aws_region = var.aws_region
|
||||
email = (var.email != "" ? var.email : "${local.identifier}@${local.zone}")
|
||||
private_ip = replace(module.rancher.private_endpoint, "http://", "")
|
||||
hostname_prefix = "n10y02rke2"
|
||||
}
|
||||
|
||||
data "http" "myip" {
|
||||
url = "https://ipinfo.io/ip"
|
||||
}
|
||||
|
||||
module "rancher" {
|
||||
source = "../../"
|
||||
# project
|
||||
identifier = local.identifier
|
||||
owner = local.owner
|
||||
project_name = local.project_name
|
||||
domain = local.domain
|
||||
zone = local.zone
|
||||
skip_project_cert_generation = true
|
||||
# access
|
||||
key_name = local.key_name
|
||||
key = local.key
|
||||
username = local.username
|
||||
admin_ip = local.runner_ip
|
||||
# rke2
|
||||
rke2_version = local.rke2_version
|
||||
local_file_path = local.local_file_path
|
||||
install_method = "rpm" # rpm only for now, need to figure out local helm chart installs otherwise
|
||||
cni = "canal"
|
||||
node_configuration = {
|
||||
"rancher" = {
|
||||
type = "all-in-one"
|
||||
size = "large"
|
||||
os = local.os
|
||||
indirect_access = true
|
||||
initial = true
|
||||
}
|
||||
}
|
||||
# rancher
|
||||
rancher_version = local.rancher_version
|
||||
rancher_helm_repository = local.rancher_helm_repository
|
||||
cert_manager_version = local.cert_manager_version
|
||||
configure_cert_manager = true
|
||||
cert_manager_configuration = {
|
||||
aws_access_key_id = local.aws_access_key_id
|
||||
aws_secret_access_key = local.aws_secret_access_key
|
||||
aws_region = local.aws_region
|
||||
email = local.email
|
||||
}
|
||||
}
|
||||
|
||||
module "rke2_image" {
|
||||
source = "rancher/server/aws"
|
||||
version = "v1.3.1"
|
||||
server_use_strategy = "skip"
|
||||
image_use_strategy = "find"
|
||||
image_type = local.os
|
||||
}
|
||||
|
||||
# this adds the private (10.) IP to the domain
|
||||
# the private IP communicates to the agents where to find Rancher
|
||||
resource "aws_route53_record" "modified" {
|
||||
depends_on = [
|
||||
module.rancher,
|
||||
]
|
||||
zone_id = module.rancher.domain_object.zone_id
|
||||
name = module.rancher.domain_object.name
|
||||
type = module.rancher.domain_object.type
|
||||
ttl = 30
|
||||
records = concat([local.private_ip], tolist(module.rancher.domain_object.records))
|
||||
allow_overwrite = true
|
||||
}
|
||||
|
||||
resource "rancher2_cloud_credential" "aws" {
|
||||
depends_on = [
|
||||
rancher2_bootstrap.authenticate,
|
||||
module.rancher,
|
||||
aws_route53_record.modified,
|
||||
]
|
||||
provider = rancher2.default
|
||||
name = "aws"
|
||||
description = "amazon ec2"
|
||||
amazonec2_credential_config {
|
||||
access_key = local.aws_access_key_id
|
||||
secret_key = local.aws_secret_access_key
|
||||
default_region = local.aws_region
|
||||
}
|
||||
}
|
||||
|
||||
resource "rancher2_machine_config_v2" "core" {
|
||||
depends_on = [
|
||||
rancher2_bootstrap.authenticate,
|
||||
module.rancher,
|
||||
aws_route53_record.modified,
|
||||
rancher2_cloud_credential.aws,
|
||||
]
|
||||
provider = rancher2.default
|
||||
generate_name = "core-rke2-template"
|
||||
amazonec2_config {
|
||||
ami = module.rke2_image.image.id
|
||||
region = local.aws_region
|
||||
security_group = [module.rancher.security_group.name]
|
||||
subnet_id = module.rancher.subnets[keys(module.rancher.subnets)[0]].id
|
||||
vpc_id = module.rancher.vpc.id
|
||||
zone = replace( # it is looking for just the last letter of the availability zone, eg. for us-west-2a it just wants 'a'
|
||||
module.rancher.subnets[keys(module.rancher.subnets)[0]].availability_zone,
|
||||
local.aws_region,
|
||||
""
|
||||
)
|
||||
instance_type = "m5.large"
|
||||
ssh_user = "ec2-user"
|
||||
userdata = <<-EOT
|
||||
#cloud-config
|
||||
bootcmd:
|
||||
- echo ${local.private_ip} ${local.domain}.${local.zone} >> /etc/hosts
|
||||
EOT
|
||||
tags = join(",", ["Id", local.identifier, "Owner", local.owner])
|
||||
}
|
||||
}
|
||||
resource "rancher2_machine_config_v2" "worker" {
|
||||
depends_on = [
|
||||
rancher2_bootstrap.authenticate,
|
||||
module.rancher,
|
||||
aws_route53_record.modified,
|
||||
rancher2_cloud_credential.aws,
|
||||
]
|
||||
provider = rancher2.default
|
||||
generate_name = "worker-rke2-template"
|
||||
amazonec2_config {
|
||||
ami = module.rke2_image.image.id
|
||||
region = local.aws_region
|
||||
security_group = [module.rancher.security_group.name]
|
||||
subnet_id = module.rancher.subnets[keys(module.rancher.subnets)[0]].id
|
||||
vpc_id = module.rancher.vpc.id
|
||||
zone = replace( # it is looking for just the last letter of the availability zone, eg. for us-west-2a it just wants 'a'
|
||||
module.rancher.subnets[keys(module.rancher.subnets)[0]].availability_zone,
|
||||
local.aws_region,
|
||||
""
|
||||
)
|
||||
instance_type = "m5.large"
|
||||
ssh_user = "ec2-user"
|
||||
userdata = <<-EOT
|
||||
#cloud-config
|
||||
bootcmd:
|
||||
- echo ${local.private_ip} ${local.domain}.${local.zone} >> /etc/hosts
|
||||
EOT
|
||||
tags = join(",", ["Id", local.identifier, "Owner", local.owner])
|
||||
}
|
||||
}
|
||||
|
||||
resource "rancher2_cluster_v2" "rke2_cluster" {
|
||||
depends_on = [
|
||||
module.rancher,
|
||||
rancher2_bootstrap.authenticate,
|
||||
module.rancher,
|
||||
aws_route53_record.modified,
|
||||
rancher2_cloud_credential.aws,
|
||||
rancher2_machine_config_v2.core,
|
||||
rancher2_machine_config_v2.worker,
|
||||
]
|
||||
provider = rancher2.default
|
||||
name = "${local.project_name}-s1-cluster"
|
||||
kubernetes_version = local.rke2_version
|
||||
enable_network_policy = true
|
||||
rke_config {
|
||||
machine_pools {
|
||||
name = "${local.hostname_prefix}cp001"
|
||||
control_plane_role = true
|
||||
etcd_role = true
|
||||
worker_role = true
|
||||
quantity = 1
|
||||
cloud_credential_secret_name = rancher2_cloud_credential.aws.id
|
||||
machine_config {
|
||||
kind = rancher2_machine_config_v2.core.kind
|
||||
name = rancher2_machine_config_v2.core.name
|
||||
}
|
||||
}
|
||||
machine_pools {
|
||||
name = "${local.hostname_prefix}wk001"
|
||||
control_plane_role = true
|
||||
etcd_role = true
|
||||
worker_role = true
|
||||
quantity = 1
|
||||
cloud_credential_secret_name = rancher2_cloud_credential.aws.id
|
||||
machine_config {
|
||||
kind = rancher2_machine_config_v2.worker.kind
|
||||
name = rancher2_machine_config_v2.worker.name
|
||||
}
|
||||
}
|
||||
rotate_certificates {
|
||||
generation = 1
|
||||
}
|
||||
}
|
||||
timeouts {
|
||||
create = "120m" # 2 hours
|
||||
}
|
||||
}
|
||||
|
||||
resource "rancher2_cluster_sync" "sync" {
|
||||
depends_on = [
|
||||
module.rancher,
|
||||
rancher2_bootstrap.authenticate,
|
||||
module.rancher,
|
||||
aws_route53_record.modified,
|
||||
rancher2_cloud_credential.aws,
|
||||
rancher2_machine_config_v2.core,
|
||||
rancher2_machine_config_v2.worker,
|
||||
rancher2_cluster_v2.rke2_cluster,
|
||||
]
|
||||
provider = rancher2.default
|
||||
cluster_id = rancher2_cluster_v2.rke2_cluster.cluster_v1_id
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
output "kubeconfig" {
|
||||
value = module.rancher.kubeconfig
|
||||
description = <<-EOT
|
||||
The kubeconfig for the server.
|
||||
EOT
|
||||
sensitive = true
|
||||
}
|
||||
output "address" {
|
||||
value = module.rancher.address
|
||||
}
|
||||
# output "admin_token" {
|
||||
# value = module.rancher.admin_token
|
||||
# sensitive = true
|
||||
# }
|
||||
output "admin_password" {
|
||||
value = module.rancher.admin_password
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
# output "rke2_cluster_subnet" {
|
||||
# value = module.rke2_cluster_access.subnets[keys(module.rke2_cluster_access.subnets)[0]]
|
||||
# }
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
variable "key_name" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The name of an AWS key pair to use for SSH access to the instance.
|
||||
This key should already be added to your ssh agent for server authentication.
|
||||
EOT
|
||||
}
|
||||
variable "key" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The contents of an AWS key pair to use for SSH access to the instance.
|
||||
This is necessary for installing rke2 on the nodes and will be removed after installation.
|
||||
EOT
|
||||
}
|
||||
variable "identifier" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
A unique identifier for the project, this helps when generating names for infrastructure items."
|
||||
EOT
|
||||
}
|
||||
variable "owner" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The owner of the project, this helps when generating names for infrastructure items."
|
||||
EOT
|
||||
}
|
||||
variable "zone" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The Route53 DNS zone to deploy the cluster into.
|
||||
This is used to generate the DNS name for the cluster.
|
||||
The zone must already exist.
|
||||
EOT
|
||||
}
|
||||
variable "rke2_version" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The version of rke2 to install on the nodes.
|
||||
eg. v1.30.2+rke2r1
|
||||
EOT
|
||||
}
|
||||
variable "rancher_version" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The version of rancher to install on the rke2 cluster.
|
||||
EOT
|
||||
default = "2.9.2"
|
||||
}
|
||||
variable "file_path" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The path to the file containing the rke2 install script.
|
||||
EOT
|
||||
default = "./rke2"
|
||||
}
|
||||
variable "aws_access_key_id" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
AWS access key ID.
|
||||
EOT
|
||||
sensitive = true
|
||||
}
|
||||
variable "aws_secret_access_key" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
AWS secret key for EC2 services.
|
||||
EOT
|
||||
sensitive = true
|
||||
}
|
||||
variable "aws_region" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
AWS region EC2 services.
|
||||
EOT
|
||||
sensitive = true
|
||||
}
|
||||
variable "email" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
Email used for TLS certification registration.
|
||||
If left blank this will be <identifier>@<zone>.
|
||||
EOT
|
||||
default = ""
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
terraform {
|
||||
required_version = ">= 1.5.0, < 1.6"
|
||||
required_providers {
|
||||
local = {
|
||||
source = "hashicorp/local"
|
||||
version = ">= 2.4"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = ">= 3.5.1"
|
||||
}
|
||||
github = {
|
||||
source = "integrations/github"
|
||||
version = ">= 5.44"
|
||||
}
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = ">= 5.11"
|
||||
}
|
||||
http = {
|
||||
source = "hashicorp/http"
|
||||
version = ">= 3.4"
|
||||
}
|
||||
null = {
|
||||
source = "hashicorp/null"
|
||||
version = ">=3"
|
||||
}
|
||||
tls = {
|
||||
source = "hashicorp/tls"
|
||||
version = ">= 4.0"
|
||||
}
|
||||
acme = {
|
||||
source = "vancluever/acme"
|
||||
version = ">= 2.0"
|
||||
}
|
||||
cloudinit = {
|
||||
source = "hashicorp/cloudinit"
|
||||
version = ">= 2.3.3"
|
||||
}
|
||||
helm = {
|
||||
source = "hashicorp/helm"
|
||||
version = ">= 2.14"
|
||||
}
|
||||
rancher2 = {
|
||||
source = "rancher/rancher2"
|
||||
version = ">= 5.0.0, < 5.1"
|
||||
}
|
||||
kubernetes = {
|
||||
source = "hashicorp/kubernetes"
|
||||
version = ">= 2.31.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# provider "aws" {
|
||||
# default_tags {
|
||||
# tags = {
|
||||
# Id = local.identifier
|
||||
# Owner = local.owner
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
# provider "acme" {
|
||||
# server_url = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
# }
|
||||
|
||||
# provider "github" {}
|
||||
# provider "kubernetes" {} # make sure you set the env variable KUBE_CONFIG_PATH to local_file_path (file_path variable)
|
||||
# provider "helm" {} # make sure you set the env variable KUBE_CONFIG_PATH to local_file_path (file_path variable)
|
||||
|
||||
# provider "rancher2" {
|
||||
# alias = "authenticate"
|
||||
# bootstrap = true
|
||||
# api_url = "https://${local.domain}.${local.zone}"
|
||||
# timeout = "300s"
|
||||
# }
|
||||
|
||||
# resource "rancher2_bootstrap" "authenticate" {
|
||||
# provider = rancher2.authenticate
|
||||
# initial_password = module.rancher.admin_password
|
||||
# password = module.rancher.admin_password
|
||||
# token_update = true
|
||||
# token_ttl = 7200 # 2 hours
|
||||
# }
|
||||
|
||||
# provider "rancher2" {
|
||||
# alias = "default"
|
||||
# api_url = "https://${local.domain}.${local.zone}"
|
||||
# token_key = rancher2_bootstrap.authenticate.token
|
||||
# timeout = "300s"
|
||||
# }
|
||||
|
||||
# locals {
|
||||
# identifier = var.identifier
|
||||
# example = "basic"
|
||||
# project_name = "tf-${substr(md5(join("-", [local.example, local.identifier])), 0, 5)}"
|
||||
# username = local.project_name
|
||||
# domain = local.project_name
|
||||
# zone = var.zone
|
||||
# key_name = var.key_name
|
||||
# key = var.key
|
||||
# owner = var.owner
|
||||
# rke2_version = var.rke2_version
|
||||
# local_file_path = var.file_path
|
||||
# runner_ip = chomp(data.http.myip.response_body) # "runner" is the server running Terraform
|
||||
# rancher_version = var.rancher_version
|
||||
# rancher_helm_repository = "https://releases.rancher.com/server-charts/stable"
|
||||
# cert_manager_version = "v1.13.1"
|
||||
# os = "sle-micro-60"
|
||||
# }
|
||||
|
||||
# data "http" "myip" {
|
||||
# url = "https://ipinfo.io/ip"
|
||||
# }
|
||||
|
||||
# module "imported_rke2" {
|
||||
# source = "./modules/cluster"
|
||||
# }
|
||||
# module "rancher" {
|
||||
# source = "./modules/rancher"
|
||||
# }
|
||||
|
||||
# # test catalog entry
|
||||
# resource "rancher2_catalog" "foo" {
|
||||
# depends_on = [
|
||||
# module.rancher,
|
||||
# ]
|
||||
# provider = rancher2.default
|
||||
# name = "test"
|
||||
# url = "http://foo.com:8080"
|
||||
# }
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
cni: calico
|
||||
disable:
|
||||
- rke2-canal
|
||||
- rke2-kube-proxy
|
||||
|
|
@ -0,0 +1 @@
|
|||
cni: cilium
|
||||
|
|
@ -0,0 +1,389 @@
|
|||
|
||||
locals {
|
||||
# project
|
||||
identifier = var.identifier # this is a random unique string that can be used to identify resources in the cloud provider
|
||||
owner = var.owner
|
||||
project_name = var.project_name
|
||||
domain = var.domain
|
||||
zone = var.zone # DNS zone
|
||||
ip_family = var.ip_family
|
||||
skip_cert = var.skip_cert_creation
|
||||
|
||||
# access
|
||||
ssh_key_name = var.key_name
|
||||
ssh_key = trimspace(var.key)
|
||||
username = var.username
|
||||
runner_ip = var.runner_ip
|
||||
|
||||
#rke2
|
||||
rke2_version = var.rke2_version
|
||||
local_file_path = (
|
||||
var.file_path != "" ? (var.file_path == path.root ? "${abspath(path.root)}/rke2" : abspath(var.file_path)) :
|
||||
"${abspath(path.root)}/rke2"
|
||||
)
|
||||
install_method = var.install_method
|
||||
download = (local.install_method == "tar" ? "download" : "skip")
|
||||
cni = var.cni
|
||||
# tflint-ignore: terraform_unused_declarations
|
||||
ingress_controller = var.ingress_controller # not currently in use, TODO: add traefik functionality
|
||||
|
||||
cni_file = (local.cni == "cilium" ? "${path.root}/cilium.yaml" : (local.cni == "calico" ? "${path.root}/calico.yaml" : ""))
|
||||
cni_config = (local.cni_file != "" ? file(local.cni_file) : "")
|
||||
api_config = <<-EOT
|
||||
node-taint:
|
||||
- "CriticalAddonsOnly=true:NoExecute"
|
||||
disable-etcd: true
|
||||
${local.cni_config}
|
||||
EOT
|
||||
database_config = <<-EOT
|
||||
disable-apiserver: true
|
||||
disable-controller-manager: true
|
||||
disable-scheduler: true
|
||||
node-taint:
|
||||
- "CriticalAddonsOnly=true:NoExecute"
|
||||
EOT
|
||||
control_plane_config = <<-EOT
|
||||
node-taint:
|
||||
- "CriticalAddonsOnly=true:NoExecute"
|
||||
${local.cni_config}
|
||||
EOT
|
||||
all_in_one_config = <<-EOT
|
||||
${local.cni_config}
|
||||
EOT
|
||||
|
||||
ino = module.initial[keys(local.initial_node)[0]]
|
||||
subnets = local.ino.project_subnets
|
||||
node_configuration = var.node_configuration
|
||||
full_node_configs = { for key, node in local.node_configuration :
|
||||
key => {
|
||||
name = substr("${local.project_name}-${md5(key)}", 0, 25)
|
||||
domain = substr("${local.project_name}-${md5(key)}", 0, 25)
|
||||
indirect_access = (node.indirect_access ? "enable" : "skip")
|
||||
file_path = "${local.local_file_path}/${substr("${local.project_name}-${md5(key)}", 0, 25)}/data"
|
||||
path = "${local.local_file_path}/${substr("${local.project_name}-${md5(key)}", 0, 25)}"
|
||||
config = (
|
||||
strcontains(node.type, "all-in-one") ? local.all_in_one_config :
|
||||
strcontains(node.type, "control-plane") ? local.control_plane_config :
|
||||
strcontains(node.type, "api") ? local.api_config :
|
||||
strcontains(node.type, "database") ? local.database_config :
|
||||
"" # worker nodes don't need additional config
|
||||
)
|
||||
config_strategy = "merge"
|
||||
role = node.type
|
||||
type = (strcontains(node.type, "worker") ? "agent" : "server")
|
||||
size = node.size
|
||||
image = node.os
|
||||
prep_script = (
|
||||
strcontains(node.os, "sles") ? templatefile("${path.root}/suse_prep.sh", {
|
||||
install_method = local.install_method,
|
||||
ip_family = local.ip_family,
|
||||
image = node.os,
|
||||
}) :
|
||||
strcontains(node.os, "rhel") ? templatefile("${path.root}/rhel_prep.sh", {
|
||||
install_method = local.install_method,
|
||||
ip_family = local.ip_family,
|
||||
image = node.os,
|
||||
}) :
|
||||
strcontains(node.os, "ubuntu") ? templatefile("${path.root}/ubuntu_prep.sh", {
|
||||
install_method = local.install_method,
|
||||
ip_family = local.ip_family,
|
||||
image = node.os,
|
||||
}) :
|
||||
""
|
||||
)
|
||||
initial = node.initial
|
||||
workfolder = strcontains(node.os, "cis") ? "/var/tmp" : "/home/${local.username}"
|
||||
cloudinit_strategy = (node.os == "sle-micro-55" || node.os == "cis-rhel-8") ? "skip" : "default"
|
||||
# CIS images are not supported on IPv6 only deployments due to kernel modifications with how AWS IPv6 works (dhcpv6)
|
||||
# tflint-ignore: terraform_unused_declarations
|
||||
fail_cis_ipv6 = ((node.os == "rhel-8-cis" && local.ip_family == "ipv6") ? one([local.ip_family, "cis_ipv6_incompatible"]) : false)
|
||||
# Ubuntu images do not support rpm install method
|
||||
# tflint-ignore: terraform_unused_declarations
|
||||
fail_ubuntu_rpm = ((strcontains(node.os, "ubuntu") && local.install_method == "rpm") ? one([local.install_method, "ubuntu_rpm_incompatible"]) : false)
|
||||
}
|
||||
}
|
||||
target_groups = {
|
||||
kubectl = substr(lower("${local.project_name}-kubectl"), 0, 32)
|
||||
application-secure = substr(lower("${local.project_name}-application-secure"), 0, 32)
|
||||
application-insecure = substr(lower("${local.project_name}-application-insecure"), 0, 32)
|
||||
}
|
||||
initial_node = { for k, v in local.full_node_configs : k => v if v.initial == true }
|
||||
additional_nodes = {
|
||||
for k, v in local.full_node_configs :
|
||||
k => merge(
|
||||
v,
|
||||
tomap({ az = local.subnets[keys(local.subnets)[index(keys(local.full_node_configs), k) % length(local.subnets)]].availability_zone }),
|
||||
tomap({ subnet = local.subnets[keys(local.subnets)[index(keys(local.full_node_configs), k) % length(local.subnets)]].tags.Name })
|
||||
)
|
||||
if v.initial != true
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_availability_zones" "available" {
|
||||
state = "available"
|
||||
}
|
||||
|
||||
module "initial" {
|
||||
depends_on = [
|
||||
data.aws_availability_zones.available,
|
||||
]
|
||||
source = "rancher/rke2/aws"
|
||||
version = "1.1.11"
|
||||
for_each = local.initial_node
|
||||
project_use_strategy = "create"
|
||||
project_vpc_use_strategy = "create"
|
||||
project_vpc_name = "${local.project_name}-vpc"
|
||||
project_vpc_zones = data.aws_availability_zones.available.names
|
||||
project_vpc_type = local.ip_family
|
||||
project_vpc_public = local.ip_family == "ipv6" ? false : true # ipv6 addresses assigned by AWS are always public
|
||||
project_subnet_use_strategy = "create"
|
||||
project_subnet_names = [for z in data.aws_availability_zones.available.names : "${local.project_name}-subnet-${z}"]
|
||||
project_security_group_use_strategy = "create"
|
||||
project_security_group_name = "${local.project_name}-sg"
|
||||
project_security_group_type = "egress" # in the future we should allow this to be variable, but we need to figure out airgap first
|
||||
project_load_balancer_use_strategy = "create"
|
||||
project_load_balancer_name = "${local.project_name}-lb"
|
||||
project_load_balancer_access_cidrs = {
|
||||
"kubectl" = {
|
||||
port = "6443"
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["${local.runner_ip}/128"] : ["${local.runner_ip}/32"])
|
||||
target_name = local.target_groups.kubectl
|
||||
}
|
||||
"application-secure" = {
|
||||
port = "443"
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["${local.runner_ip}/128"] : ["${local.runner_ip}/32"])
|
||||
target_name = local.target_groups.application-secure
|
||||
}
|
||||
"application-insecure" = {
|
||||
port = "80"
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["${local.runner_ip}/128"] : ["${local.runner_ip}/32"])
|
||||
target_name = local.target_groups.application-insecure
|
||||
}
|
||||
}
|
||||
project_domain_use_strategy = "create"
|
||||
project_domain = local.domain
|
||||
project_domain_zone = local.zone
|
||||
project_domain_cert_use_strategy = (local.skip_cert ? "skip" : "create")
|
||||
server_use_strategy = "create"
|
||||
server_name = each.value.name
|
||||
server_type = each.value.size
|
||||
server_availability_zone = data.aws_availability_zones.available.names[0]
|
||||
server_image_use_strategy = "find"
|
||||
server_image_type = each.value.image
|
||||
server_ip_family = local.ip_family
|
||||
server_cloudinit_use_strategy = each.value.cloudinit_strategy
|
||||
server_indirect_access_use_strategy = each.value.indirect_access
|
||||
server_load_balancer_target_groups = values(local.target_groups)
|
||||
server_direct_access_use_strategy = "ssh" # configure the servers for direct ssh access
|
||||
#https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-requirements/port-requirements#rancher-aws-ec2-security-group
|
||||
server_access_addresses = { # you must include ssh access here to enable setup
|
||||
ssh = {
|
||||
port = 22 # allow runner access on ssh port
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["${local.runner_ip}/128"] : ["${local.runner_ip}/32"])
|
||||
}
|
||||
api = {
|
||||
port = 6443 # allow runner IP access to API
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["${local.runner_ip}/128"] : ["${local.runner_ip}/32"])
|
||||
}
|
||||
application-secure = {
|
||||
port = 443 # allow runner IP access to https
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["${local.runner_ip}/128"] : ["${local.runner_ip}/32"])
|
||||
}
|
||||
application-insecure = {
|
||||
port = 80 # allow runner IP access to http
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["${local.runner_ip}/128"] : ["${local.runner_ip}/32"])
|
||||
}
|
||||
}
|
||||
#server_load_balancer_target_groups = values(local.target_groups) first node is an etcd node, not an API node, we use the internal LB for that
|
||||
server_user = {
|
||||
user = local.username
|
||||
aws_keypair_use_strategy = "select"
|
||||
ssh_key_name = local.ssh_key_name
|
||||
public_ssh_key = local.ssh_key
|
||||
user_workfolder = each.value.workfolder
|
||||
timeout = 10
|
||||
}
|
||||
server_add_domain = false
|
||||
server_domain_name = each.value.domain
|
||||
server_domain_zone = local.zone
|
||||
server_add_eip = false
|
||||
install_use_strategy = local.install_method
|
||||
local_file_use_strategy = local.download
|
||||
local_file_path = each.value.file_path
|
||||
install_rke2_version = local.rke2_version
|
||||
install_rpm_channel = "stable"
|
||||
install_remote_file_path = "${each.value.workfolder}/rke2"
|
||||
install_role = each.value.type
|
||||
install_start = true
|
||||
install_prep_script = each.value.prep_script
|
||||
install_start_timeout = 10
|
||||
config_use_strategy = each.value.config_strategy
|
||||
config_join_strategy = "skip"
|
||||
config_default_name = "50-default-config.yaml"
|
||||
config_supplied_name = "51-config.yaml"
|
||||
config_supplied_content = each.value.config
|
||||
retrieve_kubeconfig = true
|
||||
}
|
||||
|
||||
# There are many ways to orchestrate Terraform configurations with the goal of breaking it down
|
||||
# In this example I am using Terraform resources to orchestrate Terraform
|
||||
# I felt this was the best way to accomplish the goal without incurring additional dependencies
|
||||
# The configuration we are orchestrating isn't hard coded, we will be generating the config from a templatefile
|
||||
# see "local_file.cp_main"
|
||||
resource "terraform_data" "path" {
|
||||
depends_on = [
|
||||
module.initial,
|
||||
]
|
||||
for_each = local.additional_nodes
|
||||
triggers_replace = {
|
||||
initial_token = local.ino.join_token
|
||||
initial_url = local.ino.join_url
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = <<-EOT
|
||||
install -d ${each.value.path}
|
||||
cp ${abspath(path.module)}/variables.tf ${each.value.path}
|
||||
cp ${abspath(path.module)}/versions.tf ${each.value.path}
|
||||
EOT
|
||||
}
|
||||
}
|
||||
resource "local_file" "main" {
|
||||
depends_on = [
|
||||
module.initial,
|
||||
terraform_data.path,
|
||||
]
|
||||
for_each = local.additional_nodes
|
||||
content = templatefile(
|
||||
"${abspath(path.module)}/main.tf.tftpl",
|
||||
{
|
||||
project_security_group_name = local.ino.project_security_group.name
|
||||
project_subnets = jsonencode(local.ino.project_subnets)
|
||||
join_url = local.ino.join_url
|
||||
join_token = local.ino.join_token
|
||||
cluster_cidr = jsonencode(local.ino.cluster_cidr)
|
||||
service_cidr = jsonencode(local.ino.service_cidr)
|
||||
server_info = jsonencode(each.value)
|
||||
role = each.value.role # worker, control-plane, database, all-in-one, etc
|
||||
target_groups = jsonencode(local.target_groups)
|
||||
}
|
||||
)
|
||||
filename = "${each.value.path}/main.tf"
|
||||
}
|
||||
resource "local_file" "inputs" {
|
||||
depends_on = [
|
||||
module.initial,
|
||||
terraform_data.path,
|
||||
local_file.main,
|
||||
]
|
||||
for_each = local.additional_nodes
|
||||
content = <<-EOT
|
||||
identifier = "${local.identifier}"
|
||||
owner = "${local.owner}"
|
||||
project_name = "${local.project_name}"
|
||||
domain = "${local.domain}"
|
||||
zone = "${local.zone}"
|
||||
key_name = "${local.ssh_key_name}"
|
||||
key = "${local.ssh_key}"
|
||||
username = "${local.username}"
|
||||
runner_ip = "${local.runner_ip}"
|
||||
rke2_version = "${local.rke2_version}"
|
||||
file_path = "${each.value.file_path}"
|
||||
install_method = "${local.install_method}"
|
||||
cni = "${local.cni}"
|
||||
ip_family = "${local.ip_family}"
|
||||
ingress_controller = "${local.ingress_controller}"
|
||||
EOT
|
||||
filename = "${each.value.path}/inputs.tfvars"
|
||||
}
|
||||
|
||||
resource "terraform_data" "create" {
|
||||
depends_on = [
|
||||
module.initial,
|
||||
terraform_data.path,
|
||||
local_file.main,
|
||||
local_file.inputs,
|
||||
]
|
||||
for_each = local.additional_nodes
|
||||
triggers_replace = {
|
||||
initial = local.ino.join_url
|
||||
path = each.value.path
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = <<-EOT
|
||||
cd ${self.triggers_replace.path}
|
||||
TF_DATA_DIR="${self.triggers_replace.path}"
|
||||
terraform init -upgrade=true
|
||||
EXITCODE=1
|
||||
ATTEMPTS=0
|
||||
MAX=3
|
||||
while [ $EXITCODE -gt 0 ] && [ $ATTEMPTS -lt $MAX ]; do
|
||||
echo "Starting attempt $ATTEMPTS..."
|
||||
timeout 3600 terraform apply -var-file="inputs.tfvars" -auto-approve -state="${self.triggers_replace.path}/tfstate"
|
||||
EXITCODE=$?
|
||||
ATTEMPTS=$((ATTEMPTS + 1))
|
||||
echo "Exit code $EXITCODE..."
|
||||
done
|
||||
exit $EXITCODE
|
||||
EOT
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
# warning! this is only triggered on destroy, not refresh/taint
|
||||
when = destroy
|
||||
command = <<-EOT
|
||||
cd ${self.triggers_replace.path}
|
||||
TF_DATA_DIR="${self.triggers_replace.path}"
|
||||
EXITCODE=1
|
||||
ATTEMPTS=0
|
||||
MAX=3
|
||||
while [ $EXITCODE -gt 0 ] && [ $ATTEMPTS -lt $MAX ]; do
|
||||
echo "Starting attempt $ATTEMPTS..."
|
||||
timeout 3600 terraform destroy -var-file="inputs.tfvars" -no-color -auto-approve -state="${self.triggers_replace.path}/tfstate"
|
||||
EXITCODE=$?
|
||||
ATTEMPTS=$((ATTEMPTS + 1))
|
||||
echo "Exit code $EXITCODE..."
|
||||
done
|
||||
exit $EXITCODE
|
||||
EOT
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "kubeconfig" {
|
||||
depends_on = [
|
||||
module.initial,
|
||||
terraform_data.path,
|
||||
local_file.main,
|
||||
local_file.inputs,
|
||||
terraform_data.create,
|
||||
]
|
||||
content = local.ino.kubeconfig
|
||||
filename = "${local.local_file_path}/kubeconfig"
|
||||
}
|
||||
# commented for performance, leaving to show how you can export the state if necessary
|
||||
# data "terraform_remote_state" "additional_node_states" {
|
||||
# depends_on = [
|
||||
# module.initial,
|
||||
# terraform_data.path,
|
||||
# local_file.main,
|
||||
# local_file.inputs,
|
||||
# terraform_data.create,
|
||||
# ]
|
||||
# for_each = local.additional_nodes
|
||||
# backend = "local"
|
||||
# config = {
|
||||
# path = "${each.value.path}/tfstate"
|
||||
# }
|
||||
# }
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
# control plane terraform templatefile
|
||||
|
||||
provider "aws" {
|
||||
default_tags {
|
||||
tags = {
|
||||
Id = local.identifier
|
||||
Owner = local.owner
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
# tflint-ignore: terraform_unused_declarations
|
||||
ingress_controller = var.ingress_controller # not currently in use, TODO: add traefik functionality
|
||||
identifier = var.identifier # this is a random unique string that can be used to identify resources in the cloud provider
|
||||
owner = var.owner
|
||||
project_name = var.project_name
|
||||
username = var.username
|
||||
ip_family = var.ip_family
|
||||
runner_ip = var.runner_ip
|
||||
ssh_key = var.key
|
||||
ssh_key_name = var.key_name
|
||||
domain = var.domain
|
||||
zone = var.zone # DNS zone
|
||||
|
||||
rke2_version = var.rke2_version
|
||||
install_method = var.install_method
|
||||
download = (local.install_method == "tar" ? "download" : "skip")
|
||||
|
||||
server_info = jsondecode(<<-EOT
|
||||
${server_info}
|
||||
EOT
|
||||
)
|
||||
install_prep_script = local.server_info.prep_script
|
||||
local_file_path = local.server_info.file_path
|
||||
workfolder = local.server_info.workfolder
|
||||
cloudinit_strategy = local.server_info.cloudinit_strategy
|
||||
config = local.server_info.config
|
||||
|
||||
target_groups = jsondecode(<<-EOT
|
||||
${target_groups}
|
||||
EOT
|
||||
)
|
||||
cluster_cidr = jsondecode(<<-EOT
|
||||
${cluster_cidr}
|
||||
EOT
|
||||
)
|
||||
service_cidr = jsondecode(<<-EOT
|
||||
${service_cidr}
|
||||
EOT
|
||||
)
|
||||
}
|
||||
|
||||
data "http" "myip" {
|
||||
url = "https://ipinfo.io/ip"
|
||||
}
|
||||
|
||||
module "${role}_node" {
|
||||
source = "rancher/rke2/aws"
|
||||
version = "1.1.11"
|
||||
project_use_strategy = "skip"
|
||||
project_domain = local.domain
|
||||
project_domain_zone = local.zone
|
||||
server_use_strategy = "create"
|
||||
server_name = local.server_info.name
|
||||
server_type = local.server_info.size
|
||||
server_security_group_name = "${project_security_group_name}" # should always match project security group
|
||||
server_availability_zone = local.server_info.az
|
||||
server_image_use_strategy = "find"
|
||||
server_image_type = local.server_info.image
|
||||
server_ip_family = local.ip_family
|
||||
server_cloudinit_use_strategy = local.server_info.cloudinit_strategy
|
||||
server_indirect_access_use_strategy = local.server_info.indirect_access
|
||||
server_load_balancer_target_groups = values(local.target_groups)
|
||||
server_subnet_name = local.server_info.subnet
|
||||
server_direct_access_use_strategy = "ssh" # configure the servers for direct ssh access
|
||||
# remember these are external access objects, internal access is enabled by default
|
||||
server_access_addresses = { # you must include ssh access here to enable setup
|
||||
ssh = {
|
||||
port = 22 # allow access on ssh port
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["$${local.runner_ip}/128"] : ["$${local.runner_ip}/32"])
|
||||
}
|
||||
api = {
|
||||
port = 6443 # allow runner IP access to API
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["$${local.runner_ip}/128"] : ["$${local.runner_ip}/32"])
|
||||
}
|
||||
application-secure = {
|
||||
port = 443 # allow runner IP access to https
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["$${local.runner_ip}/128"] : ["$${local.runner_ip}/32"])
|
||||
}
|
||||
application-insecure = {
|
||||
port = 80 # allow runner IP access to http
|
||||
protocol = "tcp"
|
||||
ip_family = (local.ip_family == "ipv6" ? "ipv6" : "ipv4")
|
||||
cidrs = (local.ip_family == "ipv6" ? ["$${local.runner_ip}/128"] : ["$${local.runner_ip}/32"])
|
||||
}
|
||||
}
|
||||
server_user = {
|
||||
user = local.username
|
||||
aws_keypair_use_strategy = "select"
|
||||
ssh_key_name = local.ssh_key_name
|
||||
public_ssh_key = local.ssh_key
|
||||
user_workfolder = local.server_info.workfolder
|
||||
timeout = 10
|
||||
}
|
||||
server_add_domain = false
|
||||
server_domain_name = local.server_info.domain
|
||||
server_domain_zone = local.zone
|
||||
server_add_eip = false
|
||||
install_use_strategy = local.install_method
|
||||
local_file_use_strategy = local.download
|
||||
local_file_path = local.server_info.file_path
|
||||
install_rke2_version = local.rke2_version
|
||||
install_rpm_channel = "stable"
|
||||
install_remote_file_path = "$${local.server_info.workfolder}/rke2"
|
||||
install_role = local.server_info.type
|
||||
install_start = true
|
||||
install_prep_script = local.server_info.prep_script
|
||||
install_start_timeout = 10
|
||||
config_use_strategy = local.server_info.config_strategy
|
||||
config_join_strategy = "join"
|
||||
config_join_url = "${join_url}"
|
||||
config_join_token = "${join_token}"
|
||||
config_cluster_cidr = local.cluster_cidr
|
||||
config_service_cidr = local.service_cidr
|
||||
config_supplied_content = local.server_info.config
|
||||
config_supplied_name = "51-config.yaml"
|
||||
retrieve_kubeconfig = false # use initial
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
output "kubeconfig" {
|
||||
value = module.initial[0].kubeconfig
|
||||
description = "Kubernetes config file contents for the cluster."
|
||||
sensitive = true
|
||||
}
|
||||
output "api" {
|
||||
value = yamldecode(module.initial[0].kubeconfig).clusters[0].cluster.server
|
||||
description = "Address to use to connect to the cluster's API service."
|
||||
sensitive = true
|
||||
}
|
||||
output "cert" {
|
||||
value = module.initial[0].project_domain_tls_certificate
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
output "kubeconfig" {
|
||||
value = local.ino.kubeconfig
|
||||
description = "Kubernetes config file contents for the cluster."
|
||||
sensitive = true
|
||||
}
|
||||
output "api" {
|
||||
value = yamldecode(local.ino.kubeconfig).clusters[0].cluster.server
|
||||
description = "Address to use to connect to the cluster's API service."
|
||||
sensitive = true
|
||||
}
|
||||
output "cert" {
|
||||
value = local.ino.project_domain_tls_certificate
|
||||
description = "Information about the certificate that was generated with the domain"
|
||||
sensitive = true
|
||||
}
|
||||
# commented for performance, leaving to show how you can export the state if necessary
|
||||
# output "additional_node_states" {
|
||||
# value = data.terraform_remote_state.additional_node_states
|
||||
# description = "The states for the orchestrated modules which produce nodes."
|
||||
# sensitive = true
|
||||
# }
|
||||
output "vpc" {
|
||||
value = module.initial[keys(local.initial_node)[0]].project_vpc
|
||||
}
|
||||
output "subnets" {
|
||||
value = module.initial[keys(local.initial_node)[0]].project_subnets
|
||||
}
|
||||
output "join_url" {
|
||||
value = local.ino.join_url
|
||||
}
|
||||
output "initial_node_private_ip" {
|
||||
value = replace(replace(local.ino.join_url, ":9345", ""), "https://", "")
|
||||
}
|
||||
output "project_domain_object" {
|
||||
value = module.initial[keys(local.initial_node)[0]].project_domain_object
|
||||
}
|
||||
output "project_security_group" {
|
||||
value = module.initial[keys(local.initial_node)[0]].project_security_group
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run as root" >&2
|
||||
exit 1
|
||||
fi
|
||||
#https://docs.rke2.io/known_issues
|
||||
|
||||
systemctl disable --now firewalld || true
|
||||
systemctl stop firewalld || true
|
||||
|
||||
systemctl stop nm-cloud-setup.service
|
||||
systemctl disable nm-cloud-setup.service
|
||||
systemctl stop nm-cloud-setup.timer
|
||||
systemctl disable nm-cloud-setup.timer
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Ensure the script is run as root
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run as root" >&2
|
||||
exit 1
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
if [ "rpm" = "${install_method}" ]; then
|
||||
wget https://download.opensuse.org/distribution/leap/15.6/repo/oss/repodata/repomd.xml.key || true
|
||||
rpm --import repomd.xml.key || true
|
||||
zypper ar -f https://download.opensuse.org/distribution/leap/15.6/repo/oss/ leap-oss || true
|
||||
zypper install -y curl
|
||||
|
||||
rpm --import https://download.opensuse.org/repositories/security:/SELinux_legacy/15.5/repodata/repomd.xml.key || true
|
||||
zypper ar -f https://download.opensuse.org/repositories/security:/SELinux_legacy/15.5/security:SELinux_legacy.repo || true
|
||||
rpm --import https://rpm.rancher.io/public.key || true
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
if [ "ipv6" = "${ip_family}" ]; then
|
||||
IPV6="$(ip -6 a show eth0 | grep inet6 | head -n1 | awk '{ print $2 }' | awk -F/ '{ print $1 }')"
|
||||
IPV6_GW="$(echo "$IPV6" | awk -F: '{gw=$1":"$2":"$3":"$4"::1"; print gw}')"
|
||||
|
||||
cat > /etc/sysconfig/network/ifcfg-eth0 << EOT
|
||||
STARTMODE='auto'
|
||||
BOOTPROTO='static'
|
||||
IPADDR="$IPV6"
|
||||
PREFIXLEN='64'
|
||||
DHCLIENT6_MODE='info'
|
||||
EOT
|
||||
|
||||
[ ! -f /etc/sysconfig/network/routes ] && touch /etc/sysconfig/network/routes
|
||||
echo "default $IPV6_GW - -" >> /etc/sysconfig/network/routes
|
||||
|
||||
CONFIG_FILE="/etc/sysconfig/network/config"
|
||||
IPV6_DNS1="2001:4860:4860::8888"
|
||||
IPV6_DNS2="2606:4700:4700::1111"
|
||||
|
||||
|
||||
sed -i "s|^NETCONFIG_DNS_STATIC_SERVERS=.*|NETCONFIG_DNS_STATIC_SERVERS=\"$IPV6_DNS1 $IPV6_DNS2\"|" "$CONFIG_FILE"
|
||||
sed -i "s|^NETWORKMANAGER_DISABLE_IPV6=.*|NETWORKMANAGER_DISABLE_IPV6=\"no\"|" "$CONFIG_FILE"
|
||||
|
||||
grep -q "^NETCONFIG_DNS_STATIC_SERVERS=" "$CONFIG_FILE" || echo "NETCONFIG_DNS_STATIC_SERVERS=\"$IPV6_DNS1 $IPV6_DNS2\"" >> "$CONFIG_FILE"
|
||||
grep -q "^NETWORKMANAGER_DISABLE_IPV6=" "$CONFIG_FILE" || echo "NETWORKMANAGER_DISABLE_IPV6=\"no\"" >> "$CONFIG_FILE"
|
||||
|
||||
netconfig update -f
|
||||
|
||||
echo "Updated /etc/resolv.conf:"
|
||||
cat /etc/resolv.conf
|
||||
|
||||
echo "Testing IPv6 DNS resolution:"
|
||||
dig AAAA google.com
|
||||
fi
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run as root" >&2
|
||||
exit 1
|
||||
fi
|
||||
#https://docs.rke2.io/known_issues
|
||||
systemctl disable --now firewalld || true
|
||||
systemctl stop firewalld || true
|
||||
|
||||
if [ -d /etc/NetworkManager ]; then
|
||||
touch /etc/NetworkManager/conf.d/rke2-canal.conf
|
||||
cat <<EOF > /etc/NetworkManager/conf.d/rke2-canal.conf
|
||||
[keyfile]
|
||||
unmanaged-devices=interface-name:cali*;interface-name:flannel*
|
||||
EOF
|
||||
systemctl reload NetworkManager || true
|
||||
fi
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
# project
|
||||
variable "identifier" {
|
||||
type = string
|
||||
description = "A random alphanumeric string that is unique and less than 10 characters."
|
||||
}
|
||||
variable "owner" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
An identifier for the person or group responsible for the resources created.
|
||||
A tag 'Owner' will be added to the servers with this value.
|
||||
EOT
|
||||
}
|
||||
variable "project_name" {
|
||||
type = string
|
||||
description = "The name for the project, resources will be given a tag 'Name' with this value as a prefix."
|
||||
}
|
||||
variable "domain" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The dns domain for the project, the zone must already exist in AWS Route53.
|
||||
Example: test.example.com where example.com is a zone that is already available.
|
||||
EOT
|
||||
}
|
||||
variable "zone" {
|
||||
type = string
|
||||
description = "The dns zone to add domains under, must already exist in AWS Route53."
|
||||
}
|
||||
# access
|
||||
variable "key_name" {
|
||||
type = string
|
||||
description = "The name of an ssh key that already exists in AWS of that you want to create."
|
||||
}
|
||||
variable "key" {
|
||||
type = string
|
||||
description = "The content of an ssh key for server access. The key must be loaded into the running ssh agent."
|
||||
}
|
||||
variable "username" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The username to add to the server for Terraform to configure it.
|
||||
This user will have passwordless sudo, but login only from the 'runner_ip' address
|
||||
and only with the appropriate key (which must be in your ssh agent).
|
||||
EOT
|
||||
}
|
||||
variable "runner_ip" {
|
||||
type = string
|
||||
description = "The IP address of the computer running terraform."
|
||||
}
|
||||
# rke2
|
||||
variable "rke2_version" {
|
||||
type = string
|
||||
description = "The rke2 version to install."
|
||||
}
|
||||
variable "file_path" {
|
||||
type = string
|
||||
description = "The local file path to stage or retrieve files."
|
||||
}
|
||||
variable "install_method" {
|
||||
type = string
|
||||
description = "The method used to install RKE2 on the nodes. Must be either 'tar' or 'rpm'."
|
||||
}
|
||||
variable "cni" {
|
||||
type = string
|
||||
description = "Which CNI configuration file to add."
|
||||
}
|
||||
variable "node_configuration" {
|
||||
type = map(object({
|
||||
type = string
|
||||
size = string
|
||||
os = string
|
||||
indirect_access = bool
|
||||
initial = bool
|
||||
}))
|
||||
description = <<-EOT
|
||||
A map of configuration options for the nodes to constitute the cluster.
|
||||
Only one node should have the "initial" attribute set to true.
|
||||
Be careful which node you decide to start the cluster,
|
||||
it must host the database for others to be able to join properly.
|
||||
There are 5 types of node: 'all-in-one', 'control-plane', 'worker', 'database', 'api'.
|
||||
'all-in-one' nodes have all roles (control-plane, worker, etcd)
|
||||
'control-plane' nodes have the api (control-plane) and database (etcd) roles
|
||||
'worker' nodes have just the 'worker' role
|
||||
'database' nodes have only the database (etcd) role
|
||||
'api' nodes have only the api (control-plane) server role
|
||||
By default we will set taints to prevent non-component workloads
|
||||
from running on database, api, and control-plane nodes.
|
||||
Size correlates to the server size options from the server module:
|
||||
https://github.com/rancher/terraform-aws-server/blob/main/modules/server/types.tf
|
||||
We recommend using the size nodes that best fit your use case:
|
||||
https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-requirements#rke2-kubernetes
|
||||
OS correlates to the server image options from the server module:
|
||||
https://github.com/rancher/terraform-aws-server/blob/main/modules/image/types.tf
|
||||
We recommend using the same os for all servers, we don't currently test for clusters with mixed OS types.
|
||||
Indirect access refers to how the cluster will be load balanced,
|
||||
some admins are ok with every server in the cluster responding to inbound requests since the built in proxy will redirect,
|
||||
but that isn't always the best choice since some nodes (like database nodes and secure workers)
|
||||
are better to restrict to internal access only.
|
||||
Setting this value to true will allow the network load balancer to direct traffic to the node.
|
||||
Setting this value to false will prevent the load balancer from directing traffic to the node.
|
||||
EOT
|
||||
default = {
|
||||
"initial" = {
|
||||
type = "all-in-one"
|
||||
size = "medium"
|
||||
os = "sle-micro-60"
|
||||
indirect_access = true
|
||||
initial = true
|
||||
}
|
||||
}
|
||||
}
|
||||
variable "ip_family" {
|
||||
type = string
|
||||
description = "The IP family to use. Must be 'ipv4', 'ipv6', or 'dualstack'."
|
||||
}
|
||||
variable "ingress_controller" {
|
||||
type = string
|
||||
description = "The ingress controller to use. Must be 'nginx' or 'traefik'. Currently only supports 'nginx'."
|
||||
}
|
||||
variable "skip_cert_creation" {
|
||||
type = bool
|
||||
description = "Skip the generation of a certificate, useful when configuring cert manager."
|
||||
default = false
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
terraform {
|
||||
required_version = ">= 1.5.7, < 1.6"
|
||||
required_providers {
|
||||
local = {
|
||||
source = "hashicorp/local"
|
||||
version = ">= 2.4"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = ">= 3.5.1"
|
||||
}
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = ">= 5.11"
|
||||
}
|
||||
http = {
|
||||
source = "hashicorp/http"
|
||||
version = ">= 3.4"
|
||||
}
|
||||
acme = {
|
||||
source = "vancluever/acme"
|
||||
version = ">= 2.0"
|
||||
}
|
||||
github = {
|
||||
source = "integrations/github"
|
||||
version = ">= 6.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
locals {
|
||||
identifier = var.identifier
|
||||
example = "basic"
|
||||
project_name = "tf-${substr(md5(join("-", [local.example, local.identifier])), 0, 5)}"
|
||||
username = local.project_name
|
||||
domain = local.project_name
|
||||
zone = var.zone
|
||||
key_name = var.key_name
|
||||
key = var.key
|
||||
owner = var.owner
|
||||
rke2_version = var.rke2_version
|
||||
local_file_path = var.file_path
|
||||
runner_ip = chomp(data.http.myip.response_body) # "runner" is the server running Terraform
|
||||
rancher_version = var.rancher_version
|
||||
rancher_helm_repository = "https://releases.rancher.com/server-charts/stable"
|
||||
cert_manager_version = "v1.13.1"
|
||||
os = "sle-micro-60"
|
||||
}
|
||||
|
||||
data "http" "myip" {
|
||||
url = "https://ipinfo.io/ip"
|
||||
}
|
||||
|
||||
module "rancher" {
|
||||
source = "../../../../"
|
||||
# project
|
||||
identifier = local.identifier
|
||||
owner = local.owner
|
||||
project_name = local.project_name
|
||||
domain = local.domain
|
||||
zone = local.zone
|
||||
# access
|
||||
key_name = local.key_name
|
||||
key = local.key
|
||||
username = local.username
|
||||
admin_ip = local.runner_ip
|
||||
# rke2
|
||||
rke2_version = local.rke2_version
|
||||
local_file_path = local.local_file_path
|
||||
install_method = "rpm" # rpm only for now, need to figure out local helm chart installs otherwise
|
||||
cni = "canal"
|
||||
node_configuration = {
|
||||
"rancher" = {
|
||||
type = "all-in-one"
|
||||
size = "medium"
|
||||
os = local.os
|
||||
indirect_access = true
|
||||
initial = true
|
||||
}
|
||||
}
|
||||
# rancher
|
||||
cert_manager_version = local.cert_manager_version
|
||||
rancher_version = local.rancher_version
|
||||
rancher_helm_repository = local.rancher_helm_repository
|
||||
}
|
||||
|
||||
# test catalog entry
|
||||
resource "rancher2_catalog" "foo" {
|
||||
depends_on = [
|
||||
module.rancher,
|
||||
]
|
||||
provider = rancher2.default
|
||||
name = "test"
|
||||
url = "http://foo.com:8080"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
output "kubeconfig" {
|
||||
value = module.rancher.kubeconfig
|
||||
description = <<-EOT
|
||||
The kubeconfig for the server.
|
||||
EOT
|
||||
sensitive = true
|
||||
}
|
||||
output "address" {
|
||||
value = module.rancher.address
|
||||
}
|
||||
output "admin_token" {
|
||||
value = module.rancher.admin_token
|
||||
sensitive = true
|
||||
}
|
||||
output "admin_password" {
|
||||
value = module.rancher.admin_password
|
||||
sensitive = true
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
variable "key_name" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The name of an AWS key pair to use for SSH access to the instance.
|
||||
This key should already be added to your ssh agent for server authentication.
|
||||
EOT
|
||||
}
|
||||
variable "key" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The contents of an AWS key pair to use for SSH access to the instance.
|
||||
This is necessary for installing rke2 on the nodes and will be removed after installation.
|
||||
EOT
|
||||
}
|
||||
variable "identifier" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
A unique identifier for the project, this helps when generating names for infrastructure items."
|
||||
EOT
|
||||
}
|
||||
variable "owner" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The owner of the project, this helps when generating names for infrastructure items."
|
||||
EOT
|
||||
}
|
||||
variable "zone" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The Route53 DNS zone to deploy the cluster into.
|
||||
This is used to generate the DNS name for the cluster.
|
||||
The zone must already exist.
|
||||
EOT
|
||||
}
|
||||
variable "rke2_version" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The version of rke2 to install on the nodes.
|
||||
EOT
|
||||
}
|
||||
variable "rancher_version" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The version of rancher to install on the rke2 cluster.
|
||||
EOT
|
||||
default = "2.9.1"
|
||||
}
|
||||
variable "file_path" {
|
||||
type = string
|
||||
description = <<-EOT
|
||||
The path to the file containing the rke2 install script.
|
||||
EOT
|
||||
default = "./rke2"
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
terraform {
|
||||
required_version = ">= 1.5.0, < 1.6"
|
||||
required_providers {
|
||||
local = {
|
||||
source = "hashicorp/local"
|
||||
version = ">= 2.4"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = ">= 3.5.1"
|
||||
}
|
||||
github = {
|
||||
source = "integrations/github"
|
||||
version = ">= 5.44"
|
||||
}
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = ">= 5.11"
|
||||
}
|
||||
http = {
|
||||
source = "hashicorp/http"
|
||||
version = ">= 3.4"
|
||||
}
|
||||
null = {
|
||||
source = "hashicorp/null"
|
||||
version = ">=3"
|
||||
}
|
||||
tls = {
|
||||
source = "hashicorp/tls"
|
||||
version = ">= 4.0"
|
||||
}
|
||||
acme = {
|
||||
source = "vancluever/acme"
|
||||
version = ">= 2.0"
|
||||
}
|
||||
cloudinit = {
|
||||
source = "hashicorp/cloudinit"
|
||||
version = ">= 2.3.3"
|
||||
}
|
||||
helm = {
|
||||
source = "hashicorp/helm"
|
||||
version = ">= 2.14"
|
||||
}
|
||||
rancher2 = {
|
||||
source = "rancher/rancher2"
|
||||
version = ">= 4.1.0, < 5.0"
|
||||
}
|
||||
kubernetes = {
|
||||
source = "hashicorp/kubernetes"
|
||||
version = ">= 2.31.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# output "kubeconfig" {
|
||||
# value = module.rancher.kubeconfig
|
||||
# description = <<-EOT
|
||||
# The kubeconfig for the server.
|
||||
# EOT
|
||||
# sensitive = true
|
||||
# }
|
||||
# output "address" {
|
||||
# value = module.rancher.address
|
||||
# }
|
||||
# output "admin_token" {
|
||||
# value = module.rancher.admin_token
|
||||
# sensitive = true
|
||||
# }
|
||||
# output "admin_password" {
|
||||
# value = module.rancher.admin_password
|
||||
# sensitive = true
|
||||
# }
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
# variable "key_name" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# The name of an AWS key pair to use for SSH access to the instance.
|
||||
# This key should already be added to your ssh agent for server authentication.
|
||||
# EOT
|
||||
# }
|
||||
# variable "key" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# The contents of an AWS key pair to use for SSH access to the instance.
|
||||
# This is necessary for installing rke2 on the nodes and will be removed after installation.
|
||||
# EOT
|
||||
# }
|
||||
# variable "identifier" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# A unique identifier for the project, this helps when generating names for infrastructure items."
|
||||
# EOT
|
||||
# }
|
||||
# variable "owner" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# The owner of the project, this helps when generating names for infrastructure items."
|
||||
# EOT
|
||||
# }
|
||||
# variable "zone" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# The Route53 DNS zone to deploy the cluster into.
|
||||
# This is used to generate the DNS name for the cluster.
|
||||
# The zone must already exist.
|
||||
# EOT
|
||||
# }
|
||||
# variable "rke2_version" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# The version of rke2 to install on the nodes.
|
||||
# EOT
|
||||
# }
|
||||
# variable "rancher_version" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# The version of rancher to install on the rke2 cluster.
|
||||
# EOT
|
||||
# default = "2.9.1"
|
||||
# }
|
||||
# variable "file_path" {
|
||||
# type = string
|
||||
# description = <<-EOT
|
||||
# The path to the file containing the rke2 install script.
|
||||
# EOT
|
||||
# default = "./rke2"
|
||||
# }
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
terraform {
|
||||
required_version = ">= 1.5.0, < 1.6"
|
||||
required_providers {
|
||||
local = {
|
||||
source = "hashicorp/local"
|
||||
version = ">= 2.4"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = ">= 3.5.1"
|
||||
}
|
||||
github = {
|
||||
source = "integrations/github"
|
||||
version = ">= 5.44"
|
||||
}
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = ">= 5.11"
|
||||
}
|
||||
http = {
|
||||
source = "hashicorp/http"
|
||||
version = ">= 3.4"
|
||||
}
|
||||
null = {
|
||||
source = "hashicorp/null"
|
||||
version = ">=3"
|
||||
}
|
||||
tls = {
|
||||
source = "hashicorp/tls"
|
||||
version = ">= 4.0"
|
||||
}
|
||||
acme = {
|
||||
source = "vancluever/acme"
|
||||
version = ">= 2.0"
|
||||
}
|
||||
cloudinit = {
|
||||
source = "hashicorp/cloudinit"
|
||||
version = ">= 2.3.3"
|
||||
}
|
||||
helm = {
|
||||
source = "hashicorp/helm"
|
||||
version = ">= 2.14"
|
||||
}
|
||||
rancher2 = {
|
||||
source = "rancher/rancher2"
|
||||
version = ">= 4.1.0, < 5.0"
|
||||
}
|
||||
kubernetes = {
|
||||
source = "hashicorp/kubernetes"
|
||||
version = ">= 2.31.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
12
flake.lock
12
flake.lock
|
|
@ -5,11 +5,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -20,11 +20,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1731245184,
|
||||
"narHash": "sha256-vmLS8+x+gHRv1yzj3n+GTAEObwmhxmkkukB2DwtJRdU=",
|
||||
"lastModified": 1736166416,
|
||||
"narHash": "sha256-U47xeACNBpkSO6IcCm0XvahsVXpJXzjPIQG7TZlOToU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "aebe249544837ce42588aa4b2e7972222ba12e8f",
|
||||
"rev": "b30f97d8c32d804d2d832ee837d0f1ca0695faa5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@
|
|||
less
|
||||
openssh
|
||||
openssl
|
||||
pup
|
||||
shellcheck
|
||||
tflint
|
||||
tfsec
|
||||
|
|
@ -76,6 +77,7 @@
|
|||
updatecli
|
||||
vim
|
||||
which
|
||||
yq-go
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
|||
71
test/go.mod
71
test/go.mod
|
|
@ -1,71 +0,0 @@
|
|||
module github.com/rancher/terraform-rancher2-aws
|
||||
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.44.122
|
||||
github.com/google/go-github/v53 v53.2.0
|
||||
github.com/gruntwork-io/terratest v0.43.8
|
||||
github.com/stretchr/testify v1.8.1
|
||||
golang.org/x/oauth2 v0.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.105.0 // indirect
|
||||
cloud.google.com/go/compute v1.12.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.1 // indirect
|
||||
cloud.google.com/go/iam v0.7.0 // indirect
|
||||
cloud.google.com/go/storage v1.27.0 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.4.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
|
||||
github.com/gruntwork-io/go-commons v0.8.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-getter v1.7.1 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.0 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.9.1 // indirect
|
||||
github.com/hashicorp/terraform-json v0.13.0 // indirect
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/klauspost/compress v1.15.11 // indirect
|
||||
github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/pquerna/otp v1.2.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/tmccombs/hcl2json v0.3.3 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/urfave/cli v1.22.2 // indirect
|
||||
github.com/zclconf/go-cty v1.9.1 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.103.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c // indirect
|
||||
google.golang.org/grpc v1.51.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
module github.com/rancher/terraform-rancher2-aws/test/tests
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.55.5
|
||||
github.com/google/go-github/v53 v53.2.0
|
||||
github.com/gruntwork-io/terratest v0.47.2
|
||||
golang.org/x/oauth2 v0.25.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v0.13.0 // indirect
|
||||
cloud.google.com/go/storage v1.28.1 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
|
||||
github.com/gruntwork-io/go-commons v0.8.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-getter v1.7.6 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.22.0 // indirect
|
||||
github.com/hashicorp/terraform-json v0.23.0 // indirect
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/pquerna/otp v1.4.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
github.com/tmccombs/hcl2json v0.6.4 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/urfave/cli v1.22.16 // indirect
|
||||
github.com/zclconf/go-cty v1.15.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.29.0 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/net v0.31.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.114.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.3 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
@ -30,8 +30,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
|
|||
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
|
||||
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
|
||||
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
|
||||
cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
|
||||
cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
|
||||
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
|
||||
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
|
||||
cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
|
||||
cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
|
||||
cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
|
||||
|
|
@ -68,10 +68,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz
|
|||
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
|
||||
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
|
||||
cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
|
||||
cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0=
|
||||
cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
|
||||
cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48=
|
||||
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=
|
||||
cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4=
|
||||
cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0=
|
||||
|
|
@ -109,14 +107,14 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97
|
|||
cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc=
|
||||
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
|
||||
cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc=
|
||||
cloud.google.com/go/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs=
|
||||
cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg=
|
||||
cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
|
||||
cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
|
||||
cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
|
||||
cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
|
||||
cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=
|
||||
cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08=
|
||||
cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=
|
||||
cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=
|
||||
cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
|
||||
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
|
||||
cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4=
|
||||
cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w=
|
||||
cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE=
|
||||
|
|
@ -172,8 +170,9 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
|||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
|
||||
cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=
|
||||
cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ=
|
||||
cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=
|
||||
cloud.google.com/go/storage v1.28.1 h1:F5QDG5ChchaAVQhINh24U99OWHURqrW8OmQcGKXcbgI=
|
||||
cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y=
|
||||
cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=
|
||||
cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g=
|
||||
cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=
|
||||
|
|
@ -186,21 +185,22 @@ cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuW
|
|||
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
|
||||
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
|
||||
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHjgo=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
|
||||
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
|
|
@ -228,8 +228,8 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
|
@ -253,11 +253,12 @@ github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRH
|
|||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
|
||||
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
|
@ -273,7 +274,6 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
|||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
|
@ -310,8 +310,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI=
|
||||
github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
|
|
@ -320,8 +321,9 @@ github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPg
|
|||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ=
|
||||
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
|
|
@ -338,12 +340,14 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
|
|||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||
|
|
@ -353,33 +357,33 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99
|
|||
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
|
||||
github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=
|
||||
github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A=
|
||||
github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
|
||||
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro=
|
||||
github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78=
|
||||
github.com/gruntwork-io/terratest v0.43.8 h1:6JNZE1REO5B1AGbTvBvMDNBX/gxiO4LTkth5uFqBCbU=
|
||||
github.com/gruntwork-io/terratest v0.43.8/go.mod h1:Tw+6/fcJFiBPpsx9NNSkLG5oHKIeaqiJHVLpQ+ORIfQ=
|
||||
github.com/gruntwork-io/terratest v0.47.2 h1:t6iWwsqJH7Gx0RwXleU/vjc+2c0JXRMdj3DxYXTBssQ=
|
||||
github.com/gruntwork-io/terratest v0.47.2/go.mod h1:LnYX8BN5WxUMpDr8rtD39oToSL4CBERWSCusbJ0d/64=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY=
|
||||
github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744=
|
||||
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
github.com/hashicorp/go-getter v1.7.6 h1:5jHuM+aH373XNtXl9TNTUH5Qd69Trve11tHIrB+6yj4=
|
||||
github.com/hashicorp/go-getter v1.7.6/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
|
||||
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
|
||||
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
|
||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl/v2 v2.9.1 h1:eOy4gREY0/ZQHNItlfuEZqtcQbXIxzojlP301hDpnac=
|
||||
github.com/hashicorp/hcl/v2 v2.9.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
|
||||
github.com/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY=
|
||||
github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk=
|
||||
github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M=
|
||||
github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
|
||||
github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI=
|
||||
github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
|
||||
|
|
@ -390,20 +394,20 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
|
|||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
|
||||
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
|
|
@ -413,36 +417,34 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
|
|||
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||
github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 h1:ofNAzWCcyTALn2Zv40+8XitdzCgXY6e9qvXwN9W0YXg=
|
||||
github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
|
||||
github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
||||
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
|
@ -451,29 +453,27 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ=
|
||||
github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tmccombs/hcl2json v0.6.4 h1:/FWnzS9JCuyZ4MNwrG4vMrFrzRgsWEOVi+1AyYUVLGw=
|
||||
github.com/tmccombs/hcl2json v0.6.4/go.mod h1:+ppKlIW3H5nsAsZddXPy2iMyvld3SHxyjswOZhavRDk=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ=
|
||||
github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zclconf/go-cty v1.8.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zclconf/go-cty v1.9.1 h1:viqrgQwFl5UpSxc046qblj78wZXVDFnSOufaOTER+cc=
|
||||
github.com/zclconf/go-cty v1.9.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
|
||||
github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=
|
||||
github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
|
|
@ -485,14 +485,13 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
|||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
|
@ -529,8 +528,9 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
|
@ -577,8 +577,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
|||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
|
@ -604,8 +604,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri
|
|||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
|
||||
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
|
||||
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
|
||||
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
|
||||
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
@ -620,6 +620,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
@ -627,7 +629,6 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -688,13 +689,13 @@ golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
@ -705,8 +706,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
|
@ -747,6 +748,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
|
|||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
|
|
@ -755,6 +757,7 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
|
|
@ -762,6 +765,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
@ -819,8 +824,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ
|
|||
google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
|
||||
google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
|
||||
google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
|
||||
google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ=
|
||||
google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=
|
||||
google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE=
|
||||
google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
|
@ -930,8 +935,8 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw
|
|||
google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
|
||||
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c h1:S34D59DS2GWOEwWNt4fYmTcFrtlOgukG2k9WsomZ7tg=
|
||||
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
|
|
@ -967,8 +972,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
|
|||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
|
||||
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
|
||||
google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
|
||||
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
|
@ -985,11 +990,12 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
|
|||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
@ -1,407 +1,103 @@
|
|||
package one
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/google/go-github/v53/github"
|
||||
aws "github.com/gruntwork-io/terratest/modules/aws"
|
||||
g "github.com/gruntwork-io/terratest/modules/git"
|
||||
"github.com/gruntwork-io/terratest/modules/random"
|
||||
"github.com/gruntwork-io/terratest/modules/ssh"
|
||||
"github.com/gruntwork-io/terratest/modules/terraform"
|
||||
"golang.org/x/oauth2"
|
||||
aws "github.com/gruntwork-io/terratest/modules/aws"
|
||||
g "github.com/gruntwork-io/terratest/modules/git"
|
||||
"github.com/gruntwork-io/terratest/modules/ssh"
|
||||
"github.com/gruntwork-io/terratest/modules/terraform"
|
||||
util "github.com/rancher/terraform-rancher2-aws/test/tests"
|
||||
)
|
||||
|
||||
func TestOneBasic(t *testing.T) {
|
||||
t.Parallel()
|
||||
id := getId()
|
||||
region := getRegion()
|
||||
directory := "one"
|
||||
owner := "terraform-ci@suse.com"
|
||||
setAcmeServer()
|
||||
t.Parallel()
|
||||
id := util.GetId()
|
||||
region := util.GetRegion()
|
||||
directory := "one"
|
||||
owner := "terraform-ci@suse.com"
|
||||
util.SetAcmeServer()
|
||||
|
||||
repoRoot, err := filepath.Abs(g.GetRepoRoot(t))
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting git root directory: %v", err)
|
||||
}
|
||||
repoRoot, err := filepath.Abs(g.GetRepoRoot(t))
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting git root directory: %v", err)
|
||||
}
|
||||
|
||||
exampleDir := repoRoot + "/examples/" + directory
|
||||
testDir := repoRoot + "/test/tests/data/" + id
|
||||
exampleDir := repoRoot + "/examples/" + directory
|
||||
testDir := repoRoot + "/test/tests/data/" + id
|
||||
|
||||
err = createTestDirectories(t, id)
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
t.Fatalf("Error creating test data directories: %s", err)
|
||||
}
|
||||
keyPair, err := createKeypair(t, region, owner, id)
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
t.Fatalf("Error creating test key pair: %s", err)
|
||||
}
|
||||
sshAgent := ssh.SshAgentWithKeyPair(t, keyPair.KeyPair)
|
||||
t.Logf("Key %s created and added to agent", keyPair.Name)
|
||||
err = util.CreateTestDirectories(t, id)
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
t.Fatalf("Error creating test data directories: %s", err)
|
||||
}
|
||||
keyPair, err := util.CreateKeypair(t, region, owner, id)
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
t.Fatalf("Error creating test key pair: %s", err)
|
||||
}
|
||||
sshAgent := ssh.SshAgentWithKeyPair(t, keyPair.KeyPair)
|
||||
t.Logf("Key %s created and added to agent", keyPair.Name)
|
||||
|
||||
_, _, rke2Version, err := GetRke2Releases()
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
sshAgent.Stop()
|
||||
t.Fatalf("Error getting Rke2 release version: %s", err)
|
||||
}
|
||||
// use oldest RKE2, remember it releases much more than Rancher
|
||||
_, _, rke2Version, err := util.GetRke2Releases()
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
sshAgent.Stop()
|
||||
t.Fatalf("Error getting Rke2 release version: %s", err)
|
||||
}
|
||||
|
||||
// use latest Rancher, due to community patch issue
|
||||
rancherVersion, _, _, err := util.GetRancherReleases()
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
sshAgent.Stop()
|
||||
t.Fatalf("Error getting Rancher release version: %s", err)
|
||||
}
|
||||
|
||||
rancherVersion, _, _, err := GetRancherReleases()
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
sshAgent.Stop()
|
||||
t.Fatalf("Error getting Rancher release version: %s", err)
|
||||
}
|
||||
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
|
||||
TerraformDir: exampleDir,
|
||||
// Variables to pass to our Terraform code using -var options
|
||||
Vars: map[string]interface{}{
|
||||
"identifier": id,
|
||||
"owner": owner,
|
||||
"key_name": keyPair.Name,
|
||||
"key": keyPair.KeyPair.PublicKey,
|
||||
"zone": os.Getenv("ZONE"),
|
||||
"rke2_version": rke2Version,
|
||||
"rancher_version": rancherVersion,
|
||||
"file_path": testDir,
|
||||
},
|
||||
// Environment variables to set when running Terraform
|
||||
EnvVars: map[string]string{
|
||||
"AWS_DEFAULT_REGION": region,
|
||||
"AWS_REGION": region,
|
||||
"TF_DATA_DIR": testDir,
|
||||
"TF_IN_AUTOMATION": "1",
|
||||
"TF_CLI_ARGS_plan": "-no-color -state=" + testDir + "/tfstate",
|
||||
"TF_CLI_ARGS_apply": "-no-color -state=" + testDir + "/tfstate",
|
||||
"TF_CLI_ARGS_destroy": "-no-color -state=" + testDir + "/tfstate",
|
||||
"TF_CLI_ARGS_output": "-no-color -state=" + testDir + "/tfstate",
|
||||
},
|
||||
RetryableTerraformErrors: util.GetRetryableTerraformErrors(),
|
||||
NoColor: true,
|
||||
SshAgent: sshAgent,
|
||||
Upgrade: true,
|
||||
})
|
||||
|
||||
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
|
||||
TerraformDir: exampleDir,
|
||||
// Variables to pass to our Terraform code using -var options
|
||||
Vars: map[string]interface{}{
|
||||
"identifier": id,
|
||||
"owner": owner,
|
||||
"key_name": keyPair.Name,
|
||||
"key": keyPair.KeyPair.PublicKey,
|
||||
"zone": os.Getenv("ZONE"),
|
||||
"rke2_version": rke2Version,
|
||||
"rancher_version": rancherVersion,
|
||||
"file_path": testDir,
|
||||
},
|
||||
// Environment variables to set when running Terraform
|
||||
EnvVars: map[string]string{
|
||||
"AWS_DEFAULT_REGION": region,
|
||||
"AWS_REGION": region,
|
||||
"TF_DATA_DIR": testDir,
|
||||
"TF_IN_AUTOMATION": "1",
|
||||
"TF_CLI_ARGS_plan": "-no-color -state=" + testDir + "/tfstate",
|
||||
"TF_CLI_ARGS_apply": "-no-color -state=" + testDir + "/tfstate",
|
||||
"TF_CLI_ARGS_destroy": "-no-color -state=" + testDir + "/tfstate",
|
||||
"TF_CLI_ARGS_output": "-no-color -state=" + testDir + "/tfstate",
|
||||
},
|
||||
RetryableTerraformErrors: getRetryableTerraformErrors(),
|
||||
NoColor: true,
|
||||
SshAgent: sshAgent,
|
||||
Upgrade: true,
|
||||
})
|
||||
_, err = terraform.InitAndApplyE(t, terraformOptions)
|
||||
if err != nil {
|
||||
teardown(t, testDir, terraformOptions, keyPair)
|
||||
os.Remove(exampleDir + ".terraform.lock.hcl")
|
||||
sshAgent.Stop()
|
||||
t.Fatalf("Error creating cluster: %s", err)
|
||||
}
|
||||
t.Log("Test passed, tearing down...")
|
||||
teardown(t, testDir, terraformOptions, keyPair)
|
||||
os.Remove(exampleDir + ".terraform.lock.hcl")
|
||||
sshAgent.Stop()
|
||||
}
|
||||
|
||||
func createKeypair(t *testing.T, region string, owner string, id string) (*aws.Ec2Keypair, error) {
|
||||
t.Log("Creating keypair...")
|
||||
// Create an EC2 KeyPair that we can use for SSH access
|
||||
keyPairName := fmt.Sprintf("terraform-ci-%s", id)
|
||||
keyPair := aws.CreateAndImportEC2KeyPair(t, region, keyPairName)
|
||||
|
||||
// tag the key pair so we can find in the access module
|
||||
client, err := aws.NewEc2ClientE(t, region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := "key-name"
|
||||
keyNameFilter := ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&keyPairName},
|
||||
}
|
||||
input := &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err := client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = aws.AddTagsToResourceE(t, region, *result.KeyPairs[0].KeyPairId, map[string]string{"Name": keyPairName, "Owner": owner})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify that the name and owner tags were placed properly
|
||||
k = "tag:Name"
|
||||
keyNameFilter = ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&keyPairName},
|
||||
}
|
||||
input = &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err = client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k = "tag:Owner"
|
||||
keyNameFilter = ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&owner},
|
||||
}
|
||||
input = &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err = client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return keyPair, nil
|
||||
}
|
||||
|
||||
func getRetryableTerraformErrors() map[string]string {
|
||||
retryableTerraformErrors := map[string]string{
|
||||
// The reason is unknown, but eventually these succeed after a few retries.
|
||||
".*unable to verify signature.*": "Failed due to transient network error.",
|
||||
".*unable to verify checksum.*": "Failed due to transient network error.",
|
||||
".*no provider exists with the given name.*": "Failed due to transient network error.",
|
||||
".*registry service is unreachable.*": "Failed due to transient network error.",
|
||||
".*connection reset by peer.*": "Failed due to transient network error.",
|
||||
".*TLS handshake timeout.*": "Failed due to transient network error.",
|
||||
".*Error: disassociating EC2 EIP.*does not exist.*": "Failed to delete EIP because interface is already gone",
|
||||
".*context deadline exceeded.*": "Failed due to kubernetes timeout, retrying.",
|
||||
}
|
||||
return retryableTerraformErrors
|
||||
}
|
||||
|
||||
func setAcmeServer() string {
|
||||
acmeserver := os.Getenv("ACME_SERVER_URL")
|
||||
if acmeserver == "" {
|
||||
os.Setenv("ACME_SERVER_URL", "https://acme-staging-v02.api.letsencrypt.org/directory")
|
||||
}
|
||||
return acmeserver
|
||||
}
|
||||
|
||||
func getRegion() string {
|
||||
region := os.Getenv("AWS_REGION")
|
||||
if region == "" {
|
||||
region = os.Getenv("AWS_DEFAULT_REGION")
|
||||
}
|
||||
if region == "" {
|
||||
region = "us-west-2"
|
||||
}
|
||||
return region
|
||||
}
|
||||
|
||||
func getId() string {
|
||||
id := os.Getenv("IDENTIFIER")
|
||||
if id == "" {
|
||||
id = random.UniqueId()
|
||||
}
|
||||
id += "-" + random.UniqueId()
|
||||
return id
|
||||
}
|
||||
|
||||
func createTestDirectories(t *testing.T, id string) error {
|
||||
gwd := g.GetRepoRoot(t)
|
||||
fwd, err := filepath.Abs(gwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tdd := fwd + "/test/tests/data"
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
tdd = fwd + "/test/tests/data/" + id
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
tdd = fwd + "/test/tests/data/" + id + "/data"
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func teardown(t *testing.T, directory string, options *terraform.Options, keyPair *aws.Ec2Keypair) {
|
||||
directoryExists := true
|
||||
_, err := os.Stat(directory)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
directoryExists = false
|
||||
}
|
||||
}
|
||||
if directoryExists {
|
||||
terraform.Destroy(t, options)
|
||||
err := os.RemoveAll(directory)
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete test data directory: %v", err)
|
||||
}
|
||||
}
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
}
|
||||
func GetRancherReleases() (string, string, string, error) {
|
||||
releases, err := getRancherReleases()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
versions := filterPrerelease(releases)
|
||||
if len(versions) == 0 {
|
||||
return "", "", "", errors.New("no eligible versions found")
|
||||
}
|
||||
sortVersions(&versions)
|
||||
latest := versions[0]
|
||||
stable := latest
|
||||
lts := stable
|
||||
if len(versions) > 1 {
|
||||
stable = versions[1]
|
||||
}
|
||||
if len(versions) > 2 {
|
||||
lts = versions[2]
|
||||
}
|
||||
return latest, stable, lts, nil
|
||||
}
|
||||
|
||||
func getRancherReleases() ([]*github.RepositoryRelease, error) {
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
fmt.Println("GITHUB_TOKEN environment variable not set")
|
||||
return nil, errors.New("GITHUB_TOKEN environment variable not set")
|
||||
}
|
||||
|
||||
// Create a new OAuth2 token using the GitHub token
|
||||
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubToken})
|
||||
tokenClient := oauth2.NewClient(context.Background(), tokenSource)
|
||||
|
||||
// Create a new GitHub client using the authenticated HTTP client
|
||||
client := github.NewClient(tokenClient)
|
||||
|
||||
var releases []*github.RepositoryRelease
|
||||
releases, _, err := client.Repositories.ListReleases(context.Background(), "rancher", "rancher", &github.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func GetRke2Releases() (string, string, string, error) {
|
||||
releases, err := getRke2Releases()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
versions := filterPrerelease(releases)
|
||||
if len(versions) == 0 {
|
||||
return "", "", "", errors.New("no eligible versions found")
|
||||
}
|
||||
sortVersions(&versions)
|
||||
v := filterDuplicateMinors(versions)
|
||||
latest := v[0]
|
||||
stable := latest
|
||||
lts := stable
|
||||
if len(v) > 1 {
|
||||
stable = v[1]
|
||||
}
|
||||
if len(v) > 2 {
|
||||
lts = v[2]
|
||||
}
|
||||
return latest, stable, lts, nil
|
||||
}
|
||||
|
||||
func getRke2Releases() ([]*github.RepositoryRelease, error) {
|
||||
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
fmt.Println("GITHUB_TOKEN environment variable not set")
|
||||
return nil, errors.New("GITHUB_TOKEN environment variable not set")
|
||||
}
|
||||
|
||||
// Create a new OAuth2 token using the GitHub token
|
||||
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubToken})
|
||||
tokenClient := oauth2.NewClient(context.Background(), tokenSource)
|
||||
|
||||
// Create a new GitHub client using the authenticated HTTP client
|
||||
client := github.NewClient(tokenClient)
|
||||
|
||||
var releases []*github.RepositoryRelease
|
||||
releases, _, err := client.Repositories.ListReleases(context.Background(), "rancher", "rke2", &github.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
func filterPrerelease(r []*github.RepositoryRelease) []string {
|
||||
var versions []string
|
||||
for _, release := range r {
|
||||
version := release.GetTagName()
|
||||
if !release.GetPrerelease() {
|
||||
versions = append(versions, version)
|
||||
// [
|
||||
// "v1.28.14+rke2r1",
|
||||
// "v1.30.1+rke2r3",
|
||||
// "v1.29.4+rke2r1",
|
||||
// "v1.30.1+rke2r2",
|
||||
// "v1.29.5+rke2r2",
|
||||
// "v1.30.1+rke2r1",
|
||||
// "v1.27.20+rke2r1",
|
||||
// "v1.30.0+rke2r1",
|
||||
// "v1.29.5+rke2r1",
|
||||
// "v1.28.17+rke2r1",
|
||||
// ]
|
||||
}
|
||||
}
|
||||
return versions
|
||||
}
|
||||
func sortVersions(v *[]string) {
|
||||
slices.SortFunc(*v, func(a, b string) int {
|
||||
return cmp.Compare(b, a)
|
||||
//[
|
||||
// v1.30.1+rke2r3,
|
||||
// v1.30.1+rke2r2,
|
||||
// v1.30.1+rke2r1,
|
||||
// v1.30.0+rke2r1,
|
||||
// v1.29.5+rke2r2,
|
||||
// v1.29.5+rke2r1,
|
||||
// v1.29.4+rke2r1,
|
||||
// v1.28.17+rke2r1,
|
||||
// v1.28.14+rke2r1,
|
||||
// v1.27.20+rke2r1,
|
||||
//]
|
||||
})
|
||||
}
|
||||
func filterDuplicateMinors(vers []string) []string {
|
||||
var fv []string
|
||||
fv = append(fv, vers[0])
|
||||
for i := 1; i < len(vers); i++ {
|
||||
p := vers[i-1]
|
||||
v := vers[i]
|
||||
vp := strings.Split(v[1:], "+") //["1.30.1","rke2r3"]
|
||||
pp := strings.Split(p[1:], "+") //["1.30.1","rke2r2"]
|
||||
if vp[0] != pp[0] {
|
||||
vpp := strings.Split(vp[0], ".") //["1","30","1]
|
||||
ppp := strings.Split(pp[0], ".") //["1","30","1]
|
||||
if vpp[1] != ppp[1] {
|
||||
fv = append(fv, v)
|
||||
//[
|
||||
// v1.30.1+rke2r3,
|
||||
// v1.29.5+rke2r2,
|
||||
// v1.28.17+rke2r1,
|
||||
// v1.27.20+rke2r1,
|
||||
//]
|
||||
}
|
||||
}
|
||||
}
|
||||
return fv
|
||||
_, err = terraform.InitAndApplyE(t, terraformOptions)
|
||||
if err != nil {
|
||||
util.Teardown(t, testDir, terraformOptions, keyPair)
|
||||
os.Remove(exampleDir + ".terraform.lock.hcl")
|
||||
sshAgent.Stop()
|
||||
t.Fatalf("Error creating cluster: %s", err)
|
||||
}
|
||||
t.Log("Test passed, tearing down...")
|
||||
util.Teardown(t, testDir, terraformOptions, keyPair)
|
||||
os.Remove(exampleDir + ".terraform.lock.hcl")
|
||||
sshAgent.Stop()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,24 @@
|
|||
package prod
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/google/go-github/v53/github"
|
||||
aws "github.com/gruntwork-io/terratest/modules/aws"
|
||||
g "github.com/gruntwork-io/terratest/modules/git"
|
||||
"github.com/gruntwork-io/terratest/modules/random"
|
||||
"github.com/gruntwork-io/terratest/modules/ssh"
|
||||
"github.com/gruntwork-io/terratest/modules/terraform"
|
||||
"golang.org/x/oauth2"
|
||||
util "github.com/rancher/terraform-rancher2-aws/test/tests"
|
||||
)
|
||||
|
||||
func TestProdBasic(t *testing.T) {
|
||||
t.Parallel()
|
||||
id := getId()
|
||||
region := getRegion()
|
||||
id := util.GetId()
|
||||
region := util.GetRegion()
|
||||
directory := "prod"
|
||||
owner := "terraform-ci@suse.com"
|
||||
setAcmeServer()
|
||||
util.SetAcmeServer()
|
||||
|
||||
repoRoot, err := filepath.Abs(g.GetRepoRoot(t))
|
||||
if err != nil {
|
||||
|
|
@ -37,12 +28,12 @@ func TestProdBasic(t *testing.T) {
|
|||
exampleDir := repoRoot + "/examples/" + directory
|
||||
testDir := repoRoot + "/test/tests/data/" + id
|
||||
|
||||
err = createTestDirectories(t, id)
|
||||
err = util.CreateTestDirectories(t, id)
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
t.Fatalf("Error creating test data directories: %s", err)
|
||||
}
|
||||
keyPair, err := createKeypair(t, region, owner, id)
|
||||
keyPair, err := util.CreateKeypair(t, region, owner, id)
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
t.Fatalf("Error creating test key pair: %s", err)
|
||||
|
|
@ -50,7 +41,8 @@ func TestProdBasic(t *testing.T) {
|
|||
sshAgent := ssh.SshAgentWithKeyPair(t, keyPair.KeyPair)
|
||||
t.Logf("Key %s created and added to agent", keyPair.Name)
|
||||
|
||||
_, _, rke2Version, err := GetRke2Releases()
|
||||
// use oldest RKE2, remember it releases much more than Rancher
|
||||
_, _, rke2Version, err := util.GetRke2Releases()
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
|
|
@ -58,7 +50,8 @@ func TestProdBasic(t *testing.T) {
|
|||
t.Fatalf("Error getting Rke2 release version: %s", err)
|
||||
}
|
||||
|
||||
rancherVersion, _, _, err := GetRancherReleases()
|
||||
// use latest Rancher, due to community patch policy
|
||||
rancherVersion, _, _, err := util.GetRancherReleases()
|
||||
if err != nil {
|
||||
os.RemoveAll(testDir)
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
|
|
@ -90,318 +83,20 @@ func TestProdBasic(t *testing.T) {
|
|||
"TF_CLI_ARGS_destroy": "-no-color -state=" + testDir + "/tfstate",
|
||||
"TF_CLI_ARGS_output": "-no-color -state=" + testDir + "/tfstate",
|
||||
},
|
||||
RetryableTerraformErrors: getRetryableTerraformErrors(),
|
||||
RetryableTerraformErrors: util.GetRetryableTerraformErrors(),
|
||||
NoColor: true,
|
||||
SshAgent: sshAgent,
|
||||
Upgrade: true,
|
||||
})
|
||||
_, err = terraform.InitAndApplyE(t, terraformOptions)
|
||||
if err != nil {
|
||||
teardown(t, testDir, terraformOptions, keyPair)
|
||||
util.Teardown(t, testDir, terraformOptions, keyPair)
|
||||
os.Remove(exampleDir + ".terraform.lock.hcl")
|
||||
sshAgent.Stop()
|
||||
t.Fatalf("Error creating cluster: %s", err)
|
||||
}
|
||||
t.Log("Test passed, tearing down...")
|
||||
teardown(t, testDir, terraformOptions, keyPair)
|
||||
util.Teardown(t, testDir, terraformOptions, keyPair)
|
||||
os.Remove(exampleDir + ".terraform.lock.hcl")
|
||||
sshAgent.Stop()
|
||||
}
|
||||
|
||||
func createKeypair(t *testing.T, region string, owner string, id string) (*aws.Ec2Keypair, error) {
|
||||
t.Log("Creating keypair...")
|
||||
// Create an EC2 KeyPair that we can use for SSH access
|
||||
keyPairName := fmt.Sprintf("terraform-ci-%s", id)
|
||||
keyPair := aws.CreateAndImportEC2KeyPair(t, region, keyPairName)
|
||||
|
||||
// tag the key pair so we can find in the access module
|
||||
client, err := aws.NewEc2ClientE(t, region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := "key-name"
|
||||
keyNameFilter := ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&keyPairName},
|
||||
}
|
||||
input := &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err := client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = aws.AddTagsToResourceE(t, region, *result.KeyPairs[0].KeyPairId, map[string]string{"Name": keyPairName, "Owner": owner})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify that the name and owner tags were placed properly
|
||||
k = "tag:Name"
|
||||
keyNameFilter = ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&keyPairName},
|
||||
}
|
||||
input = &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err = client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k = "tag:Owner"
|
||||
keyNameFilter = ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&owner},
|
||||
}
|
||||
input = &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err = client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return keyPair, nil
|
||||
}
|
||||
|
||||
func getRetryableTerraformErrors() map[string]string {
|
||||
retryableTerraformErrors := map[string]string{
|
||||
// The reason is unknown, but eventually these succeed after a few retries.
|
||||
".*unable to verify signature.*": "Failed due to transient network error.",
|
||||
".*unable to verify checksum.*": "Failed due to transient network error.",
|
||||
".*no provider exists with the given name.*": "Failed due to transient network error.",
|
||||
".*registry service is unreachable.*": "Failed due to transient network error.",
|
||||
".*connection reset by peer.*": "Failed due to transient network error.",
|
||||
".*TLS handshake timeout.*": "Failed due to transient network error.",
|
||||
".*Error: disassociating EC2 EIP.*does not exist.*": "Failed to delete EIP because interface is already gone",
|
||||
".*context deadline exceeded.*": "Failed due to kubernetes timeout, retrying.",
|
||||
}
|
||||
return retryableTerraformErrors
|
||||
}
|
||||
|
||||
func setAcmeServer() string {
|
||||
acmeserver := os.Getenv("ACME_SERVER_URL")
|
||||
if acmeserver == "" {
|
||||
os.Setenv("ACME_SERVER_URL", "https://acme-staging-v02.api.letsencrypt.org/directory")
|
||||
}
|
||||
return acmeserver
|
||||
}
|
||||
|
||||
func getRegion() string {
|
||||
region := os.Getenv("AWS_REGION")
|
||||
if region == "" {
|
||||
region = os.Getenv("AWS_DEFAULT_REGION")
|
||||
}
|
||||
if region == "" {
|
||||
region = "us-west-2"
|
||||
}
|
||||
return region
|
||||
}
|
||||
|
||||
func getId() string {
|
||||
id := os.Getenv("IDENTIFIER")
|
||||
if id == "" {
|
||||
id = random.UniqueId()
|
||||
}
|
||||
id += "-" + random.UniqueId()
|
||||
return id
|
||||
}
|
||||
|
||||
func createTestDirectories(t *testing.T, id string) error {
|
||||
gwd := g.GetRepoRoot(t)
|
||||
fwd, err := filepath.Abs(gwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tdd := fwd + "/test/tests/data"
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
tdd = fwd + "/test/tests/data/" + id
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
tdd = fwd + "/test/tests/data/" + id + "/data"
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func teardown(t *testing.T, directory string, options *terraform.Options, keyPair *aws.Ec2Keypair) {
|
||||
directoryExists := true
|
||||
_, err := os.Stat(directory)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
directoryExists = false
|
||||
}
|
||||
}
|
||||
if directoryExists {
|
||||
terraform.Destroy(t, options)
|
||||
err := os.RemoveAll(directory)
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete test data directory: %v", err)
|
||||
}
|
||||
}
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
}
|
||||
func GetRancherReleases() (string, string, string, error) {
|
||||
releases, err := getRancherReleases()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
versions := filterPrerelease(releases)
|
||||
if len(versions) == 0 {
|
||||
return "", "", "", errors.New("no eligible versions found")
|
||||
}
|
||||
sortVersions(&versions)
|
||||
latest := versions[0]
|
||||
stable := latest
|
||||
lts := stable
|
||||
if len(versions) > 1 {
|
||||
stable = versions[1]
|
||||
}
|
||||
if len(versions) > 2 {
|
||||
lts = versions[2]
|
||||
}
|
||||
return latest, stable, lts, nil
|
||||
}
|
||||
|
||||
func getRancherReleases() ([]*github.RepositoryRelease, error) {
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
fmt.Println("GITHUB_TOKEN environment variable not set")
|
||||
return nil, errors.New("GITHUB_TOKEN environment variable not set")
|
||||
}
|
||||
|
||||
// Create a new OAuth2 token using the GitHub token
|
||||
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubToken})
|
||||
tokenClient := oauth2.NewClient(context.Background(), tokenSource)
|
||||
|
||||
// Create a new GitHub client using the authenticated HTTP client
|
||||
client := github.NewClient(tokenClient)
|
||||
|
||||
var releases []*github.RepositoryRelease
|
||||
releases, _, err := client.Repositories.ListReleases(context.Background(), "rancher", "rancher", &github.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func GetRke2Releases() (string, string, string, error) {
|
||||
releases, err := getRke2Releases()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
versions := filterPrerelease(releases)
|
||||
if len(versions) == 0 {
|
||||
return "", "", "", errors.New("no eligible versions found")
|
||||
}
|
||||
sortVersions(&versions)
|
||||
v := filterDuplicateMinors(versions)
|
||||
latest := v[0]
|
||||
stable := latest
|
||||
lts := stable
|
||||
if len(v) > 1 {
|
||||
stable = v[1]
|
||||
}
|
||||
if len(v) > 2 {
|
||||
lts = v[2]
|
||||
}
|
||||
return latest, stable, lts, nil
|
||||
}
|
||||
|
||||
func getRke2Releases() ([]*github.RepositoryRelease, error) {
|
||||
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
fmt.Println("GITHUB_TOKEN environment variable not set")
|
||||
return nil, errors.New("GITHUB_TOKEN environment variable not set")
|
||||
}
|
||||
|
||||
// Create a new OAuth2 token using the GitHub token
|
||||
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubToken})
|
||||
tokenClient := oauth2.NewClient(context.Background(), tokenSource)
|
||||
|
||||
// Create a new GitHub client using the authenticated HTTP client
|
||||
client := github.NewClient(tokenClient)
|
||||
|
||||
var releases []*github.RepositoryRelease
|
||||
releases, _, err := client.Repositories.ListReleases(context.Background(), "rancher", "rke2", &github.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
func filterPrerelease(r []*github.RepositoryRelease) []string {
|
||||
var versions []string
|
||||
for _, release := range r {
|
||||
version := release.GetTagName()
|
||||
if !release.GetPrerelease() {
|
||||
versions = append(versions, version)
|
||||
// [
|
||||
// "v1.28.14+rke2r1",
|
||||
// "v1.30.1+rke2r3",
|
||||
// "v1.29.4+rke2r1",
|
||||
// "v1.30.1+rke2r2",
|
||||
// "v1.29.5+rke2r2",
|
||||
// "v1.30.1+rke2r1",
|
||||
// "v1.27.20+rke2r1",
|
||||
// "v1.30.0+rke2r1",
|
||||
// "v1.29.5+rke2r1",
|
||||
// "v1.28.17+rke2r1",
|
||||
// ]
|
||||
}
|
||||
}
|
||||
return versions
|
||||
}
|
||||
func sortVersions(v *[]string) {
|
||||
slices.SortFunc(*v, func(a, b string) int {
|
||||
return cmp.Compare(b, a)
|
||||
//[
|
||||
// v1.30.1+rke2r3,
|
||||
// v1.30.1+rke2r2,
|
||||
// v1.30.1+rke2r1,
|
||||
// v1.30.0+rke2r1,
|
||||
// v1.29.5+rke2r2,
|
||||
// v1.29.5+rke2r1,
|
||||
// v1.29.4+rke2r1,
|
||||
// v1.28.17+rke2r1,
|
||||
// v1.28.14+rke2r1,
|
||||
// v1.27.20+rke2r1,
|
||||
//]
|
||||
})
|
||||
}
|
||||
func filterDuplicateMinors(vers []string) []string {
|
||||
var fv []string
|
||||
fv = append(fv, vers[0])
|
||||
for i := 1; i < len(vers); i++ {
|
||||
p := vers[i-1]
|
||||
v := vers[i]
|
||||
vp := strings.Split(v[1:], "+") //["1.30.1","rke2r3"]
|
||||
pp := strings.Split(p[1:], "+") //["1.30.1","rke2r2"]
|
||||
if vp[0] != pp[0] {
|
||||
vpp := strings.Split(vp[0], ".") //["1","30","1]
|
||||
ppp := strings.Split(pp[0], ".") //["1","30","1]
|
||||
if vpp[1] != ppp[1] {
|
||||
fv = append(fv, v)
|
||||
//[
|
||||
// v1.30.1+rke2r3,
|
||||
// v1.29.5+rke2r2,
|
||||
// v1.28.17+rke2r1,
|
||||
// v1.27.20+rke2r1,
|
||||
//]
|
||||
}
|
||||
}
|
||||
}
|
||||
return fv
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,395 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
ec2 "github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/google/go-github/v53/github"
|
||||
aws "github.com/gruntwork-io/terratest/modules/aws"
|
||||
g "github.com/gruntwork-io/terratest/modules/git"
|
||||
"github.com/gruntwork-io/terratest/modules/random"
|
||||
"github.com/gruntwork-io/terratest/modules/terraform"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
func GetRancherReleases() (string, string, string, error) {
|
||||
releases, err := getRancherReleases()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
versions := filterPrerelease(releases)
|
||||
if len(versions) == 0 {
|
||||
return "", "", "", errors.New("no eligible versions found")
|
||||
}
|
||||
zeroPadVersionNumbers(&versions)
|
||||
sortVersions(&versions)
|
||||
filterDuplicateMinors(&versions)
|
||||
removeZeroPadding(&versions)
|
||||
latest := versions[0]
|
||||
stable := latest
|
||||
lts := stable
|
||||
if len(versions) > 1 {
|
||||
stable = versions[1]
|
||||
}
|
||||
if len(versions) > 2 {
|
||||
lts = versions[2]
|
||||
}
|
||||
return latest, stable, lts, nil
|
||||
}
|
||||
|
||||
func getRancherReleases() ([]*github.RepositoryRelease, error) {
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
fmt.Println("GITHUB_TOKEN environment variable not set")
|
||||
return nil, errors.New("GITHUB_TOKEN environment variable not set")
|
||||
}
|
||||
|
||||
// Create a new OAuth2 token using the GitHub token
|
||||
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubToken})
|
||||
tokenClient := oauth2.NewClient(context.Background(), tokenSource)
|
||||
|
||||
// Create a new GitHub client using the authenticated HTTP client
|
||||
client := github.NewClient(tokenClient)
|
||||
|
||||
var releases []*github.RepositoryRelease
|
||||
releases, _, err := client.Repositories.ListReleases(context.Background(), "rancher", "rancher", &github.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func GetRke2Releases() (string, string, string, error) {
|
||||
releases, err := getRke2Releases()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
versions := filterPrerelease(releases)
|
||||
if len(versions) == 0 {
|
||||
return "", "", "", errors.New("no eligible versions found")
|
||||
}
|
||||
zeroPadVersionNumbers(&versions)
|
||||
sortVersions(&versions)
|
||||
filterDuplicateMinors(&versions)
|
||||
removeZeroPadding(&versions)
|
||||
latest := versions[0]
|
||||
stable := latest
|
||||
lts := stable
|
||||
if len(versions) > 1 {
|
||||
stable = versions[1]
|
||||
}
|
||||
if len(versions) > 2 {
|
||||
lts = versions[2]
|
||||
}
|
||||
return latest, stable, lts, nil
|
||||
}
|
||||
|
||||
func getRke2Releases() ([]*github.RepositoryRelease, error) {
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
fmt.Println("GITHUB_TOKEN environment variable not set")
|
||||
return nil, errors.New("GITHUB_TOKEN environment variable not set")
|
||||
}
|
||||
|
||||
// Create a new OAuth2 token using the GitHub token
|
||||
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: githubToken})
|
||||
tokenClient := oauth2.NewClient(context.Background(), tokenSource)
|
||||
|
||||
// Create a new GitHub client using the authenticated HTTP client
|
||||
client := github.NewClient(tokenClient)
|
||||
|
||||
var releases []*github.RepositoryRelease
|
||||
releases, _, err := client.Repositories.ListReleases(context.Background(), "rancher", "rke2", &github.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func filterReleaseCandidate(v *[]string) {
|
||||
var fv []string
|
||||
versions := *v
|
||||
for i := 1; i < len(versions); i++ {
|
||||
if strings.Contains(versions[i], "-") != true {
|
||||
fv = append(fv, versions[i])
|
||||
}
|
||||
}
|
||||
*v = fv
|
||||
}
|
||||
|
||||
func filterPrerelease(r []*github.RepositoryRelease) []string {
|
||||
var versions []string
|
||||
for _, release := range r {
|
||||
version := release.GetTagName()
|
||||
if !release.GetPrerelease() {
|
||||
versions = append(versions, version)
|
||||
// [
|
||||
// "v1.28.14+rke2r1",
|
||||
// "v1.30.1+rke2r3",
|
||||
// "v1.29.4+rke2r1",
|
||||
// "v1.30.1+rke2r2",
|
||||
// "v1.29.5+rke2r2",
|
||||
// "v1.30.1+rke2r1",
|
||||
// "v1.27.20+rke2r1",
|
||||
// "v1.30.0+rke2r1",
|
||||
// "v1.29.5+rke2r1",
|
||||
// "v1.28.17+rke2r1",
|
||||
// ]
|
||||
}
|
||||
}
|
||||
return versions
|
||||
}
|
||||
|
||||
func sortVersions(v *[]string) {
|
||||
slices.SortFunc(*v, func(a, b string) int {
|
||||
return cmp.Compare(b, a)
|
||||
//[
|
||||
// v1.4.1+rke2r3,
|
||||
// v1.30.1+rke2r3,
|
||||
// v1.30.1+rke2r2,
|
||||
// v1.30.1+rke2r1,
|
||||
// v1.30.0+rke2r1,
|
||||
// v1.29.5+rke2r2,
|
||||
// v1.29.5+rke2r1,
|
||||
// v1.29.4+rke2r1,
|
||||
// v1.28.17+rke2r1,
|
||||
// v1.28.14+rke2r1,
|
||||
// v1.27.20+rke2r1,
|
||||
//]
|
||||
})
|
||||
}
|
||||
|
||||
func filterDuplicateMinors(v *[]string) { // assumes versions are sorted already
|
||||
var fv []string
|
||||
versions := *v
|
||||
fv = append(fv, versions[0])
|
||||
for i := 1; i < len(versions); i++ {
|
||||
c := versions[i]
|
||||
p := versions[i-1]
|
||||
cp := strings.Split(c[1:], "+") //["1.30.1","rke2r3"]
|
||||
pp := strings.Split(p[1:], "+") //["1.30.1","rke2r2"]
|
||||
if cp[0] != pp[0] {
|
||||
cpp := strings.Split(cp[0], ".") //["1","30","1]
|
||||
ppp := strings.Split(pp[0], ".") //["1","30","1]
|
||||
if cpp[1] != ppp[1] {
|
||||
fv = append(fv, c)
|
||||
//[
|
||||
// v1.30.1+rke2r3,
|
||||
// v1.29.5+rke2r2,
|
||||
// v1.28.17+rke2r1,
|
||||
// v1.27.20+rke2r1,
|
||||
//]
|
||||
}
|
||||
}
|
||||
}
|
||||
*v = fv
|
||||
}
|
||||
|
||||
func zeroPadVersionNumbers(v *[]string) {
|
||||
var zv []string
|
||||
versions := *v
|
||||
for i := 0; i < len(versions); i++ {
|
||||
vp := strings.Split(versions[i], "+") //["v1.3.1","rke2r3"] OR ["v2.5.4"] if no "+"
|
||||
vpp := strings.Split(vp[0], ".") //["v1","3","1]
|
||||
major := vpp[0] // assumes single digit major
|
||||
minor := ""
|
||||
trivial := ""
|
||||
if len(vpp[1]) < 2 {
|
||||
minor = fmt.Sprintf("0%s", vpp[1]) // assumes double digit versions
|
||||
} else {
|
||||
minor = vpp[1]
|
||||
}
|
||||
if len(vpp[2]) < 2 {
|
||||
trivial = fmt.Sprintf("0%s", vpp[2]) // assumes double digit versions
|
||||
} else {
|
||||
trivial = vpp[2]
|
||||
}
|
||||
if len(vp) > 1 {
|
||||
version := fmt.Sprintf("%s.%s.%s+%s", major, minor, trivial, vp[1]) //"v1.03.01+rke2r3"
|
||||
zv = append(zv, version)
|
||||
} else {
|
||||
version := fmt.Sprintf("%s.%s.%s", major, minor, trivial) //"v1.03.01"
|
||||
zv = append(zv, version)
|
||||
}
|
||||
}
|
||||
*v = zv
|
||||
}
|
||||
|
||||
func removeZeroPadding (v *[]string) {
|
||||
var zv []string
|
||||
versions := *v
|
||||
for i := 0; i < len(versions); i++ {
|
||||
vp := strings.Split(versions[i], "+") //["v1.03.01","rke2r3"] OR ["v2.05.04"] if no "+"
|
||||
vpp := strings.Split(vp[0], ".") //["v1","03","01]
|
||||
major := vpp[0] // assumes single digit major
|
||||
minor := vpp[1]
|
||||
trivial := vpp[2]
|
||||
if minor[0] == '0' {
|
||||
minor = minor[1:]
|
||||
}
|
||||
if trivial[0] == '0' {
|
||||
trivial = trivial[1:]
|
||||
}
|
||||
if len(vp) > 1 {
|
||||
version := fmt.Sprintf("%s.%s.%s+%s", major, minor, trivial, vp[1]) //"v1.3.1+rke2r3"
|
||||
zv = append(zv, version)
|
||||
} else {
|
||||
version := fmt.Sprintf("%s.%s.%s", major, minor, trivial) //"v1.3.1"
|
||||
zv = append(zv, version)
|
||||
}
|
||||
}
|
||||
*v = zv
|
||||
}
|
||||
|
||||
func CreateKeypair(t *testing.T, region string, owner string, id string) (*aws.Ec2Keypair, error) {
|
||||
t.Log("Creating keypair...")
|
||||
// Create an EC2 KeyPair that we can use for SSH access
|
||||
keyPairName := fmt.Sprintf("terraform-ci-%s", id)
|
||||
keyPair := aws.CreateAndImportEC2KeyPair(t, region, keyPairName)
|
||||
|
||||
// tag the key pair so we can find in the access module
|
||||
client, err := aws.NewEc2ClientE(t, region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := "key-name"
|
||||
keyNameFilter := ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&keyPairName},
|
||||
}
|
||||
input := &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err := client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = aws.AddTagsToResourceE(t, region, *result.KeyPairs[0].KeyPairId, map[string]string{"Name": keyPairName, "Owner": owner})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify that the name and owner tags were placed properly
|
||||
k = "tag:Name"
|
||||
keyNameFilter = ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&keyPairName},
|
||||
}
|
||||
input = &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err = client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k = "tag:Owner"
|
||||
keyNameFilter = ec2.Filter{
|
||||
Name: &k,
|
||||
Values: []*string{&owner},
|
||||
}
|
||||
input = &ec2.DescribeKeyPairsInput{
|
||||
Filters: []*ec2.Filter{&keyNameFilter},
|
||||
}
|
||||
result, err = client.DescribeKeyPairs(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return keyPair, nil
|
||||
}
|
||||
|
||||
func GetRetryableTerraformErrors() map[string]string {
|
||||
retryableTerraformErrors := map[string]string{
|
||||
// The reason is unknown, but eventually these succeed after a few retries.
|
||||
".*unable to verify signature.*": "Failed due to transient network error.",
|
||||
".*unable to verify checksum.*": "Failed due to transient network error.",
|
||||
".*no provider exists with the given name.*": "Failed due to transient network error.",
|
||||
".*registry service is unreachable.*": "Failed due to transient network error.",
|
||||
".*connection reset by peer.*": "Failed due to transient network error.",
|
||||
".*TLS handshake timeout.*": "Failed due to transient network error.",
|
||||
".*Error: disassociating EC2 EIP.*does not exist.*": "Failed to delete EIP because interface is already gone",
|
||||
".*context deadline exceeded.*": "Failed due to kubernetes timeout, retrying.",
|
||||
}
|
||||
return retryableTerraformErrors
|
||||
}
|
||||
|
||||
func SetAcmeServer() string {
|
||||
acmeserver := os.Getenv("ACME_SERVER_URL")
|
||||
if acmeserver == "" {
|
||||
os.Setenv("ACME_SERVER_URL", "https://acme-staging-v02.api.letsencrypt.org/directory")
|
||||
}
|
||||
return acmeserver
|
||||
}
|
||||
|
||||
func GetRegion() string {
|
||||
region := os.Getenv("AWS_REGION")
|
||||
if region == "" {
|
||||
region = os.Getenv("AWS_DEFAULT_REGION")
|
||||
}
|
||||
if region == "" {
|
||||
region = "us-west-2"
|
||||
}
|
||||
return region
|
||||
}
|
||||
|
||||
func GetId() string {
|
||||
id := os.Getenv("IDENTIFIER")
|
||||
if id == "" {
|
||||
id = random.UniqueId()
|
||||
}
|
||||
id += "-" + random.UniqueId()
|
||||
return id
|
||||
}
|
||||
|
||||
func CreateTestDirectories(t *testing.T, id string) error {
|
||||
gwd := g.GetRepoRoot(t)
|
||||
fwd, err := filepath.Abs(gwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tdd := fwd + "/test/tests/data"
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
tdd = fwd + "/test/tests/data/" + id
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
tdd = fwd + "/test/tests/data/" + id + "/data"
|
||||
err = os.Mkdir(tdd, 0755)
|
||||
if err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Teardown(t *testing.T, directory string, options *terraform.Options, keyPair *aws.Ec2Keypair) {
|
||||
directoryExists := true
|
||||
_, err := os.Stat(directory)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
directoryExists = false
|
||||
}
|
||||
}
|
||||
if directoryExists {
|
||||
terraform.Destroy(t, options)
|
||||
err := os.RemoveAll(directory)
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete test data directory: %v", err)
|
||||
}
|
||||
}
|
||||
aws.DeleteEC2KeyPair(t, keyPair)
|
||||
}
|
||||
Loading…
Reference in New Issue