How to dynamically change autoscaling instance names - openstack

I have created a heat stack which autoscales depending on CPU use. Each time a new instance is created, it is given a random name.
Is there a way to set a specific name with a counter added to the end of it so that each time a new instance is created it increases by 1?
E.g. Myinstance1, Myinstance2, Myinstance3 ... MyinstanceX
Thanks in advance!

In Openstack HEAT, stack resource names are manipulated with stack_name and suffixed with a short_id. That's why on every autoscaled up instance you could see the instance name as such. This is how the implementation done in overall HEAT project and it is not possible to define instance name suffixed with incremental number.

if i understood you correctly, and if you are Object Oriented Programing:
you are looking for a design pattern called Factory, or more simply, create a static member that will increase in the constructor, and will be added to the name member of the instance created.

You can set the custom names by going to your Auto Scaling Groups and Tags tab, and then adding a tag with the key of "Name" and the value of "MyInstance". Numbering does not make that much sense since your instances are going to be launched and terminated constantly.

Update at 21/09/2020 :
Seems that creating an incremental number is impossible so far, but I found a workaround to achieve my goal, so post here hoping that could give you some ideas.
Mindset:
I tried to find something (which is number) that is created dynamically with the instance for scaling up, to me that is OS::Neutron::Port, so I append one part of IP address after a string to get a distinctive name for each instance.
Solution:
1.Create a port OS::Neutron::Port.
2.Get IP address using get_attr.
3.Split it with dot as delimiter using str_split.
4.Append one part of the address to the string using str_replace.
Sample Code:
lb_server.yaml
resources:
corey_port:
type: OS::Neutron::Port
properties:
network: { get_param: network }
fixed_ips:
- subnet: { get_param: subnet }
number:
type: OS::Heat::Value
properties:
value:
# 192.168.xxx.yyy => [192,168,xxx,yyy]
str_split: ['.', { get_attr: [corey_port, fixed_ips, 0, ip_address] }]
server:
type: OS::Nova::Server
properties:
name:
str_replace:
template: Corey-%last%
params:
# 0 1 2 3
#[192,168,xxx,yyy]
"last%": { get_attr: [number, value, 3] }
flavor: { get_param: flavor }
......
The outcome shoud be Corey-168, Corey-50, Corey-254, etc.

Related

Merging yaml documents together based on specific key in slice of maps in golang

Given the example below. I want to overlay B onto A based on the key type. So, if the same type exists in both A and B, then B will overwrite A, otherwise it just gets appended. If something exists in A, that doesn't exist in B, then it also gets appended to the slice.
A
service: myservice
contacts:
- type: slack
contact: https://slack.com/SDGSDF
- type: email
contact: email#email.com
B
service: myservice
contacts:
- type: slack
contact: https://slack.com/FVJTYSAFA
Overlay B on A
service: myservice
contacts:
- type: slack
contact: https://slack.com/FVJTYSAFA # Slack gets updated
- type: email # email gets appended to slice
contact: email#email.com
I have a tried a few things and It seems like there could be multiple ways to solve this problem.
custom Unmarshaler (seems like this could work). Where I would unmarshal the yaml and then unmarshal it again, but the second time merging it together. Not entirely sure if this is possible though.
Converting it to a map[string]interface{} and trying to just process it this way
Unmarshal each yaml document into a struct and then merge the structs together with reflect
Something I don't know yet?
I dug into unmarshaling both into a struct and then merging those structs. I got close, but get lost when using reflect and how I would go about doing what I want to do.
When I try using something like map[string]interface{}, I'm not sure how to dig deeper into the yaml object. For instance, I know I can do something like
var y1 = []byte(`
service: myservice
contacts:
- type: "slack"
contact: "https://slack.com/SDGSDF"
- type: "email"
contact: "email#email.com"
`)
func main() {
data:= map[string]interface{}{}
err := yaml.Unmarshal(y1, &data)
if err != nil {
log.Fatal(err)
}
}
But then how do i loop over contacts and compare using the map[string]interface{} method?
I am trying to learn go, so sorry if I don't phrase this correctly or I am missing something. Thanks for the help!

