Terraform variable validation Terraform v0.13 with length & Substr - validation

Terraform variable validation using length function
Getting error while using length function & substr for vswitch_ids
Condition - vswitch_name value must start with vsw-
variable "vswitch_ids" {
description = "The vswitch IDs."
type = list(string)
validation {
condition = (
length(var.vswitch_ids) > 0 &&
substr(var.switch_ids, 0, 4) == "vsw-"
)
error_message = "The vswitch_name value must start with \"vsw-\"."
}
}
Error: Invalid function argument
on modules/k8s/variables.tf line 34, in variable "vswitch_ids":
34: substr(var.vswitch_ids, 0, 4) == "vsw-"
|----------------
| var.vswitch_ids is list of string with 3 elements
Invalid value for "str" parameter: string required.

The following should work. It will check if all elements in your variable list start with vsw:
variable "vswitch_ids" {
description = "The vswitch IDs."
type = list(string)
validation {
condition = (
length(var.vswitch_ids) > 0 &&
length([for v in var.vswitch_ids: 1 if substr(v, 0, 4) == "vsw-"]) == length(var.vswitch_ids)
)
error_message = "The vswitch_name value must start with \"vsw-\"."
}
}

Related

How can I interpolate a random octet into a CIDR block in Terraform?

I have the following random_test.tf Terraform file, which I've successfully initialized:
resource "random_integer" "octet" {
min = 0
max = 255
}
variable "base_cidr_block" {
description = "Class A CIDR block in RFC 1918 range"
default = "10.0.0.0/8"
}
provider "null" {
base_cidr_block = "10.${random_integer.octet.result}.0.0/16"
}
output "ip_block" {
value = var.base_cidr_block
}
I'm using the null provider as a placeholder to test defining a 10.0.0.0/16 CIDR block with a random second octet. However, base_cidr_block is always 10.0.0.0/8 even though I'm expecting it to be assigned something like 10.100.0.0/16, which would then be shown on standard output as ip_block. Instead, I always get the default:
$ terraform plan
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# random_integer.octet will be created
+ resource "random_integer" "octet" {
+ id = (known after apply)
+ max = 255
+ min = 0
+ result = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ ip_block = "10.0.0.0/8"
Running terraform apply then always sends ip_block = "10.0.0.0/8" to the console. What am I doing wrong?
Here's what I've come up with, although I may not understand the intent.
First, I've created a module. I'm using the random_integer, and setting a keeper:
variable "netname" {
default = "default"
}
variable "subnet" {
default = "10.0.0.0/8"
}
resource "random_integer" "octet" {
min = 0
max = 255
keepers = {
netname = var.netname
}
}
output "rand" {
value = random_integer.octet.result
}
output "random-subnet" {
value = "${cidrsubnet("${var.subnet}", 8, random_integer.octet.result)}"
}
Next I call the module, passing in my keeper, and optionally the subnet:
module "get-subnet-1" {
source = "./module/"
netname = "subnet-1"
}
output "get-subnet-1" {
value = module.get-subnet-1.random-subnet
}
module "get-subnet-2" {
source = "./module/"
netname = "subnet-2"
}
output "get-subnet-2" {
value = module.get-subnet-2.random-subnet
}
Finally, my output:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
get-subnet-1 = 10.2.0.0/16
get-subnet-2 = 10.6.0.0/16

How to create autoincrement variable Odoo POS

I'm working on these files to add a custom autoincrement value to each pos ticket generated in odoo v10:
Point_of_sale es el modulo
.. \addons\point_of_sale\static\src\js\ models.js
.. \addons\pos_ticket\static\src\xml\pos_ticket_view.xml
odoo code:
Model.js
order_id_ : function (){
var x = 1;
if(this.pos.order.id)
{
x = this.pos.order.id++;
}
else
{
x = x++;
}
function sequense(num)
{
var s = ""+ num;
while (s.length < 8)
{
s = "0" + s;
}
return s;
}
return sequense(x);
},
pos_ticket_view.xml
<t t-esc="order.order_id_()" / >
But when I run it like this I get this error because the variable isn't yet created:
Your if statement can't be processed if one of the earlier variables don't exist.
Instead of:
if(this.pos.order.id)
You should ensure the early variables exist, like so:
if(this.pos && this.pos.order && this.pos.order.id)
If pos or pos.order is not set, it should stop evaluating the if statement and you should no longer receive an error.

Swift distance() method throws fatal error: can not increment endIndex

I was trying to find a substring match in a string, and get the matched position.
I can't figure out what's wrong with the following code:
let str1 = "hello#゚Д゚"
let cmp = "゚Д゚"
let searchRange = Range(start: str1.startIndex, end: str1.endIndex)
let range = str1.rangeOfString(cmp, options: .allZeros, range: searchRange)
println("\(searchRange), \(range!)") // output: 0..<9, 6..<9
let dis = distance(searchRange.startIndex, range!.startIndex) // fatal error: can not increment endIndex! reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
// let dis = distance(searchRange.startIndex, range!.endIndex) // This will go and output: distance=7
println("distance=\(dis)")
As the comments suggested, although the range had valid values, the distance() method threw a fatal error.
If I'm wrong about the use of distance(), what method should I use to archive the target?
Any advice would be helpful. Thanks.
range!.startIndex points here:
"hello#゚Д゚"
^
But, in this case, #゚ is a single character in Swift.
Therefore, This code:
for var idx = searchRange.startIndex; idx != range!.startIndex; idx = idx.successor() {
println("\(idx): \(str1[idx])");
}
prints:
0: h
1: e
2: l
3: l
4: o
5: #゚
7: Д゚
fatal error: Can't form a Character from an empty String
// and emits BAD_INSTRUCTION exception
As you can see range!.startIndex never matches to the character boundaries, and the for loop run out the string. That's why you see the exception.
In theory, since String is considered as "Collection of Characters" in Swift, "゚Д゚" should not be a substring of "hello#゚Д゚".
I think .rangeOfString() uses NSString implementation which treats string as a sequence of unichar. I don't know this should be considered as a bug or not.
Try this:
func search<C: CollectionType where C.Generator.Element: Equatable>(col1: C, col2: C) -> C.Index? {
if col2.startIndex == col2.endIndex {
return col1.startIndex
}
var col1Ind = col1.startIndex
while col1Ind != col1.endIndex {
var ind1 = col1Ind
var ind2 = col2.startIndex
while col1[ind1] == col2[ind2] {
++ind1; ++ind2
if ind2 == col2.endIndex { return col1Ind }
if ind1 == col1.endIndex { return nil }
}
++col1Ind
}
return nil
}
Searches for the first instance of the col2 sequence in col1. If found, returns the index of the start of the sub-sequence. If not found, returns nil. If col2 is empty, returns the startIndex of col1.

Checking for TPM readiness with WMI and VBSCRIPT

If I am using this WMI method '.IsEnabled' should I be concerned with how I am handling the results in my if statement. If a method returns a bool value can I still use a Not or should I do something like
if myStatus <> 0 OR isTPMEnabled <> True then
Here is my code
function isTPMReadyToBeOwned(myTPMService)
dim myStatus, isTPMEnabled, isTPMActivated, isTPMOwnershipAllowed
myStatus = myTPMService.IsEnabled(isTPMEnabled)
if myStatus <> 0 or not(isTPMEnabled) then
oLogging.CreateEntry "TPM isn't enable and must be enabled and activated manually, errorcode " & Hex(myStatus), LogTypeWarning
isTPMReadyToBeOwned = False
exit Function
end If
myStatus = myTPMService.IsActivated(isTPMActivated)
If myStatus <> 0 or not(isTPMActivated) then
oLogging.CreateEntry "TPM isn't active and must be activated manually, errorcode " & Hex(myStatus), LogTypeWarning
isTPMReadyToBeOwned = False
exit Function
end If
myStatus = myTPMService.isOwnershipAllowed(isTPMOwnershipAllowed)
if myStatus <> 0 or not(isTPMOwnershipAllowed) then
oLogging.CreateEntry "TPM ownership is not allowed, errorcode " & Hex(myStatus), LogTypeWarning
isTPMReadyToBeOwned = False
exit Function
end If
isTPMReadyToBeOwned = True
end Function
Boolean expressions/variables shouldn't be compared to boolean literal, because it adds an extra level of complexity (operator and operand). So use Not isTPMEnabled. As Not is neither a function nor an array, don't use param list/index (); reserve () for cases of precedence override.
Update wrt comment:
() have (too) many functions in VBScript
parameter list () in function calls: x = f(y, z)
index (): a = SomeArray(4711)
precedence override: 2 + 3 * 4 = 14, (2 + 3) * 5 = 25
() in boolean expression should be of type 3 only.

LINQ attempts to truncate variable value to length of comparison

The where clause in the LINQ statement below causes the following error when 'logLevel' has a value of "Error"
Error message = An error occurred while executing the command definition. See the inner exception for details.
Inner exception = p_linq_2 : String truncation: max=3, len=5, value='Error'
If I change && (logLevel == "All" || logLevel == "Error") to && (logLevel == "Error") the error no longer occurs.
It seems that to do the comparison against "All", LINQ tries to truncate the value in 'logLevel' to 3 characters first?
What is going on here?
(I'm running MVC 4, SQL CE 4)
IQueryable<LogEvent> list = (from a in _context.ELMAH_Error
where a.TimeUtc >= start && a.TimeUtc <= end
&& (logLevel == "All" || logLevel == "Error")
select new LogEvent
{
IdType = "guid", Id = "",IdAsInteger = 0,IdAsGuid = a.ErrorId,LoggerProviderName = "Elmah",LogDate = a.TimeUtc,MachineName = a.Host,Message = a.Message,Type = a.Type,Level = "Error",Source = a.Source,StackTrace = ""
});

Resources