Skip to content

Commit

Permalink
Merge branch 'master' into davidkpiano/811-monitor
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkpiano committed Apr 29, 2021
2 parents cc71908 + 8a5abd7 commit aa512af
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- uses: hashicorp/setup-terraform@v1
with:
terraform_version: 0.15.1
terraform_wrapper: false
terraform_wrapper: false
- name: checkout to repo
uses: actions/checkout@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ terraform.tfvars
*.tfstate*
.terragrunt
.terragrunt-cache

.terraform.lock.hcl
# IDE files
.idea
.vscode
Expand Down
8 changes: 5 additions & 3 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -207,21 +207,23 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.4.0)
mini_portile2 (2.5.0)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.2)
multipart-post (2.1.1)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
octokit (4.18.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (3.1.1)
racc (1.5.2)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
Expand Down
3 changes: 2 additions & 1 deletion examples/azure/terraform-azure-aks-example/output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ output "cluster_password" {
}

output "kube_config" {
value = azurerm_kubernetes_cluster.k8s.kube_config_raw
value = azurerm_kubernetes_cluster.k8s.kube_config_raw
sensitive = true
}

output "host" {
Expand Down
3 changes: 2 additions & 1 deletion examples/azure/terraform-azure-cosmosdb-example/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ output "endpoint" {
}

output "primary_key" {
value = azurerm_cosmosdb_account.test.primary_key
value = azurerm_cosmosdb_account.test.primary_key
sensitive = true
}
2 changes: 1 addition & 1 deletion examples/azure/terraform-azure-vm-example/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ output "virtual_network_name" {
}

output "vm_admin_username" {
value = azurerm_virtual_machine.vm_example.os_profile[*].admin_username
value = nonsensitive(azurerm_virtual_machine.vm_example.os_profile[*].admin_username)
}

output "vm_image_sku" {
Expand Down
7 changes: 4 additions & 3 deletions modules/azure/availabilityset.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func CheckAvailabilitySetContainsVM(t testing.TestingT, vmName string, avsName s

// CheckAvailabilitySetContainsVME checks if the Virtual Machine is contained in the Availability Set VMs
func CheckAvailabilitySetContainsVME(t testing.TestingT, vmName string, avsName string, resGroupName string, subscriptionID string) (bool, error) {
client, err := GetAvailabilitySetClientE(subscriptionID)
client, err := CreateAvailabilitySetClientE(subscriptionID)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -71,7 +71,7 @@ func GetAvailabilitySetVMNamesInCaps(t testing.TestingT, avsName string, resGrou

// GetAvailabilitySetVMNamesInCapsE gets a list of VM names in the specified Azure Availability Set
func GetAvailabilitySetVMNamesInCapsE(t testing.TestingT, avsName string, resGroupName string, subscriptionID string) ([]string, error) {
client, err := GetAvailabilitySetClientE(subscriptionID)
client, err := CreateAvailabilitySetClientE(subscriptionID)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -120,7 +120,7 @@ func GetAvailabilitySetE(t testing.TestingT, avsName string, resGroupName string
}

// Get the client reference
client, err := GetAvailabilitySetClientE(subscriptionID)
client, err := CreateAvailabilitySetClientE(subscriptionID)
if err != nil {
return nil, err
}
Expand All @@ -135,6 +135,7 @@ func GetAvailabilitySetE(t testing.TestingT, avsName string, resGroupName string
}

// GetAvailabilitySetClientE gets a new Availability Set client in the specified Azure Subscription
// TODO: remove in next version
func GetAvailabilitySetClientE(subscriptionID string) (*compute.AvailabilitySetsClient, error) {
// Validate Azure subscription ID
subscriptionID, err := getTargetAzureSubscription(subscriptionID)
Expand Down
4 changes: 2 additions & 2 deletions modules/azure/availabilityset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ The below tests are currently stubbed out, with the expectation that they will t
If/when methods to create and delete network resources are added, these tests can be extended.
*/

func TestGetAvailabilitySetClientE(t *testing.T) {
func TestCreateAvailabilitySetClientE(t *testing.T) {
t.Parallel()

subscriptionID := ""

client, err := GetAvailabilitySetClientE(subscriptionID)
client, err := CreateAvailabilitySetClientE(subscriptionID)

require.NoError(t, err)
assert.NotEmpty(t, *client)
Expand Down
27 changes: 27 additions & 0 deletions modules/azure/client_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,33 @@ func CreateStorageBlobContainerClientE(subscriptionID string) (*storage.BlobCont
return &blobContainerClient, nil
}

// CreateAvailabilitySetClientE creates a new Availability Set client in the specified Azure Subscription
func CreateAvailabilitySetClientE(subscriptionID string) (*compute.AvailabilitySetsClient, error) {
// Validate Azure subscription ID
subscriptionID, err := getTargetAzureSubscription(subscriptionID)
if err != nil {
return nil, err
}

// Lookup environment URI
baseURI, err := getBaseURI()
if err != nil {
return nil, err
}

// Get the Availability Set client
client := compute.NewAvailabilitySetsClientWithBaseURI(baseURI, subscriptionID)

// Create an authorizer
authorizer, err := NewAuthorizer()
if err != nil {
return nil, err
}
client.Authorizer = *authorizer

return &client, nil
}

// CreateVMInsightsClientE gets a VM Insights client
func CreateVMInsightsClientE(subscriptionID string) (*insights.VMInsightsClient, error) {
// Validate Azure subscription ID
Expand Down
15 changes: 13 additions & 2 deletions modules/k8s/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,31 @@ import (
"fmt"

corev1 "k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// IngressNotAvailable is returned when a Kubernetes service is not yet available to accept traffic.
type IngressNotAvailable struct {
ingress *extensionsv1beta1.Ingress
ingress *networkingv1.Ingress
}

// Error is a simple function to return a formatted error message as a string
func (err IngressNotAvailable) Error() string {
return fmt.Sprintf("Ingress %s is not available", err.ingress.Name)
}

// IngressNotAvailableV1Beta1 is returned when a Kubernetes service is not yet available to accept traffic.
type IngressNotAvailableV1Beta1 struct {
ingress *networkingv1beta1.Ingress
}

// Error is a simple function to return a formatted error message as a string
func (err IngressNotAvailableV1Beta1) Error() string {
return fmt.Sprintf("Ingress %s is not available", err.ingress.Name)
}

// UnknownKubeResourceType is returned if the given resource type does not match the list of known resource types.
type UnknownKubeResourceType struct {
ResourceType KubeResourceType
Expand Down
89 changes: 81 additions & 8 deletions modules/k8s/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (
"time"

"github.com/stretchr/testify/require"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/gruntwork-io/terratest/modules/logger"
Expand All @@ -16,19 +17,19 @@ import (

// ListIngresses will look for Ingress resources in the given namespace that match the given filters and return them.
// This will fail the test if there is an error.
func ListIngresses(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) []extensionsv1beta1.Ingress {
func ListIngresses(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) []networkingv1.Ingress {
ingresses, err := ListIngressesE(t, options, filters)
require.NoError(t, err)
return ingresses
}

// ListIngressesE will look for Ingress resources in the given namespace that match the given filters and return them.
func ListIngressesE(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) ([]extensionsv1beta1.Ingress, error) {
func ListIngressesE(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) ([]networkingv1.Ingress, error) {
clientset, err := GetKubernetesClientFromOptionsE(t, options)
if err != nil {
return nil, err
}
resp, err := clientset.ExtensionsV1beta1().Ingresses(options.Namespace).List(context.Background(), filters)
resp, err := clientset.NetworkingV1().Ingresses(options.Namespace).List(context.Background(), filters)
if err != nil {
return nil, err
}
Expand All @@ -38,23 +39,23 @@ func ListIngressesE(t testing.TestingT, options *KubectlOptions, filters metav1.

// GetIngress returns a Kubernetes Ingress resource in the provided namespace with the given name. This will fail the
// test if there is an error.
func GetIngress(t testing.TestingT, options *KubectlOptions, ingressName string) *extensionsv1beta1.Ingress {
func GetIngress(t testing.TestingT, options *KubectlOptions, ingressName string) *networkingv1.Ingress {
ingress, err := GetIngressE(t, options, ingressName)
require.NoError(t, err)
return ingress
}

// GetIngressE returns a Kubernetes Ingress resource in the provided namespace with the given name.
func GetIngressE(t testing.TestingT, options *KubectlOptions, ingressName string) (*extensionsv1beta1.Ingress, error) {
func GetIngressE(t testing.TestingT, options *KubectlOptions, ingressName string) (*networkingv1.Ingress, error) {
clientset, err := GetKubernetesClientFromOptionsE(t, options)
if err != nil {
return nil, err
}
return clientset.ExtensionsV1beta1().Ingresses(options.Namespace).Get(context.Background(), ingressName, metav1.GetOptions{})
return clientset.NetworkingV1().Ingresses(options.Namespace).Get(context.Background(), ingressName, metav1.GetOptions{})
}

// IsIngressAvailable returns true if the Ingress endpoint is provisioned and available.
func IsIngressAvailable(ingress *extensionsv1beta1.Ingress) bool {
func IsIngressAvailable(ingress *networkingv1.Ingress) bool {
// Ingress is ready if it has at least one endpoint
endpoints := ingress.Status.LoadBalancer.Ingress
return len(endpoints) > 0
Expand All @@ -81,3 +82,75 @@ func WaitUntilIngressAvailable(t testing.TestingT, options *KubectlOptions, ingr
)
logger.Logf(t, message)
}

// ListIngressesV1Beta1 will look for Ingress resources in the given namespace that match the given filters and return
// them, using networking.k8s.io/v1beta1 API. This will fail the test if there is an error.
func ListIngressesV1Beta1(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) []networkingv1beta1.Ingress {
ingresses, err := ListIngressesV1Beta1E(t, options, filters)
require.NoError(t, err)
return ingresses
}

// ListIngressesV1Beta1E will look for Ingress resources in the given namespace that match the given filters and return
// them, using networking.k8s.io/v1beta1 API.
func ListIngressesV1Beta1E(t testing.TestingT, options *KubectlOptions, filters metav1.ListOptions) ([]networkingv1beta1.Ingress, error) {
clientset, err := GetKubernetesClientFromOptionsE(t, options)
if err != nil {
return nil, err
}
resp, err := clientset.NetworkingV1beta1().Ingresses(options.Namespace).List(context.Background(), filters)
if err != nil {
return nil, err
}
return resp.Items, nil

}

// GetIngressV1Beta1 returns a Kubernetes Ingress resource in the provided namespace with the given name, using
// networking.k8s.io/v1beta1 API. This will fail the test if there is an error.
func GetIngressV1Beta1(t testing.TestingT, options *KubectlOptions, ingressName string) *networkingv1beta1.Ingress {
ingress, err := GetIngressV1Beta1E(t, options, ingressName)
require.NoError(t, err)
return ingress
}

// GetIngressV1Beta1E returns a Kubernetes Ingress resource in the provided namespace with the given name, using
// networking.k8s.io/v1beta1.
func GetIngressV1Beta1E(t testing.TestingT, options *KubectlOptions, ingressName string) (*networkingv1beta1.Ingress, error) {
clientset, err := GetKubernetesClientFromOptionsE(t, options)
if err != nil {
return nil, err
}
return clientset.NetworkingV1beta1().Ingresses(options.Namespace).Get(context.Background(), ingressName, metav1.GetOptions{})
}

// IsIngressAvailableV1Beta1 returns true if the Ingress endpoint is provisioned and available, using
// networking.k8s.io/v1beta1 API.
func IsIngressAvailableV1Beta1(ingress *networkingv1beta1.Ingress) bool {
// Ingress is ready if it has at least one endpoint
endpoints := ingress.Status.LoadBalancer.Ingress
return len(endpoints) > 0
}

// WaitUntilIngressAvailableV1Beta1 waits until the Ingress resource has an endpoint provisioned for it, using
// networking.k8s.io/v1beta1 API.
func WaitUntilIngressAvailableV1Beta1(t testing.TestingT, options *KubectlOptions, ingressName string, retries int, sleepBetweenRetries time.Duration) {
statusMsg := fmt.Sprintf("Wait for ingress %s to be provisioned.", ingressName)
message := retry.DoWithRetry(
t,
statusMsg,
retries,
sleepBetweenRetries,
func() (string, error) {
ingress, err := GetIngressV1Beta1E(t, options, ingressName)
if err != nil {
return "", err
}
if !IsIngressAvailableV1Beta1(ingress) {
return "", IngressNotAvailableV1Beta1{ingress: ingress}
}
return "Ingress is now available", nil
},
)
logger.Logf(t, message)
}
8 changes: 4 additions & 4 deletions modules/k8s/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestGetIngressEReturnsErrorForNonExistantIngress(t *testing.T) {
t.Parallel()

options := NewKubectlOptions("", "", "default")
_, err := GetIngressE(t, options, "i-dont-exist")
_, err := GetIngressV1Beta1E(t, options, "i-dont-exist")
require.Error(t, err)
}

Expand All @@ -39,7 +39,7 @@ func TestGetIngressEReturnsCorrectIngressInCorrectNamespace(t *testing.T) {
KubectlApplyFromString(t, options, configData)
defer KubectlDeleteFromString(t, options, configData)

service := GetIngress(t, options, "nginx-service-ingress")
service := GetIngressV1Beta1(t, options, "nginx-service-ingress")
require.Equal(t, service.Name, "nginx-service-ingress")
require.Equal(t, service.Namespace, uniqueID)
}
Expand All @@ -53,7 +53,7 @@ func TestListIngressesReturnsCorrectIngressInCorrectNamespace(t *testing.T) {
KubectlApplyFromString(t, options, configData)
defer KubectlDeleteFromString(t, options, configData)

ingresses := ListIngresses(t, options, metav1.ListOptions{})
ingresses := ListIngressesV1Beta1(t, options, metav1.ListOptions{})
require.Equal(t, len(ingresses), 1)

ingress := ingresses[0]
Expand All @@ -70,7 +70,7 @@ func TestWaitUntilIngressAvailableReturnsSuccessfully(t *testing.T) {
KubectlApplyFromString(t, options, configData)
defer KubectlDeleteFromString(t, options, configData)

WaitUntilIngressAvailable(t, options, ExampleIngressName, 60, 5*time.Second)
WaitUntilIngressAvailableV1Beta1(t, options, ExampleIngressName, 60, 5*time.Second)
}

const EXAMPLE_INGRESS_DEPLOYMENT_YAML_TEMPLATE = `---
Expand Down
4 changes: 0 additions & 4 deletions modules/terraform/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ func InitAndApplyE(t testing.TestingT, options *Options) (string, error) {
return "", err
}

if _, err := GetE(t, options); err != nil {
return "", err
}

return ApplyE(t, options)
}

Expand Down
4 changes: 0 additions & 4 deletions modules/terraform/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ func InitAndPlanE(t testing.TestingT, options *Options) (string, error) {
return "", err
}

if _, err := GetE(t, options); err != nil {
return "", err
}

return PlanE(t, options)
}

Expand Down
4 changes: 0 additions & 4 deletions modules/terraform/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,5 @@ func InitAndValidateE(t testing.TestingT, options *Options) (string, error) {
return "", err
}

if _, err := GetE(t, options); err != nil {
return "", err
}

return ValidateE(t, options)
}

0 comments on commit aa512af

Please sign in to comment.