Symfony 5 switch cache adapter on condition

I need to switch the Symfony cache adapter depending on ENV conditions. Like if some variable is set, use "cache.adapter.apcu" or use "cache.adapter.filesystem" otherwise.
Is it possible somehow? The documentation is not really helpful with it.
P.S.: It is not possible for us to do this via the creation of a whole new environment
Here is a basic example for a CacheAdapter which has adapters fed into it and then picking one based on a parameter (or alternatively envvar):
<?php
namespace App\Cache;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\InvalidArgumentException;
use Psr\Container\ContainerInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Symfony\Contracts\Service\ServiceSubscriberTrait;
class EnvironmentAwareCacheAdapter implements AdapterInterface, ServiceSubscriberInterface
{
use ServiceSubscriberTrait;
private string $environment;
public function __construct(string $environment)
{
$this->environment = $environment;
}
public function getItem($key)
{
return $this->container->get($this->environment)->getItem($key);
}
public function getItems(array $keys = [])
{
return $this->container->get($this->environment)->getItems($key);
}
// ...
}
This is how you would configure it:
services:
App\Cache\EnvironmentAwareCacheAdapter:
arguments:
$environment: '%kernel.environment%'
tags:
- { name: 'container.service_subscriber', key: 'dev', id: 'cache.app' }
- { name: 'container.service_subscriber', key: 'prod', id: 'cache.system' }
It's not the most elegant solution and is missing error handling and possibly a fallback. Basically, by adding tags with an appropriately named key and the alias to an existing cache as id, you can then refer to that cache with the key in your own adapter. So, depending on your environment you will pick either one. You can replace the key and the constructor argument with anything else you like. I hope that helps.
It seems like you can not set up your cache configuration to use a environment variable like so:
framework:
cache:
app: %env(resolve:CACHE_ADAPTER)%
It is the constraint of FrameworkBundle that provides the cache service. And this constraint will not be "fixed" (Using environment variables at compile time #25173).
To make it possible you need to make your own cache provider that can just pass all arguments to the needed cache provider. You will have access to environment variables at runtime and so you can use it as a proxy that knows what provider to use.

Binding QML widgets to a list model, but having some widget only bind to a specific index?

I'm writing a QML GUI that talks to a monitoring server. In one case, there's 3 grouped remote systems, one is is a master, the other two are slaves. I have the full statuses of each one, but need to show more details for the master system.
So for example I'm receiving an update message containing:
{
systems: {
1: {
type: Debian,
name: system1,
status: OK,
detailedStatus1: 123,
detailedStatus2: xyz
},
2: {
type: Ubuntu,
name: system2,
status: OK,
detailedStatus1: 456,
detailedStatus2: abc
},
3: {
type: Windows,
name: system3,
status: OK,
detailedStatus1: 789,
detailedStatus2: def
}
},
currentMaster: (1 or 2 or 3)
}
...and I want to show type, name, and status for all 3 systems, but only show detailedStatus1 and detailedStatus2 for the currentMaster system.
What should my QML model be like? Should I have a "masterModel ListModel" that my detailedStatus widgets bind to, and an "allsystems ListModel" for type/name/status, and update masterModel everytime currentMaster changes? Or is there a way to do this from a single "allsystems ListModel" , using currentMaster to know what to bind to? Should I be doing something else altogether?

Get parameter and attributes of a class in .cc file

The problem is: Several mobile elements(ME) are employed to gather sensory data from the field. first the nodes should be clusterd and some energy-riched CHs should be selected as rendezvous nodes(RN).sensor nodes deliver their data to RNs and finally the mobile elements should visit these RNs to gather data.
The main part of this work is Estimation of routing paths toward RNs.
1) how can I do clustering and determining the RNs?
2)how can I force mobile elements to pass my defined movement paths?
I used INET wireless showcases to simulate this problem.
first part: I don't know. Plz help!
as the second part of my problem( movement of ME) I did:
module MEpath extends AdhocHost
{
parameters:
#display("i=device/cellphone");
#class(MEpath);
mobilityType = "MassMobility";
}
network MyNet
{
parameters:
int numHost;
int numME;
string mediumType = default("IdealRadioMedium");
submodules:
visualizer: IntegratedCanvasVisualizer {
parameters:
#display("p=47,16");
}
configurator: IPv4NetworkConfigurator {
parameters:
#display("p=47,97");
}
radioMedium: <mediumType> like IRadioMedium {
parameters:
#display("p=55,271");
}
lifecycleController: LifecycleController {
parameters:
#display("p=34,176");
}
host[numHost]: AdhocHost {
parameters:
#display("p=222,300");
}
mobileHost[numME]: MEpath {
#display("p=296,207;i=device/pocketpc");
}
}
Is defining MEpath module correct or not? which class or .cc file should I change? what should I write in MEpath.cc?
maybe it is unusual but at all I have problem in working with omnet++ and inet manual. I couldn't find out which attribute and parameter of a class should I change? !
Ad. 2. You can use BonnMotionMobility. It is explained in INET Framework 4.0 User's Guide as well as in INET API Reference. It required a file which contains several values: time, x, and y, separated by a space. An example of this file you can find in examples directory of INET for example: examples\mobility\bonnmotion_small.movements.
To use this type of mobility you should set in omnetpp.ini something like:
**.mobileHost*.mobility.typename = "BonnMotionMobility"
**.mobileHost*.mobility.traceFile = "your_trace_file"
Moreover, you should remove this line:
mobilityType = "MassMobility";
from your MEpath definition (because this way it is hardcoded, and it cannot be controlled via omnetpp.ini).
The definition of MEpath is correct. It requires a *.h and *.cc files that contain a declaration and definition of MEpath C++ class.

