How to start %index% with 1 in OS::Heat::ResourceGroup - openstack-heat

I use %index% in OS::Heat::ResourceGroup and it starts with a 0 value.
I want it to start with the value of 1. How to do it?
resources:
server_group:
type: OS::Heat::ResourceGroup
properties:
count: 3
resource_def:
type: OS::Nova::Server
name: { get_param: [ server_names, '%index%' ] }
I tried with '%index% + 1' but it did not work:
Error return: invalid literal for int() with base 10: '0 + 1'

Related

Getting empty merged list when trying to merge two dict lists with multiple when conditions in Ansible

here are my two list -
listone -
list1":
[
{
"_ref": "LAB1/1/4094",
"vlan_id": 12,
"vlan_name": "test_vlan_1",
"vlan_subnet": "192.168.1.0/28",
"vlan_vrf": "vrf_1"
},
{
"_ref": "LAB2/1/4094",
"vlan_id": 12,
"vlan_name": "test_vlan_1",
"vlan_subnet": "192.168.2.0/28",
"vlan_vrf": "vrf_1"
}
]
secondlist -
"list2":
[
{
"_ref": "LAB1/1/4094",
"vlan_id": "12",
"vlan_name": "test_vlan_1",
"vlan_ref": "vlan/ZG5zLnZsYW4kLmNvbS5pbmZvYmxveC5kbnMudmxhbl92aWV3JElORlJBTEFCLjEuNDA5NC4xMg:LAB1/test_vlan_1/12"
}
]
- name: merge lists final
set_fact:
merged_list: "{{ merged_list|default([]) + [ item[0] | union(item[1]) ] }}"
when: item[0]._ref == item[1]._ref and item[0].vlan_id == item[1].vlan_id and item[0].vlan_name == item[1].vlan_name
loop: "{{ query('nested', list1, list2) }}"
- name: print results
debug:
var: merged_list
I get output as:
TASK [print results] ***********************************************************
ok: [localhost] => {
"merged_list": "VARIABLE IS NOT DEFINED!"
}
desired output: in below, if you notice list2 has a match with list1 first dict item so list2 item merged with list1 first item, in the final output i want merged with a match and also unmatched item of list1 which is second one.
"merged_list":
[
{
"_ref": "LAB1/1/4094",
"vlan_id": 12,
"vlan_name": "test_vlan_1",
"vlan_subnet": "192.168.1.0/28",
"vlan_vrf": "vrf_1",
"vlan_ref": "vlan/ZG5zLnZsYW4kLmNvbS5pbmZvYmxveC5kbnMudmxhbl92aWV3JElORlJBTEFCLjEuNDA5NC4xMg:LAB1/test_vlan_1/12"
},
{
"_ref": "LAB2/1/4094",
"vlan_id": 12,
"vlan_name": "test_vlan_1",
"vlan_subnet": "192.168.2.0/28",
"vlan_vrf": "vrf_1"
}
]
i believe when: item[0]._ref == item[1]._ref and item[0].vlan_id == item[1].vlan_id and item[0].vlan_name == item[1].vlan_name condition is not working as i expected. Any suggestions/clue to make this work and get merged_list as the way i am looking for.
The items in the lists are dictionaries. You need the filter combine to merge them. For example, the playbook below (simplified for testing)
- hosts: localhost
vars:
list1:
- {_ref: ZG5, name: LAB1, vlan_id: 12, vlan_name: test_vlan_1}
- {_ref: XXX, name: LAB2, vlan_id: 12, vlan_name: test_vlan_1}
- {_ref: YYY, name: LAB3, vlan_id: 13, vlan_name: test_vlan_1}
list2:
- {_ref: ZG5, vlan_id: 12, vlan_name: test_vlan_1, vlan_ref: vlan/ZG5}
tasks:
- set_fact:
merged_list: "{{ merged_list|d([]) + [_item] }}"
loop: "{{ query('nested', list1, list2) }}"
vars:
_conditions:
- "{{ item.0._ref == item.1._ref }}"
- "{{ item.0.vlan_id == item.1.vlan_id }}"
- "{{ item.0.vlan_name == item.1.vlan_name }}"
_item: "{{ _conditions is all|ternary(item.0|combine(item.1), item.0) }}"
- debug:
var: merged_list
gives
merged_list:
- {_ref: ZG5, name: LAB1, vlan_id: 12, vlan_name: test_vlan_1, vlan_ref: vlan/ZG5}
- {_ref: XXX, name: LAB2, vlan_id: 12, vlan_name: test_vlan_1}
- {_ref: YYY, name: LAB3, vlan_id: 13, vlan_name: test_vlan_1}

