Access VSTS Service Endpoint credentials from extension - azure-devops

I'm developing a VSTS extension.
I have configured a VSTS Service Endpoint through the portal.
I need to use the credentials of the configured endpoint in my extension code.
Does anybody know how to do this?
-Thanks in advance.

You need to add the service endpoint you want to use into the task.json of your build extension and then you can use it in the build task. Refer to this link for details: Service Endpoints in Team Services.
And you can also look at the VSTS Agent Task in GitHub for how to use the service endpoint in a build task like this one.

Thanks Eddie,
I found a solution for this with your help,
I was using 0.5.8 version of the vsts-task-lib library and update it to 0.9.7 and did the following,
//Import the task lib 0.9.7
import tl = require('vsts-task-lib/task');
//Get the endpoint ID (a guid)
serverEndpoint = tl.getInput('serverEndpoint', true);
//Get the enpoint URL for the retrieved end point id and parse it to URL type
serverEndpointUrl: url.Url = url.parse(tl.getEndpointUrl(this.serverEndpoint, false));
//Extract authentication details from url
serverEndpointAuth = tl.getEndpointAuthorization(this.serverEndpoint, false);
//Read parameters to variable
//NOTE: You cant write this data to console, if you do write, it will write //asterisk (****) instead of real values.
username = this.serverEndpointAuth['parameters']['username'];
password = this.serverEndpointAuth['parameters']['password'];
//Pass the variables as parameters.

Related

Azure terraform Use existing managed identity to authenticate web app

I hope somebody can help me to solve this issue.
Using terraform I scripted some resource groups and webapps. Those web app have some configurations that need to access a key vault to retrieve some secrets.
But to do so, I need to activate the azure identity on the web app.
So far everything is working just fine without any problem. But as I am still learning how to use terraform with azure, I need to keep destroying and spinning up the webapps, which mean everytime I need to activate the identity and add the access policy in the key vault.
So what I did, is to create a azure managed identity resource in the same resource group where I have the key vault. Now I would like to use this managed identity to authenticate my web app everytime I spin up the web app.
My web app code looks like this:
resource "azurerm_app_service" "app-hri-stg-eur-configurations-api" {
name = "app-hri-${var.env}-${var.reg-name}-webapp-testing"
app_service_plan_id = azurerm_app_service_plan.ASP-hri-stg-eur-webapp.id
location = var.location
resource_group_name = azurerm_resource_group.rg-hri-stg-eur-webapp.name
app_settings = {
"secret" = "#Microsoft.KeyVault(SecretUri=https://mykeyvault.vault.azure.net/secrets/test)"
...... <My configuration>
}
identity {
type = "UserAssigned"
}
}
And here is where I am getting confused, how can I reference the azure managed identity that I have already created to grant access to my web app to read the secrets?
I hope I made my question clear enough, and please if not just ask for more info
Thank you so much for any help you can provide
A identity block supports the following:
type - (Required) Specifies the identity type of the App Service. Possible values are SystemAssigned (where Azure will generate a Service Principal for you), UserAssigned where you can specify the Service Principal IDs in the identity_ids field, and SystemAssigned, UserAssigned which assigns both a system managed identity as well as the specified user assigned identities.
identity_ids - (Optional) Specifies a list of user managed identity ids to be assigned. Required if type is UserAssigned.
so you should have sth like this:
data "azurerm_user_assigned_identity" "example" {
name = "name_of_user_assigned_identity"
resource_group_name = "name_of_resource_group"
}
If your identity is in another resource group. It allows you to reference to already created azure resource.
identity {
type = "UserAssigned",
identity_ids = [data.azurerm_user_assigned_identity.example.id]
}

How to integrate SAP Cloud Platform TMS to CI/CD pipeline?

We are trying to implement SAP Cloud Platform Transport Management service in our current CI/CD pipeline (Piper Project).
We are referring to documentation in https://sap.github.io/jenkins-library/scenarios/TMS_Extension/ for the configuration details.
Appreciate if someone can answer the below questions.
Which parameter should we configure in tmsUpload step for the Transport Management service end-point? (The only parameters we can see in the above documentation are credentialsId, nodeName and mtaPath)
As we understand, credentialsId needs to be configured in Jenkins. But what credentials should we configure for tmsUpload? We tried with the service clientid, verificationkey and clientsecret but neither worked.
I know I am quite late but for future users who dont figure it out.
The parameters required are listed at this site :
https://sap.github.io/jenkins-library/steps/tmsUpload/
For tmsUpload credentials you have to create a service key on your SAP TMS account. It would be a JSON file. After creating the file, create jenkins credentials of type secret text and paste the entire content of the JSON file in the secret text. Assign a CredentialID to this secret text and provide it in the credentialsid parameter of the tmsUpload step in your pipeline config file.
Hope this helps your problem.

