AWS Route53 - Adding Simple Record - go

I am able to add "Weighted" A records for the AWS Route53 using the API, using [Weight: aws.Int64(weight)], it works great using the code below. But how to add "Simple" A record - I did not see an option for Simple?
params := &route53.ChangeResourceRecordSetsInput{
ChangeBatch: &route53.ChangeBatch{ // Required
Changes: []*route53.Change{ // Required
{ // Required
Action: aws.String("UPSERT"), // Required
ResourceRecordSet: &route53.ResourceRecordSet{ // Required
Name: aws.String(name), // Required
Type: aws.String("A"), // Required
ResourceRecords: []*route53.ResourceRecord{
{ // Required
Value: aws.String(target), // Required
},
},
TTL: aws.Int64(TTL),
//Region: aws.String("us-east-1"),
Weight: aws.Int64(weight),
SetIdentifier: aws.String("-"),
},
},
},
Comment: aws.String("Sample update."),
},
HostedZoneId: aws.String(zoneId), // Required
}

A 'Simple' record is just a phrasing inside the Web Console. Just leave the record without any Weight or Latency flag and it will be a standard DNS record inside Route53.
See the type ResourceRecordSet documentation, required fields are marked. The rest, like Weight are optional!
https://docs.aws.amazon.com/sdk-for-go/api/service/route53/#ResourceRecordSet
Pretty much the same as using the CLI (https://aws.amazon.com/premiumsupport/knowledge-center/simple-resource-record-route53-cli/), just port the same fields to the Go struct.

after a couple of hours of searching that lead nowhere, I found that using the aws-sdk-go-v2 works well for adding a simple record, trying to not add a weight or latency flag will only result in an error while using the version 1 of the SDK, so I did this and worked fine:
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
// handle error
return err
}
client := route53.NewFromConfig(cfg)
params := &route53.ChangeResourceRecordSetsInput{
ChangeBatch: &types.ChangeBatch{
Changes: []types.Change{
{
Action: types.ChangeActionUpsert,
ResourceRecordSet: &types.ResourceRecordSet{
Name: aws.String(name),
Type: types.RRTypeCname,
ResourceRecords: []types.ResourceRecord{
{
Value: aws.String(target),
},
},
TTL: aws.Int64(60),
},
},
},
},
HostedZoneId: aws.String(zoneId),
}
output, err := client.ChangeResourceRecordSets(context.TODO(), params)

Related

How to set null config values in helm charts via pulumi

I'm trying to configure a helm chart via pulumi and golang. According to the helm chart documentation default components can be removed by setting the config to null. I managed to set the desired config values for the helm chart in my pulumi script, but it's not possible to set config values to null.
Update:
It seems that the custom abstraction layer on top of the pulumi helm chart resource could not handle the config. I have added a minimal working example which uses the helm chart resource directly and its working as expected:
package main
import (
helmv3 "github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes/helm/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := helmv3.NewChart(ctx, "otel-collect", helmv3.ChartArgs{
Chart: pulumi.String("opentelemetry-collector"),
Version: pulumi.String("0.31.1"),
FetchArgs: helmv3.FetchArgs{
Repo: pulumi.String("https://open-telemetry.github.io/opentelemetry-helm-charts"),
},
Values: pulumi.Map{
"fullnameOverride": pulumi.String("otel-collector"),
"mode": pulumi.String("deployment"),
"config": pulumi.Map{
"receivers": pulumi.Map{
"jaeger": pulumi.Map{
"protocols": pulumi.Map{
"thrift_compact": nil,
},
},
"prometheus": nil,
},
"service": pulumi.Map{
"pipelines": pulumi.Map{
"metrics": nil,
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
In this scenario I want to set the prometheus config to null but when this chart is deployed the default values for prometheus are set. I have also tried "prometheus": pulumi.Any(nil), but this also does not change the config.
The issue was caused by an abstraction layer I put on top of the pulumi helm resources.

How to return value from the Looker Golang sdk

I'm attempting to perform the run inline query api endpoint using the Looker Golang SDK. https://github.com/looker-open-source/sdk-codegen/blob/474ee9365dafe6549826a9f627ac0a79dc0e9a56/go/sdk/v4/models.go
https://developers.looker.com/api/explorer/4.0/methods/Query/run_inline_query
However when I execute this I get a blank response back not the expected data from fmt.Println(response). I also attempted to create and run, a sql query, while it looked like the API call executed I didn't receive any results in a very similar fashion. I feel like i'm missing something in getting results. I've validated these queries run in Looker.
Massive disclaimer, I'm a beginner to Golang. I'd really appreciate anyone being able to tell me what i'm doing wrong here.
func getDashboards(sdk *looker.LookerSDK) error {
fields := []string{
"dashboard.id",
"dashboard_element.id",
"dashboard_element.type",
"dashboard_element.result_source",
"query.model",
"query.view",
"query.formatted_fields",
"query.id",
"dashboard.title",
"look.id"}
limit := "5000"
response, err := sdk.RunInlineQuery(
looker.RequestRunInlineQuery{
ResultFormat: "json",
Body: looker.WriteQuery{
Model: "system__activity",
View: "dashboard",
Fields: &fields,
Limit: &limit,
},
}, nil)
if err != nil {
fmt.Println(err)
}
fmt.Println(response)
return err
}

How can I test validation functionality in a terraform provider

I have written some more sophisticated validation logic for fields I need to validate in a custom terraform provider. I can, of course, test these are unit tests, but that's insufficient; why if I forgot to actually apply the validator?
So, I need to actually use terraform config and have the provider do it's normal, natural thing.
Basically, I expect it to error. The documentation seems to indicate that I should do a regex match on the output. But this can't be right; it seems super brittle. Can someone tell me how this is done?
func TestValidation(t *testing.T) {
const userBasic = `
resource "my_user" "dude" {
name = "the.dude%d"
password = "Password1" // needs a special char to pass
email = "the.dude%d#domain.com"
groups = [ "readers" ]
}
`
rgx, _ := regexp.Compile("abc")
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: userBasic,
ExpectError: rgx,
},
},
})
}
This code obviously doesn't work. And, a lot of research isn't yielding answers.
Since sdk version 2.3.0 you can set ErrorCheck function on resource.TestCase to provide more complex validation for errors.
For example:
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
ErrorCheck: func(err error) error {
if err == nil {
return errors.New("expected error but got none")
}
// your validation code here
// some simple example with string matching
if strings.Contains(err.Error(), "your expected error message blah") {
return nil
}
// return original error if no match
return err
},
Steps: []resource.TestStep{
{
Config: userBasic,
},
},
})

