Graphviz: automatic variables? - graphviz

Suppose I define a node:
"somenode" [xlabel="somenode"]
Is there an automatic variable, as in make such that I can write, for example (in pseudo code) something like:
"somenode" [xlabel=$#]

You can use graphviz-py to make a variable.
Code
digraph g {
{{ some_node_name = "somenode" }}
"{{= some_node_name }}" [xlabel="{{= some_node_name }}"]
}
Output

If attribute supports type escString (which label attribute does) you can use \N for node name and \G for graph name. On edge label you can use \T for tail node name and \H for head node name.
digraph {
Node1 [xlabel="\N"]
Node2 -> Node3 [xlabel="\T" label="\H"]
}
Result:

Related

Depth first search on Neo4j with filtering on node properties

I would like to perform a depth first search on my graph and so, get all the paths existing from a given node ('N1456' in my example), and all the nodes of theses path must have the same property "PROPERTY_TO_FILTER".
Typically, my graph is composed of two types of node, and two types of relations.
For now, I tested the following request :
WITH "
MATCH (my_node{name : 'N1456'})
CALL apoc.path.expandConfig(protein, {uniqueness:'NODE_GLOBAL', bfs : FALSE}) YIELD path
WITH path, my_node, last(nodes(path)) as subgraph
WHERE my_node<> subgraph and my_node.my_property CONTAINS 'PROPERTY_TO_FILTER'
RETURN nodes(path), length(path) AS len
ORDER BY len DESC" AS query
CALL apoc.export.json.query(query, "my_results.json", {})
YIELD properties, data
RETURN properties, data;
However, the results are not the ones attended. I get a list of paths but only the first node has the property "PROPERTY_TO_FILTER" ; this filter is not taken into account for the other nodes...
I guess I should put a filter at apoc.path.expandConfig level, but I see in the documentation that this is only possible to filter the node label, not the node properties.
Could someone help please ?
Maybe this can help:
MATCH(fromNode:LABEL{name : 'N1456'})-[r:REL_TO_TRAVERSE*1..2]->(toNode:LABEL)
WHERE toNode.my_property CONTAINS 'PROPERTY_TO_FILTER'
RETURN fromNode,r,toNode
It's called variable length pattern matching:
https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-varlength

Jenkins - Put parameter in array

In a declarative pipeline I want user will choose list of machines and then some action will be executed on them in parallel.
I have an extendedChoice parameter with multiSelectDelimiter: ','
When I go over the list with this code below I get the characters of node and not entire node, how can I fix it ?
for (node in nodes) {
echo node
}
This should do it:
for (node in nodes.split(',')) {
echo node
}

how to build up terraform local_file dynamically

I want to create few EC2 instances and grab their private_ips into a ec2.ini style file for further use with Ansible.
resource "local_file" "ec2_id" {
count = var.instance_count
content = "${aws_instance.instance[count.index].private_ip} ansible_ssh_user=ec2-user\n"
filename = "ec2.ini"
}
This always prints the private_ip of latest EC2 instance created.
Any idea how to solve this.
Update:-
data "template_file" "hehe" {
count = var.instance_count
template = "${element(aws_instance.instance.*.private_ip, count.index)} ansible_ssh_user=ec2-user subnetmask=${element(split("/", data.aws_subnet.selected-subnet-id.cidr_block),1)}\n"
}
resource "local_file" "ec2_id" {
count = var.instance_count
content = "${element(data.template_file.hehe.*.rendered, count.index)}"
filename = "ec2.ini"
}
does not work. gives me the last created instance private_ip.
When you use count inside a resource you are asking Terraform to create multiple instances of that resource. However, in your case you didn't include count.index in the filename argument and so all of your instances are competing to overwrite the same filename ec2.ini, and so only one of them can "win".
It sounds like your goal is to create only one file that contains all of the IP addresses. This is very close to one of the examples that are in the Terraform String Templates documentation at the time I write this, which we can adapt to your goal like this:
resource "local_file" "ec2_iini" {
filename = "ec2.ini"
content = <<-EOT
%{ for ip in aws_instance.instance.*.private_ip ~}
${ip} ansible_ssh_user=ec2-user
%{ endfor ~}
EOT
}
In the above example the local_file resource itself does not have count set, because our goal is to create only one file. Instead, we use Terraform's template for directive to repeat a string template once per instance, gathering the result as a single string which local_file can then use as its content argument.
I used the "heredoc" style of string literal here because I think it makes the for directive easier to read by splitting it over multiple lines. The - in <<-EOT causes Terraform to look at all of the lines between the opening <<-EOT and the closing EOT and find the smallest number of leading spaces those lines have in common, which it will then strip off when rendering. That means that you can have the template indented in your configuration but avoid those indentations appearing in the rendered string, which should look something like this:
10.1.0.34 ansible_ssh_user=ec2-user
10.1.0.5 ansible_ssh_user=ec2-user
10.1.0.92 ansible_ssh_user=ec2-user
The ~ markers on the end of the two %{ ... } directives instruct Terraform's template engine to ignore the newline and whitespace after them, so we can wrap the template over multiple lines without introducing additional newlines into the result. The only line of the template that generates a trailing newline here is the middle line containing the IP address interpolation and the ansible_ssh_user portion, so the result ends up having only one newline per entry as seems to be intended here.

How to do nokogiri attribute selection?

I have many statements like this in my test.xml file
<House name="bla"><Room id="bla" name="black" ></Room></House>
How do I print all Rooms with name="black". I am using CSS selector but Only House and Room attributes are taken by the selector.
I started with trying to print all name's, doesn't matter House or Room.
nodes = doc.css("name"). But it gives null as the output. So I am not able to proceed.
In CSS you have a syntax for matching elements by an attribute key-val pair:
nodes = doc.css("[name='black']")
For future reference you can also chain attribute selectors
nodes = doc.css(".my-class[name='black'][foo='bar']")
Or omit the val and match any element where the attribute is present:
nodes = doc.css("[name]")

dot: dash in name

Is it possible to have a dash in the node name? I tried escaping with backslash (searching the web didn't helped either).
Example:
digraph test {
some-name -> other-name;
}
Just include the node names in double quotes like this:
digraph test {
"some-name" -> "other-name";
}
Since I faced the problem, the same goes for subgraphes names:
digraph G {
{node "A-1"}
{node "B"}
subgraph "A-1B" {edge [dir=none]"A-1" -> "B"}
}
You can also use identifier-like names (i.e. without spaces, dashes, etc.), but also provide a better name as a label attribute, by declaring node explicitly first.
digraph D {
nodeA [label="Node A"];
nodeB [label="Node B"];
nodeA -> nodeB;
}

Resources