GKE Creation from Cloud Deployment Manager

Waiting for create [operation-1544424409972-57ca55456bd22-84bb0f13-64975fdc]...failed.
ERROR: (gcloud.deployment-manager.deployments.create) Error in Operation [operation-1544424409972-57ca55456bd22-84bb0f13-64975fdc]: errors:
- code: CONDITION_NOT_MET
location: /deployments/infrastructure/resources/practice-gke-clusters->$.properties->$.cluster.name
message: |-
InputMapping for field [cluster.name] for method [create] could not be set from input, mapping was: [$.ifNull($.resource.properties.cluster.name, $.resource.name)
], and evaluation context was:
{
"deployment" : {
"id" : 4291795636642362677,
"name" : "infrastructure"
},
"intent" : "CREATE",
"matches" : [ ],
"project" : "resources-practice",
"requestId" : "",
"resource" : {
"name" : "practice-gke-clusters",
"properties" : {
"initialNodeCount" : 1,
"location" : "asia-east2-a",
"loggingService" : "logging.googleapis.com",
"monitoringService" : "monitoring.googleapis.com",
"network" : "$(ref.practice-gke-network.selfLink)",
"subnetwork" : "$(ref.practice-gke-network-subnet-1.selfLink)"
},
"self" : { }
}
}
I always experience this when I try to create a GKE out of deployment manager w/ the jinja template below
resources:
- name: practice-gke-clusters
type: container.v1.cluster
properties:
network: $(ref.practice-gke-network.selfLink)
subnetwork: $(ref.practice-gke-network-subnet-1.selfLink)
initialNodeCount: 1
loggingService: logging.googleapis.com
monitoringService: monitoring.googleapis.com
location: asia-east2-a
You are missing:
properties:
cluster:
name: practice-gke-clusters
initialNodeCount: 3
nodeConfig:
oauthScopes:
- https://www.googleapis.com/auth/compute
- https://www.googleapis.com/auth/devstorage.read_only
- https://www.googleapis.com/auth/logging.write
- https://www.googleapis.com/auth/monitoring
Modify the initialNodeCount and oauthScopes as required.

Fn::Sub expression does not resolve to a string

I have created a parameter:
Parameters:
..
list:
Description: "Provide a list .."
Type: CommaDelimitedList
Default: "test1, test2"
Now I want to reference this list (which will resolve in "test1", "test2", ..) from a file in my cloudformation which looks like this:
configure_xx:
files:
/etc/file.conf:
content: !Sub |
input {
logs {
log_group => [ "${list}" ]
access_key_id => "${logstashUserKey}"
secret_access_key => "${logstashUserKey.SecretAccessKey}"
region => "eu-west-1"
}
}
How can I make this work for the parameter list? (the keys work).
error: Fn::Sub expression does not resolve to a string
Just switch the parameter type for a "String"
Parameters:
..
list:
Description: "Provide a list .."
Type: String
Default: "test1, test2"
If, for some reason, you have no control over this parameter type, you could use Fn::Join to transform the list to a string. For exemple:
configure_xx:
files:
/etc/file.conf:
content:
Fn::Sub:
- |-
input {
logs {
log_group => [ "${joinedlist}" ]
access_key_id => "${logstashUserKey}"
secret_access_key => "${logstashUserKey.SecretAccessKey}"
region => "eu-west-1"
}
}
- joinedlist:
Fn::Join:
- ', '
- !Ref list

Filter data being passed into a crossfilter group without using dimensional filters