Openstack Heat - separate templates

I am looking for the best way of creating a stack, in a number of separate steps.
I would like in the first template, to only get up the compute nodes and the network configuration.
In the second template, I would like to create the storage nodes and attach them to the already existing compute nodes.
What do you think is the best way to do this?
Following is one possible approach.
1) Define first template for your compute nodes and network configuration. But define outputs in your first template to expose your compute node IDs. For example, if you create a OS::Nova::Server with name mynode1, you can expose its ID as the output for that template as follows:
outputs:
mynode1_id:
description: ID of mynode1
value: {getattr: [mynode1, id]}
Once you instantiate a heat stack, say mystack1, with this first template, then you can access the ID of mynode1 as follows:
heat output-show mystack1 mynode1_id
2) Create your second template for storage with IDs of your compute nodes from step1 as input parameters. For example:
parameters:
mynode1_id:
type: string
description: ID for mynode1
Then you can use that in your "resources:" section as follows:
resources:
...
...
my_volume_attach:
type: OS::Cinder::VolumeAttachment
properties:
instance_uuid: {get_param: mynode1_id}
...
3) Invoke your second heat stack creation as follows:
heat stack-create -f second-template.yaml -P mynode1_id=`heat output-show mystack1 mynode1_id` mystack2
You might also want to define dependencies between your resources, using the depends_on attribute.
From your description it doesn't seem like using several templates is the correct solution.
for example - if you want objects 3,4 created after objects 1,2, you can define a template as follows:
heat_template_version: '2015-10-15'
parameters:
param1:
type: string
description: just an example of parameter
resources:
object1:
type: OS::Neutron::XXX
properties:
property: XXX
description: object1
object2:
type: OS::Neutron::XXX
properties:
property: XXX
description: object2
object3:
type: OS::Nova::XXX
properties:
property: XXX
description: object3
depends_on: object1
object4:
type: OS::Nova::XXX
properties:
property: XXX
description: object4
depends_on: object1

Resources