Is it possible to add multiple security groups while creating ALB - aws-cdk

https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_elasticloadbalancingv2/ApplicationLoadBalancer.html
ALB CDK has an attribute to return the list of security groups but couldn't find a way to add a list of security groups while creating ALB. Is there any workaround for this?

Depending on your use case for the security group. This may work - just put it in a loop for multiple security groups:
myAlb.connections.addSecurityGroup(mySG)
EDIT:
There's actually a ticket for this.
https://github.com/aws/aws-cdk/issues/5138
Here is a workaround:
myElb; // ELB created elsewhere in code
// get the CfnLoadBalancer from the LoadBalancer object
const cfnElb = myElb.node.defaultChild as elb.CfnLoadBalancer
// View SG list before the addition
console.log(cfnAdminELB.securityGroups)
// SecurityGroups can be 'undefined' need to check so that you don't get a warning
if (cfnElb.securityGroups){
cfnElb.securityGroups.push(mySecurityGroup.securityGroupId)
}
// Verify the token is added
console.log(cfnAdminELB.securityGroups)
In theory, you could delete things from the cfnElb.securityGroups list too if you wanted to get rid of their default CDK creates.

Related

How to reload a ResourceTable programmatically in Laravel Nova?

I have a custom resource-tool (ledger entry tool) that modifies values of a resource as well as insert additional rows into related resources.
"Account" is the main resources.
"AccountTransaction" and "AccountLog" both get written to when a ledger entry is created. And through events, the account.balance value is updated.
After a successful post of a ledger entry (using Nova.request) in the resource-tool, I would like the new balance value updated in the account detail panel, as well as the new entries in AccountTransaction and AccountLog to be visible.
The simple way would be to simply reload the page, but I am looking for a more elegant solution.
Is it possible to ask these components to refresh themselves from within my resource-tool vue.js component?
Recently had the same issue, until I referred to this block of code
Nova has vuex stores modules, where they have defined storeFilters.
Assigning filters an empty object and then requesting them again "reloads" the resources. Haven't done much more research on this matter, but if you are looking for what I think you are looking for, this should be it.
async reloadResources() {
this.resourceName = this.$router.currentRoute.params.resourceName || this.$router.currentRoute.name;
if (this.resourceName) {
let filters_backup = _.cloneDeep(this.$store.getters[`${this.resourceName}/filters`]);
let filters_to_change = _.cloneDeep(filters_backup);
filters_to_change.push({});
await this.$store.commit(`${this.resourceName}/storeFilters`, filters_to_change);
await this.$store.commit(`${this.resourceName}/storeFilters`, filters_backup);
}
},

Firebase rules to access specific child's value

The childByAutoId would be useful if you want to save in a node multiple children of the same type, that way each child will have its own unique identifier.
List:{
KJHBJJHB:{
name:List-1,
owner:John Doe,
user_id:<Fire base generated User_id>
},
KhBHJBJjJ:{
name:List-2,
owner:Jane Lannister,
user_id:<Fire base generated User_id>
},
KhBHJZJjZ:{
name:List-3,
owner:John Doe,
user_id:<Fire base generated User_id>
}
}
I am trying to access the List with the help of the following code:
let ref = FIRDatabase.database().reference(withPath: "/List")
The current user logged into the app is John Doe. When the user accesses the list, I want all the List child whose owner is John Doe(i.e. List-1 & List-3) and ignore the other child values.
Do I have to do this in my application or can this be achieved via Firebase Security rules?
My current rule definition is:
"List":{
".read": "root.child('List/'+root.child('List').val()+'/user_id').val() === auth.uid" }
But this rule is not giving me any success. Any idea how to achieve the desired result?
You're trying to use security rules to filter the list. This is not possible and one of the common pitfalls for developers coming to Firebase from a SQL background. We commonly refer to it as "rules are not filters" and you can learn more about it in:
the Firebase documentation
this answer
our new video series Firebase for SQL developers
and many previous questions mentioning "rules are not filters"
The solution is almost always the same: keep a separate list of the keys of posts that each user has access to.
UserLists:{
JohnUid: {
KJHBJJHB: true,
KhBHJZJjZ: true
},
JaneUid: {
KhBHJBJjJ: true
}
}
This type of list is often referred to as an index, since it contains references to the actual post. You can also find more about this structure in the Firebase documentation on structuring data.

How to keep conversation data in MS Bot framework

I am working with Microsoft bot development framework, using its node.js sdk.
I have been looking for a way to save all the messages of a conversation. I set persistConversationData to true, and tried to access the conversationData using session.conversationData. However, it is empty.
1- Is there a builtin method to access all the messages within a conversation?
2- If persistConversationData is not for that, can anyone please explain its usage.
Thank you so much.
By default, messages will not be persisted by the Microsoft Bot Framework. For stateful operations, you can use the Bot State API the following ways:
Set userData. The persisted data will be available to the same user across different conversations.
Set conversationData. The persisted data will be available to all the users within the same conversation.
Set privateConversationData. The persisted data will be available to the given user in the given conversation.
Set dialogData for storing temporary information in between the steps of a waterfall.
According to the documentation, conversationData is disabled by default. If you want to use it, you have to set persistConversationData to true.
tl;dr You have to take care of persistence for yourself. E.g.
// ...
var bot = new builder.UniversalBot(connector, { persistConversationData: true });
bot.dialog('/', function (session) {
let messages = session.conversationData || [];
messages.push(session.message);
session.conversationData = messages;
});

Zf2 Redis Adapter, getItems using wildcards