I'm trying to figure out how to add a filter onto a crossfilter group that is not related to a dimensional filter. Let's look at an example:
var livingThings = crossfilter({
// Fact data.
{ name: “Rusty”, type: “human”, legs: 2 },
{ name: “Alex”, type: “human”, legs: 2 },
{ name: “Lassie”, type: “dog”, legs: 4 },
{ name: “Spot”, type: “dog”, legs: 4 },
{ name: “Polly”, type: “bird”, legs: 2 },
{ name: “Fiona”, type: “plant”, legs: 0 }
}); //taken from http://blog.rusty.io/2012/09/17/crossfilter-tutorial/
if we were to make a dimension on type and a group of that dimension:
var typeDim = livingThings.dimension(function(d){return d.type});
var typeGroup = typeDim.group();
we would expect typeGroup.top(Infinity) to output
{{human:2},
{dog:2},
{bird:1},
{plant:1}}
My question is how can we filter the data such that they include only 4 legged creatures in this grouping? I also don't want to use dimension.filter... because i don't want this filter to be global, just for this one grouping. In other words
var filterDim = livingThings.dimension(function(d){return d.legs}).filterExact(4);
is not allowed.
I'm thinking of something similar to what I did to post-filter dimensions as in https://stackoverflow.com/a/30467216/4624663
basically I want to go into the internals of the typeDim dimension, and filter the data before it is passed into the groups. Creating a fake group that calls typeDim.group().top() will most likely not work as the individual livingThings records are already grouped by that point. I know this is tricky: thanks for any help.
V
Probably best to use the reduceSum functionality to create a pseudo-count group that only counts records with 4 or more legs:
var livingThings = crossfilter({
// Fact data.
{ name: “Rusty”, type: “human”, legs: 2 },
{ name: “Alex”, type: “human”, legs: 2 },
{ name: “Lassie”, type: “dog”, legs: 4 },
{ name: “Spot”, type: “dog”, legs: 4 },
{ name: “Polly”, type: “bird”, legs: 2 },
{ name: “Fiona”, type: “plant”, legs: 0 }
}); //taken from http://blog.rusty.io/2012/09/17/crossfilter-tutorial/
var typeDim = livingThings.dimension(function(d){return d.type});
var typeGroup = typeDim.group().reduceSum(function(d) {
return d.legs === 4 ? 1 : 0;
});
That will sum across a calculated value that will be 1 for records with 4 legs and 0 for records with ... not 4 legs. In other words, it should just count 4-legged creatures.
I think, this is what you are looking for. Comment back if I'm wrong.
var dimByLegs = livingThings.dimension(function(d){return d.legs});
dimByLegs.filterExact(4);
var dogs = dimByLegs.group();
dimByLegs.top(Infinity).forEach(function(d){console.log(d.type, d.legs);});
dimByLegs.dispose();

mongodb regex how to match image/*

I've got a schema like
var MediaSchema = new Schema({
created: {
type: Date,
default: Date.now
},
user: {
type: String,
default: 'whisher',
trim: true
},
title: {
type: String,
default: '',
trim: true
},
type: {
type: String,
default: '',
trim: true
},
url: {
type: String,
default: '',
trim: true
}
});
in type I can have
image/gif:
image/jpeg:
image/pjpeg:
image/png:
image/svg+xml:
image/example:
but also
application/pdf
video/mpeg
and so on
my goal is fetch all the rows which are images
so I tried with:
db.media.find( { type: /image/gif|jpeg|pjpeg|png/i } );
but give me
SyntaxError: Invalid flags supplied to RegExp constructor 'gif'
so what's the right way ?
Is there a better way of querying without using regex ?
You can use $regex operator as follows :
db.collection.find({type : {$regex : "^image/.*", $options : "i"}})
You can also query without using $regex operator as follows :
db.collection.find({type : /.*image.*/i})
If this query is frequent, I'd recommend you add a new field that more closely maps to your requirement:
isImage : Boolean
Or, a bit more general if you'd like:
typeGroup: Number
You would index either one. typeGroup might be set to a 1 for example if it was an image of any type, or 2 if it was a video file, etc.
Performing a regular expression to match the files repeatedly to answer the same question will measurably affect the overall performance of your application. With this alternative approach, you can easily find the correct documents efficiently:
Media.find().where('isImage', true).exec(/* your callback */);
db.media.find( { type: /image\/gif|jpeg|pjpeg|png/i } );
but there is a better way ?