Terraform variable validation for CIDR, looking alternative for regex
Below is the tested code in Terraform version 13.0
is there any alternative way to achieve same thing with not using regex?
cidr block - start 172.28.0.0.0/16
variable "vpc_cidr" {
description = "Kubernetes cluster CIDR notation for vpc."
validation {
condition = can(regex("^([0-9]{1,3}\\.){3}[0-9]{1,3}($|/(16))$", var.pod_cidr))
error_message = "Vpc_cidr value must be greater than 172.0.0.0/16."
}
}
how to validate CIDR block 172.28.x.x/16 with cidrsubnet function?
https://www.terraform.io/docs/language/functions/cidrsubnet.html
validation condition - if IP range is outof 172.28.x.x/16 then validation will be failed
I can't think of a direct way to achieve what you want with the functions in today's Terraform, but I think we can break the check into two conditions that, taken together, lead to the same effect:
The zeroth address in the subnet must be 172.28.0.0.
The netmask of the range must be 255.255.0.0.
We can test these two rules using two expressions:
cidrhost(var.vpc_cidr, 0) == "172.28.0.0"
cidrnetmask(var.vpc_cidr) == "255.255.0.0"
Both of these functions can fail if given something that isn't valid CIDR block syntax at all, and cidrnetmask will additionally fail if given an IPv6 address, so we can add try guards to both of them to turn that error into a false result as condition expects:
try(cidrhost(var.vpc_cidr, 0), null) == "172.28.0.0"
try(cidrnetmask(var.vpc_cidr), null) == "255.255.0.0"
The try function will return the result of the first expression that doesn't produce a dynamic error, so in the above examples an invalid input to the cidrhost or cidrnetmask function will cause an expression like null == "172.28.0.0", which will always be false and thus the condition will still not be met.
Finally, we can combine these together using the && operator to get the complete condition expression:
condition = (
try(cidrhost(var.vpc_cidr, 0), null) == "172.28.0.0" &&
try(cidrnetmask(var.vpc_cidr), null) == "255.255.0.0"
)
You have one 0 to many and it should be greater then 172.0.0.0/16. For example:
172.1.0.0/16
not:
172.0.0.0.0/16
A bit of hack, but still:
variable "vpc_cidr" {
validation {
condition = cidrsubnet("${var.pod_cidr}/16", 0, 0) == "172.28.0.0/16"
}
}
I prefer the solution from https://dev.to/drewmullen/terraform-variable-validation-with-samples-1ank
variable "string_like_valid_ipv4_cidr" {
type = string
default = "10.0.0.0/16"
validation {
condition = can(cidrhost(var.string_like_valid_ipv4_cidr, 32))
error_message = "Must be valid IPv4 CIDR."
}
}
Also note, as commented there, that the condition requires a modification to work for /32 addresses.
Related
If we want to execute a thread group with 2 concurrent users only when IP Address is not in (10.0.0.1, 10.0.0.2). How can we achieve this?
I have used below condition but its not working
${__groovy(if ((org.apache.jmeter.util.JMeterUtils.getLocalHostIP()!='10.0.0.1') || (org.apache.jmeter.util.JMeterUtils.getLocalHostIP()!='10.0.0.2')) return '2' else return '0',)}
I believe you need to change || operator to && operator
${__groovy(if ((org.apache.jmeter.util.JMeterUtils.getLocalHostIP()!='10.10.10.1') && (org.apache.jmeter.util.JMeterUtils.getLocalHostIP()!='10.0.0.2')) return '2' else return '0',)}
You can also consider slightly changing syntax so it would be more readable and it would be easier to add next IPs if needed:
${__groovy(if (['10.0.0.1'\, '10.0.0.2'].contains(org.apache.jmeter.util.JMeterUtils.getLocalHostIP())) return '0' else return '2',)}
More information:
Apache Groovy - Logical Operators
Apache Groovy - Why and How You Should Use It
I have a requirement in Go of altering the bool value and store it.
I am receiving value == true but I need to alter it and store the altered value.
I can think of only storing the alerted to a var and pass it in the next statement.
Eg psuedo code:
chnagevalue := false
if value == false {
changevalue == true
}
what's the best way to do it in Go? Is there any pre-defined way to do it?
Use the logical NOT operator ! to change true to false and vice versa:
changedValue := !value
There's a short answer, written somewhere else :-)
Yours is almost good too:
changedValue := false
if !value {
changedValue == true
}
An if statement is always about something being true.
so in the above it reads : if a value equals false is true then {}.
of course your mind reads it the short way :
if a value equals false then {}.
the switch of course works the best:
changedValue := !changedValue
BTW: I would never use a fieldname like "changedValue" because...
every variable is a value of some kind, so there is no need of writing that.
"changed" should be enough.
or, when it is a boolean like this , even better:
"isChanged" or "hasChanged"
I have such a piece of code:
std::map<int, int> mp;
// do something
auto itor = mp.find(some_value);
if (itor != mp.end() && itor->second == some_other_value) {
// do something
}
I'm worrying about which expression would be evaluated first, itor != mp.end() or itor->second == some_other_value?
If the second one is evaluated firstly (because of some compiler-optimization maybe?), it might get an undefined behavior because itor == mp.end() may be true.
Should I worry about this issue so that I have to code like this:
if (itor != mp.end) {
if (itor->second == some_other_value) {
// do something
}
}
No worries; your code is fine.
If the first condition of if (a && b) is false, then the second condition is not evaluated.
Look up "short-circuit evaluation"
Wikipedia has some info.
Logical And - && - expression is evaluated left to right so itor != mp.end() will be evaluated initially. Moreover, it returns true only if both expressions return true, hence if the first one is false the second one is not checked.
so the first case should work.
I'm working with a chart that has the following structure at the beginning but I'm having a hard time understanding when does this evaluate to true.
{{- if and .Values.vpceIngress.enabled .Values.http.paths (ne .Values.vpceIngress.class "traefik2") }}
I believe that both enabled and paths must be true, but the ne throws me off after that.
and and ne are functions in go templates.
and
Returns the boolean AND of its arguments by returning the
first empty argument or the last argument, that is,
"and x y" behaves as "if x then y else x". All the
arguments are evaluated.
ne
Returns the boolean truth of arg1 != arg2
So the template line equates to a more psuedo codish
if (
.Values.vpceIngress.enabled
&& .Values.http.paths
&& .Values.vpceIngress.class != "traefik2"
)
The truthiness of the plain .Value.key is basically a "is this field/key not the zero value for the data type. This also works for maps as 'is this field/key defined' due to a map without that path equating to nil or non value (Note that this only works when the parent map is actually defined! Otherwise the template errors)
Is it possible to add two conditions in while controller? My two conditions are Complete ="True" and Results >200.
I tried using it by setting Complete = False and Results=0 in user defined variables and used it in while controller as follows:
${__javaScript("${Complete}" != "true")} && ${__javaScript((parseInt(${Results}) >90)}.
But it is looping indefinitely. Please help.
Try the following condition (working for me):
${__jexl3("${Complete}" == "False" && ${Results} >= 0,)}
where Complete - False & Results - 0.
For above values, condition will be evaluated to true, hence executes the children of the While Controller.
Note: Please change the conditions == & >= symbols and values False && 0 as per your requirements.
You must reset the values inside the While Controller, to make the condition evaluated to false, otherwise you will struck in infinite loop.
References:
https://jmeter.apache.org/usermanual/component_reference.html#While_Controller
https://www.blazemeter.com/blog/using-while-controller-jmeter
For Multiple Condition in While Loop using Groovey Function for '&&' and '||' for the same field.
${__groovy(!(vars.get('ocrstatus_1').equals('500') || vars.get('ocrstatus_1').equals('1000')) ,)}