java.net.net-corepcfpcfdev

Access User Provided Service variables from PCF using .NET core


I have a .NET core webapi running on PCF, Ive Create a user-provided service (cups) that contain my database credentials

cf cups my-proj-db -p '{"username":"dba", "password":"dbapass", "server":"whateverserver:1433", "database":"schools"}'

when I log onto PCF and go to

Settings->Environment Variables->View Env Vars

I am able to see the username, db, etc under

 "system_env_json": {
    "VCAP_SERVICES": {
      "user-provided": [...

Now i want to retrieve the DB values so in my .NET code I do

Environment.GetEnvironmentVariable("vcap.services.my-proj-db.credentials.server",EnvironmentVariableTarget.Process)

I also tired EnvironmentVariableTarget.Machine & EnvironmentVariableTarget.User

but the value is always null, I know in Java this is how they retrieve it, but how do i do it in .NET core?

Just a side note, if i add a costume variable directly to PCF like

cf set-env my-app-name ENV_VAR_NAME MyFunkyName

I am able to get the value by

Environment.GetEnvironmentVariable("ENV_VAR_NAME", EnvironmentVariableTarget.Process)

Appreciate the help!!


Solution

  • so finally, was able to get this to work using Steeltoe extension. Here is what all is required.

    install the following nuget packages

    Steeltoe.Common.Hosting
    Steeltoe.Extensions.Configuration.CloudFoundryCore
    Steeltoe.Extensions.Logging.DynamicSerilogCore
    Steeltoe.Management.CloudFoundryCore
    

    then Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.ConfigureCloudFoundryOptions(Configuration);
    }
    

    then in program.cs

    public static void Main(string[] args)
    {
       CreateHostBuilder(args).Build().Run();
    }    
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
               .UseCloudHosting() //Enable listening on a Env provided port
               .AddCloudFoundryConfiguration() //Add cloud-foundry environment variables as a configuration source
               .ConfigureWebHostDefaults(webBuilder =>
               {
                   webBuilder.UseStartup<Startup>();
               });
    

    then in which ever class you want to access the values you have to do following

    using Microsoft.Extensions.Options;
    using Steeltoe.Extensions.Configuration.CloudFoundry;
    
     public class EnvironmentManager
        {
            private CloudFoundryApplicationOptions _appOptions { get; set; }
            private CloudFoundryServicesOptions _serviceOptions { get; set; }
    
            public EnvironmentManager(IOptions<CloudFoundryApplicationOptions> appOptions, IOptions<CloudFoundryServicesOptions> serviceOptions)
            {
                _appOptions = appOptions.Value;
                _serviceOptions = serviceOptions.Value;
            }
    

    you can then wherever you want to access the values you could just do

    var value = _serviceOptions.Services["user-provided"]
                               .First(q => q.Name.Equals("my-proj-db"))
                               .Credentials["username"].Value;