I'm making my first steps in using Redis under ZF2.
I was wondering if there is a method to retrieve keys by pattern.
e.g.:
after setting multiple values with keys like: 'stackOverflow_'.time(), i would like to retrieve later all keys matching the 'stackOverflow_' pattern.
tried using getItems(array $keys) with wildcard in: \vendor\zendframework\zendframework\library\Zend\Cache\Storage\Adapter\AbstractAdapter.php
$redisKeyPattern = 'stackOverflow_';
$redis = $this->getServiceLocator()->get('Redis');
$values = $redis->getItems(array($redisKeyPattern.'*'));
with no succces.
any ideas?
UDPATE:
thanks guys. i ended up with duplicating the Redis adapter and adding my own functionality that utilizes the 'keys' function in the Redis extension:
public function getItemsByKeyPattern($pattern) {
$keys = $this->getRedisResource()->keys('*'.$pattern.'*');
if(empty($keys)) return null;
foreach($keys as &$key){
$key = explode(':', $key)[1];
}
$items = parent::getItems($keys);
return $items;
}
and it works for me :)
sadly to say there is no method present to return items with a wildcard, also redis don't support namespaces for stored items.
you need to define each item you want to receive, maybe you should look at a implementation like this
$receiveRedisKeys = [];
foreach($resultSet as $result)
{
$receiveRedisKeys[] = 'predefined_prefix_' . $result->getId();
}
$redisCacheResultSet = $redis->getItems($receiveRedisKeys);
i know that someone on github made a new repository where he modified redis to allow namespaces but this requires that you build the redis binarys by yourself from source. this leeds to a redis version you can't update anymore over apt-get
It's not possible, but there are some alternatives.
One idea is to keep a set with the keys you are interested in. That is the most common approach to this problem: each time you create one of the keys you will want to retrieve later, you add its name to a set. Then when you need to operate on one of those keys, you can grab it from the set. Read this article to get a general idea about this approach.
Another idea is to use the SCAN command to walk the keyspace with the pattern you are using, and as a second step retrieve the values with MGET followed by the keys you collected. This approach is good for administrative processes, but not as something that should be included in an application because the performance will be worse than that of the first idea. More about SCAN.
Finally, an option that is not recommended but I'm listing it just for completeness is to use the KEYS command to collect the keys you want, then proceed to get the values with MGET, as in the SCAN approach. This is not recommended as KEYS shouldn't be used in production environments. More about KEYS.

Hydrate related objects

I am looking for a simple way to hydrate a related object. A Note belongs to a Document and only owners of a Document can add Notes so when a user tries to edit a Note, I need to hydrate the related Document in order to find out if the user has access to it. In my Service layer I have the following:
public void editNote(Note note)
{
// Get the associated Document object (required for validation) and validate.
int docID = noteRepository.Find(note.NoteID).DocumentID;
note.Document = documentRepository.Find(docID);
IDictionary<string, string> errors = note.validate();
if (errors.Count > 0)
{
throw new ValidationException(errors);
}
// Update Repository and save.
noteRepository.InsertOrUpdate(note);
noteRepository.Save();
}
Trouble is, noteRepository.InsertOrUpdate(note) throws an exception with "An object with the same key already exists in the ObjectStateManager." when the repository sets EntityState.Modified. So a number of questions arise:
Am I approaching this correctly and if so, how do I get around the exception?
Currently, the controller edit action takes in a NoteCreateEditViewModel. Now this does have a DocumentID field as this is required when creating a new Note as we need to know which Document to attach it to. But for edit, I cannot use it as a malicious user could provide a DocumentID to which they do have access and thus edit a Note they don't own. So should there be seperate viewmodels for create and edit or can I just exclude the DocumentID somehow on edit? Or is there a better way to go about viewmodels such that an ID is not required?
Is there a better way to approach this? I have read that I should just have a Document repository as an aggregate and lose the Note repository but am not sure if/how this helps.
I asked a similar question related to this but it wasn't very clear so hoping this version will allow someone to understand and thus point me in the right direction.
EDIT
Based on the information provided by Ladislav Mrnka and the answer detailed here: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key, it seems that my repository method need to be like the following:
public void InsertOrUpdate(Note note)
{
if (note.NoteID == default(int)) {
// New entity
context.Notes.Add(note);
} else {
// Existing entity
//context.Entry(note).State = EntityState.Modified;
context.Entry(oldNote).CurrentValues.SetValues(note);
}
}
But how do I get the oldNote from the context? I could call context.Entry(Find(note.NoteID)).CurrentValues.SetValues(note) but am I introducing potential problems here?
Am I approaching this correctly and if so, how do I get around the exception?
I guess this part of your code loads the whole Node from the database to find DocumentID:
int docID = noteRepository.Find(note.NoteID).DocumentID;
In such case your InsertOrUpdate cannot take your node and attach it to context with Modified state because you already have note with the same key in the context. Common solution is to use this:
objectContext.NoteSet.ApplyCurrentValues(note);
objectContext.SaveChanges();
But for edit, I cannot use it as a malicious user could provide a DocumentID to which they do have access and thus edit a Note they don't own.
In such case you must add some security. You can add any data into hidden fields in your page but those data which mustn't be changed by the client must contain some additional security. For example second hidden field with either signature computed on server or hash of salted value computed on server. When the data return in the next request to the server, it must recompute and compare signature / hash with same salt and validate that the passed value and computed value are same. Sure the client mustn't know the secret you are using to compute signature or salt used in hash.
I have read that I should just have a Document repository as an aggregate and lose the Note repository but am not sure if/how this helps.
This is cleaner way to use repositories but it will not help you with your particular error because you will still need Note and DocumentId.

Resources