azure sdk for net login is takes too long

I am using Fluent Library to develop a web app which can create a sql server on azure. The console app works great but when I implement the code to a web api it stuck in authentication step. I'm sure about the credentials which are true and I have a Service Principal.
// Authenticate
var credentials = new AzureCredentials(new ServicePrincipalLoginInformation { ClientId = ClientId, ClientSecret = Password }, tenantId, AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Configure().Authenticate(credentials).WithDefaultSubscription();
I also can repro it on my side. I try to debug it with following code and add quick watch for azureauth.WithDefaultSubscription(), then get value The function evaluation requires all threads to run. So I guess that it may run some threads that WebAPI can't handle.
var azureauth = Azure.Configure().Authenticate(credentials);
azureauth.WithDefaultSubscription()
Please have a try to use following code to use specified subscriptionId as workaround. It works correctly on my side.
var azure = Azure.Configure().Authenticate(credentials).WithSubscription("subscriptionId");

TFS REST API: How to "Make requests on behalf of others"?

I want my VSTS extension (installed on-prem TFS2015.3) to be able to do specific requests on behalf of a admin/service account ("Make requests on behalf of others")
Background: I manipulate (WorkItem) Process Template, specifically the GLOBALWORKFLOW (only on team-project level) in my extensions typescript, but the user of the extension in Web Access is NOT a project-admin so he is not allowed to use the function updateWorkItemTypeDefinition() - Non-Project-Admins get "Access denied" even if I gave that custom group every permission available ("Edit project-level-information" permissions for project-level GLOBALWORKFLOWs? Still didn't work for custom groups, only for Project Admin Accounts).
It seems I'm forced to impersonate a project admin /service account which is allowed to change the global workflow in the project
How do I impersonate in extension typescript code on-prem TFS and REST (1. not .NET and 2. without changing to basic auth, saw that solution already somewhere else - but I'm very sure I cannot request that change in my organization)
Thanks for your help
You can impersonate user through vsts-node-api.
There are many function to impersonate user, such as Basic, NTLM, PWA (VSTS) etc..., you can check these function here.
import * as vm from 'vso-node-api';
// your collection url
var collectionUrl = "XXX";
let authHandler = vm.getNtlmHandler("[user name]","[password]","[workstation optional]","[domain optional]");
var connect = new vm.WebApi(collectionUrl, authHandler);
There is the sample that you could refer to.

Authenticating (Team Foundation Server) with impersonalization

I have found how to authenticate to TFS from my app with a given username/password.
I'd like to use the REST services.
public static void BasicAuthRestSample()
{
// Create instance of VssConnection using basic auth credentials.
// For security, ensure you are connecting to an https server, since credentials get sent in plain text.
VssConnection connection = new VssConnection(new Uri(collectionUri), new VssCredentials(new WindowsCredential(new NetworkCredential(username, password))));
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
List<QueryHierarchyItem> items = witClient.GetQueriesAsync(teamProjectName).Result;
}
This solution is working fine, but if i create a new workitem, that is created by "username".
But i want to create workitems by impersonalized users, so i want to see "seconduser" as the creator if i look at the workitem in TFS.
I was googling a lot but can't find an example....
Update for VSTS:
After trying to implement i have found this:
"For security reasons (and compliance and a number of other reasons), the impersonation header isn't supported on Visual Studio Online"
A strange thing is that the error message currently misleading, it tells me that I need the special permission while the whole impersonation feature is actually disabled in VSTS.
According to REST API Reference for VS Team Services and TFS, there is no REST API similar to TFS Impersonation right now. As the .net api still works with VSTS for most features (not support vNext build, etc), you can take the .net api as an alternative.
You should use the TfsTeamProjectCollection constructor accepting an IdentityDescriptor.
You can find the full explanation in Introducing TFS Impersonation.
Snippet from the post
// Get the TFS Identity Management Service
IIdentityManagementService identityManagementService =
currentUserCollection.GetService<IIdentityManagementService>();
// Look up the user that we want to impersonate
TeamFoundationIdentity identity = identityManagementService.ReadIdentity(
IdentitySearchFactor.AccountName, username, MembershipQuery.None, ReadIdentityOptions.None);
TfsTeamProjectCollection impersonatedCollection =
new TfsTeamProjectCollection(currentUserCollection.Uri, identity.Descriptor);