Make a resource schema dependant on another variable

I'm creating a plugin in Terraform and I want to add a field to the schema which can be called only when another field has been provided.
"host_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("host_name", nil),
Description: "Should give name in FQDN if being used for DNS puposes .",
},
"enableDns": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("host_name", nil),
Description: "Should give name in FQDN if being used for DNS puposes .",
Here I want to pass the enableDns string in the .tf file only when host_name is passed. If it is not given and I pass enableDns it should throw an error during plan.
Terraform providers don't really have a first class way to do stuff conditionally based on other parameters other than the ConflictsWith attribute.
There is a hacky way to do some cross parameter stuff using CustomizeDiff but it's only really used in a couple of places where it's really needed.
Normally the provider would simply validate the individual parameters and if the API that the provider is working against requires cross parameter validation then this is only seen at apply time when the API returns the error.
For an example of using CustomizeDiff to throw a plan time error when doing cross parameter validation see the aws_elasticache_cluster resource:
CustomizeDiff: customdiff.Sequence(
func(diff *schema.ResourceDiff, v interface{}) error {
// Plan time validation for az_mode
// InvalidParameterCombination: Must specify at least two cache nodes in order to specify AZ Mode of 'cross-az'.
if v, ok := diff.GetOk("az_mode"); !ok || v.(string) != elasticache.AZModeCrossAz {
return nil
}
if v, ok := diff.GetOk("num_cache_nodes"); !ok || v.(int) != 1 {
return nil
}
return errors.New(`az_mode "cross-az" is not supported with num_cache_nodes = 1`)
},

kubernetes filter objects in Informer

Im writing custom controller for kubernetes.
Im creating shared informer
cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options meta_v1.ListOptions) (k8sruntime.Object, error) {
return client.CoreV1().ConfigMaps(nameSpace).List(options)
},
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
return client.CoreV1().ConfigMaps(nameSpace).Watch(options)
},
},
&api_v1.ConfigMap{},
0, //Skip resyncr
cache.Indexers{},
)
I have option to add filtering function into call back functions to further decrease number of objects im working with.
Something like that
options.FieldSelector := fields.OneTermEqualSelector("metadata.name", nodeName).String()
I would like to filter out objects by regular expression. Or by some label at least. Unfortunately documentation is not helping. Could not find anything except for tests for code itself.
Ho do i apply regular expression on filtering mechanism?
Where do i get some examples on this issue?
Its not possible to filter objects by regular expression.
It is possible to filer object by lable
This is the code that will filter by label
labelSelector := labels.Set(map[string]string{"mylabel": "ourdaomain1"}).AsSelector()
informer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options meta_v1.ListOptions) (k8sruntime.Object, error) {
options.LabelSelector = labelSelector.String()
return client.CoreV1().ConfigMaps(nameSpace).List(options)
},
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
options.LabelSelector = labelSelector.String()
return client.CoreV1().ConfigMaps(nameSpace).Watch(options)
},
},
&api_v1.ConfigMap{},
0, //Skip resyncr
cache.Indexers{},
)
Another thing that is important to remember is how do you add new objects to k8s
I was doing something like
kubectl --namespace==ourdomain1 create configmap config4 -f ./config1.yaml
This is not good. It overwrites all the fields in config map and puts whole file content into data of the new object.
Proper way is
kubectl create -f ./config1.yam

Resources