pyvmomi to retrieve custom attribute "owner" for all VMs - pyvmomi

I'm trying (and failing) to figure out how to use pyvmomi to retrieve a custom attribute named "owner" for all VMs in a vCenter.
I use code like this to retrieve VM name, power state, and uuid:
summary = vm.summary
print(summary.config.name, " ", summary.runtime.powerState, " summary.config.uuid)
But, I cannot figure out how to retrieve the custom attribute named "owner" for all VMs in a vCenter.
Thanks in advance

CustomAttribute is stored separately in customValue field. Each customValue have its name and key, the "Owner" in your case is the name, you need to get its key first.
here is a sample:
conn=connect.SmartConnect(host='***', user='***', pwd='***', port=443)
content = conn.RetrieveContent()
cfm = content.customFieldsManager
required_field = ["Owner"]
my_customField = {}
for my_field in cfm.field:
if my_field.name in required_field:
my_customField[my_field.key]=my_field.name
The key and its display name is in my_customField dict, you can get customValue by it
for opts in vm.customValue:
if opts.key in my_customField:
output[my_customField[opts.key]]=opts.value
and in output dict you have what you want.

Related

How add dynamic user attribute value in keycloak with saml

ENVIRONMENT:
Keycloack 3.2
Saml2.0
SITUATION:
I need to add user attributes value dynamically.
TASK:
I need name attribute for my user, which can fill dynamically from First Name and Last Name fields, which as I found in keycloack can be fullName property.
NOTE: Instead of fullName it can be firstName + lastName field in my case as well.
ACTION:
I added user property with name fullName under my Clients -> myCLient -> Mappers,
then added under my user Users -> myUser -> Attributes, attribute key name and attribute value ${fullName}.
RESULT:
As a result I got ${fullName} as a value instead of dynamic value from my predefined user property.
QUESTIONS:
Is it possible to do this kind of things what I need ?
If it's possible then, what are wrong in my steps here?
For users like me who looking for a solution of this problem with newest version of Keycloak, in keycloak 18.0 you can create a Mapper with the type Javascript Mapper with this code: user.getFirstName() + ' ' + user.getLastName().
As a solution, I found that under client in keylock we have builtin user properties.
Example X500 givenName, X500 surname can be added and can get in BE side as a part of SAML assertion attributes.
There is another solution if the user federation are LDAP or Active Directory
On the user federation you can use the full-name-ldap-mapper.
By default it uses cn, but you can change that.
Next in your client you would add a saml mapper.
{
"name": "fullName",
"protocol": "saml",
"protocolMapper": "saml-user-attribute-mapper",
"consentRequired": false,
"config": {
"attribute.nameformat": "Unspecified",
"user.attribute": "full name",
"friendly.name": "Full name",
"attribute.name": "displayName"
}
}
Remember the attribute.name is the property that the SP would use.
Also the nameformat has to be discussed with the SP.

Getting the Username of user from Pointer (Parse.com)

I have a class called "Chat" and one of the columns is a pointer to the user that has created the object. How do I get that user's username value in a query?
I need the query to retrieve objects from the "Chat" class and add them to an array and instead of adding the user id, I would like it to add the username.
Any suggestions?
Thanks
var queryUserId = result["user"] as PFUser
self.nameString = queryUserId.username

"at" sign in parameter names in resource definition

from the documentation (http://docs.angularjs.org/api/ngResource.$resource):
$resource(url[, paramDefaults][, actions]);
paramDefaults(optional) – {Object=} – Default values for url parameters.
...
If the parameter value is prefixed with # then the value of that parameter is extracted from the data object.
The question is what data object do they refer to? How to use this feature?
lets say you have a resource like this:
var User = $resource('/user/:userId', {userId:'#id'});
var user = User.get({userId:123});
It means that the value of :userId in your url will be replaced with the id property from the user object when that property is required.
So when is it required? Its required when you are doing something to an existing user, like geting one, updating one. It is not required when you create a user.
In most cases, you will want to have at least one param prefixed with # in your REST url that resource uses (probably the object id). If you dont have one, that means that in order for you to save an instance of an object, you dont need to know anything about where its stored. This implies that its a singleton object. Maybe like a settings object.
Here is your long awaited example:
var User = $resource('/user/:userId/:dogName', {userId:'#id', dogName:#dog});
User.get({userId:123, dog:'Matt'}, function() { .. })
will produce the request: GET /user/123/Matt

setWhatId in salesforce using email template

i have to send an email to a user in salesforce using email template.this template contain merge field type of custom object.
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setTargetObjectId(user.get(0).id);
mail.setTargetObjectId(user.get(0).Id)
mail.setTemplateId(specifier.get(0).Template_id__c);
mail.saveAsActivity = false;
mail.setWhatId(custom_object.Id);
i read in documentation
If you specify a contact for the targetObjectId field, you can specify a whatId as well. This helps to further ensure that merge fields in the template contain the correct data. The value must be one of the following types:
Account
Asset
Campaign
Case
Contract
Opportunity
Order
Product
Solution
Custom
but if we are sending email to a user not to contact then how to assign a custom object for merge field type in custom objects as in the above code
This is a GIGANTIC whole in their email methods, and one that has annoyed me for years. Particularly given workflow email alerts seem to have no problem sending an email template for a user. Alas, you can't use setWhatId() if your target is a user. But you can vote for them to add that functionality,
I've worked around this I typically create a contact with the same name and email as the user, use it to send the email, and then delete it. This works well, although dealing with validation rules on the contact object can be a challenge. See their dev boards for a full discussion.
You can get the template and replace the merge fields as follows:
EmailTemplate template = [SELECT Id, Subject, HtmlValue, Body FROM EmailTemplate WHERE Name = 'Case Update'];
Case modifiedCase = [SELECT Account.Id, Account.Name, Owner.FirstName, Owner.LastName, CaseNumber, Subject, LastModifiedBy.FirstName, LastModifiedBy.LastName from Case where Id=:modifiedCaseId];
String subject = template.Subject;
subject = subject.replace('{!Case.Account}', modifiedCase.Account.Name);
subject = subject.replace('{!Case.CaseNumber}', modifiedCase.CaseNumber);
subject = subject.replace('{!Case.Subject}', modifiedCase.Subject);
String htmlBody = template.HtmlValue;
htmlBody = htmlBody.replace('{!Case.Account}', modifiedCase.Account.Name);
htmlBody = htmlBody.replace('{!Case.OwnerFullName}', ownerFullName);
...
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setSubject(subject);
email.setHtmlBody(htmlBody);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
As far as no new fields are added in the template this will work fine. The admin can mess with the format of the email without the need for code changes.
Not sure this is possible to do, but it depends on the relationship between your custom object and your users that will be receiving the merged emails. Do you have a 1-to-1 relationship between User and CustomObject? If so, perhaps adding a reference to the single custom object instance that each user object references and then adding custom formula fields on your user object with CustomObject__r.CustomField__c would do the trick.
In a custom formula field on your User object:
TEXT(CustomObject__r.CustomField__c)
Then your template could be changed into a User template and the merge fields would be the formula fields that actually pointed to your custom object instance. But if you have some other relationship like 1-to-many or many-to-many between User and CustomObject__c, I think you're out of luck.

Salesforce Custom Object Relationship Creation

I want to create two objects and link them via a parent child relationship in C# using the Metadata API.
I can create objects and 'custom' fields for the objects via the metadata, but the service just ignores the field def for the relationship.
By snipet for the fields are as follows:
CustomField[] fields = new CustomField[] { new CustomField()
{
type = FieldType.Text,
label = "FirstName",
length = 50,
lengthSpecified = true,
fullName = "LJUTestObject__c.FirstName__c"
},
new CustomField()
{
type = FieldType.Text,
label = "LastName",
length = 50,
lengthSpecified = true,
fullName = "LJUTestObject__c.Lastname__c"
},
new CustomField()
{
type = FieldType.Text,
label = "Postcode",
length = 50,
lengthSpecified = true,
fullName = "LJUTestChildObject__c.Postcode__c"
},
new CustomField()
{
type = FieldType.MasterDetail,
relationshipLabel = "PostcodeLookup",
relationshipName = "LJUTestObject__c.LJUTestObject_Id__c",
relationshipOrder = 0,
relationshipOrderSpecified = true,
fullName = "LJUTestChildObject__c.Lookup__r"
}
};
The parent object looks like:
LJUTestObject
ID,
FirstName, Text(50)
LastName, Text(50)
The child objext looks like:
LJUTestChildObject
ID,
Postcode, Text(50)
I want to link the parent to the child so one "LJUTestObject", can have many "LJUTestChildObjects".
What values do I need for FieldType, RelationshipName, and RelationshipOrder to make this happen?
TL;DR:
Use this as a template for accomplishing what you want:
var cf = new CustomField();
cf.fullName = "ChildCustomObject__c.ParentCustomField__c";
cf.type = FieldType.MasterDetail;
cf.typeSpecified = true;
cf.label = "Parent Or Whatever You Want This To Be Called In The UI";
cf.referenceTo = "ParentCustomObject__c";
cf.relationshipName = "ParentOrWhateverYouWantThisToBeCalledInternally";
cf.relationshipLabel = "This is an optional label";
var aUpsertResponse = smc.upsertMetadata(metadataSession, null, null, new Metadata[] { cf });
The key difference:
The natural temptation is to put the CustomField instances into the fields array of a CustomObject, and pass that CustomObject to the Salesforce Metadata API. And this does work for most data fields, but it seems that it does not work for relationship fields.
Instead, pass the CustomField directly to the Salesforce Metadata API, not wrapped in a CustomObject.
Those muted errors:
Turns out that errors are occurring, and the Salesforce Metadata API knows about them, but doesn't bother telling you about them when they occur for CustomFields nested inside a CustomObject.
By passing the CustomField directly to the Metadata API (not wrapped in a CustomObject), the call to upsertMetadata will still return without an exception being thrown (as it was already doing for you), but this time, if something goes wrong, upsertResponse[0].success will be false instead of true, and upsertResponse[0].errors will give you more information.
Other gotchas
Must specify referenceTo, and if it doesn't match the name of an existing built-in or custom object, the error message will be the same as if you had not specified referenceTo at all.
fullName should end in __c not __r. __r is for relationship names, but remember that fullName is specifying the field name, not the relationship name.
relationshipName - I got it working by not including __r on the end, and not including the custom object name at the start. I haven't tested to be sure other ways don't work, but be aware that at the very least, you don't need to have those extra components in the relationshipName.
Remember generally that anything with label in its name is probably for display to users in the UI, and thus can have spaces in it to be nicely formatted the way users expect.
Salesforce... really???
(mini rant warning)
The Salesforce Metadata API is unintuitive and poorly documented. That's why you got stuck on such a simple thing. That's why no-one knew the answer to your question. That's why, four years later, I got stuck on the same thing. Creating relationships is one of the main things you would want to do with the Salesforce Metadata API, and yet it has been this difficult to figure out, for this long. C'mon Salesforce, we know you're a sales company more than a tech company, but you earn trazillions of dollars and are happy to show it off - invest a little more in a better API experience for the developers who invest in learning your platform.
I've not created these through the meta data API like this myself, but I'd suggest that:
relationshipName = "LJUTestObject__c.LJUTestObject_Id__c
Should be:
relationshipName = "LJUTestObject__c.Id
as Id is a standard field, the __c suffix is only used for custom fields (not standard fields on custom objects). Also, it may be that the relationship full name should end in __c not __r, but try the change above first and see how you go.
SELECT
Id,
OwnerId,
WhatId,
Reminder_Date_Time__c,
WhoId,
Record_Type_Name__c,
Task_Type__c,
Assigned_Date__c,
Task_Status__c,
ActivityDate,
Subject,
Attended_By__c,
Is_Assigned__c
FROM Task
WHERE
(NOT Task_Status__c LIKE 'Open') AND
ActivityDate >= 2017-12-13 AND
(NOT Service__r.Service_State__c LIKE 'Karnataka')

Resources