I'm try to get primary IP of virtual machine and I get error 'virtualMachine.GetPrimaryPublicIPAddress().IPAddress' threw an exception of type 'System.NullReferenceException'
I successfully to get IP by use Rest-API in Postman
e.g Postman GET Method
https://management.azure.com/subscriptions/{{subid}}/resourceGroups/{{rg}}/providers/Microsoft.Network/networkInterfaces/{{vm_name}}?api-version=2020-11-01
my code in .Net
var credentials = SdkContext.AzureCredentialsFactory
.FromServicePrincipal(clientId,
clientSecret,
tenantId,
AzureEnvironment.AzureGlobalCloud);
var azure = Azure
.Configure()
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.Authenticate(credentials)
.WithSubscription(subscriptionId);
foreach (var virtualMachine in azure.VirtualMachines.ListByResourceGroup(resourceGroupName))
{
var name = virtualMachine.Name;
var os_type = virtualMachine.OSType;
var size = virtualMachine.OSDiskSize;
var ip = virtualMachine.GetPrimaryPublicIPAddress().IPAddress; //Error
}
Thanks for Help
Try this code:
using Microsoft.Azure.Management.Compute.Fluent;
using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent.Core;
using System;
using System.Threading.Tasks;
namespace myVMDotnetProject
{
class Program
{
static void Main(string[] args)
{
GetVMInfo();
Console.WriteLine("okok");
Console.ReadLine();
}
static async Task GetVMInfo()
{
var credentials = SdkContext.AzureCredentialsFactory.FromFile(Environment.GetEnvironmentVariable("AZURE_AUTH_LOCATION", EnvironmentVariableTarget.User));
var azure = Azure
.Configure()
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.Authenticate(credentials)
.WithDefaultSubscription();
IVirtualMachines _client = azure.VirtualMachines;
var list = await _client.ListAsync();
foreach (var instance in list)
{
var name = instance.Name;
var ip = instance.GetPrimaryPublicIPAddress().IPAddress;
Console.WriteLine("name: " + name + ", ip: " + ip);
}
}
}
}
Here is the result I test locally:
Related
I am trying to connect to the new Google Analytics Data api using C# to request data from the new google analytics GA4. The only sample i can find is
Quickstart client libraries .net This does work but it uses a service account. The cloud .net client library google-cloud-dotnet only has examples for using a service account.
When i try to pass it desktop app credentials for using Oauth" authorization i get
Error creating credential from JSON. Unrecognized credential type.
using System;
using System.Threading;
using System.Threading.Tasks;
using Google.Analytics.Data.V1Beta;
namespace GoogleAnalyticsExamplesData
{
class Program
{
private const string PropertyId = "250796939";
private const string PathToCreds = #"C:\dev\ServiceAccountCred.json";
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
// Check whether the environment variable exists.
var environmentVariable = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
// If necessary, create it.
if (environmentVariable == null)
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", PathToCreds);
await SampleRunReport(PropertyId);
}
static async Task SampleRunReport(string propertyId = "YOUR-GA4-PROPERTY-ID")
{
// Using a default constructor instructs the client to use the credentials
// specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
var client = await BetaAnalyticsDataClient.CreateAsync(CancellationToken.None);
var request = new RunReportRequest
{
Property = "properties/" + PropertyId,
Dimensions = {new Dimension {Name = "date"},},
Metrics = {new Metric {Name = "totalUsers"}, new Metric {Name = "newUsers"}},
DateRanges = {new DateRange {StartDate = "2021-04-01", EndDate = "today"},},
};
var response = await client.RunReportAsync(request);
Console.WriteLine("Report result:");
foreach (var row in response.Rows)
{
Console.WriteLine(
$"{row.DimensionValues[0].Value}, {row.MetricValues[0].Value}, {row.MetricValues[1].Value}");
}
}
}
}
Links to Google.Analytics.Data.V1Beta Web client credentials, desktop credentials
After several hours of digging around i found that you can use ICredential using a builder. This works with a Desktop app credentials, for installed applications.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Google.Analytics.Data.V1Beta;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util.Store;
namespace GoogleAnalyticsExamplesData
{
class Program
{
private const string PropertyId = "250796939";
private const string PathToCreds = #"C:\dev\credentials.json";
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
await SampleRunReport(PropertyId);
}
static async Task SampleRunReport(string propertyId = "YOUR-GA4-PROPERTY-ID")
{
// Using a default constructor instructs the client to use the credentials
// specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
//var client = await BetaAnalyticsDataClient.CreateAsync(CancellationToken.None);
BetaAnalyticsDataClient client ;
await using (var stream = new FileStream(PathToCreds, FileMode.Open, FileAccess.Read))
{
// Requesting Authentication or loading previously stored authentication for userName
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
new[] { "https://www.googleapis.com/auth/analytics.readonly"},
"userName",
CancellationToken.None,
new FileDataStore("credPath", true)).Result;
client = await new BetaAnalyticsDataClientBuilder
{
TokenAccessMethod = credential.GetAccessTokenForRequestAsync
}.BuildAsync();
}
var request = new RunReportRequest
{
Property = "properties/" + PropertyId,
Dimensions = {new Dimension {Name = "date"},},
Metrics = {new Metric {Name = "totalUsers"}, new Metric {Name = "newUsers"}},
DateRanges = {new DateRange {StartDate = "2021-04-01", EndDate = "today"},},
};
var response = await client.RunReportAsync(request);
Console.WriteLine("Report result:");
foreach (var row in response.Rows)
{
Console.WriteLine(
$"{row.DimensionValues[0].Value}, {row.MetricValues[0].Value}, {row.MetricValues[1].Value}");
}
}
}
}
I'm attempting to initiate a call with the Microsoft Graph SDK Create call API using the code sample below. The attempt fails with a Not Found exception.
I have registered the bot application, added the API call permissions and I am able to receive incoming calls from Teams.
It's not clear from the Microsoft documentation whether Teams users can be called directly or whether they have to be allocated a VoIP number. Has anyone been able to use the Graph SDK to call a Teams User? Is there some special configuration a User needs to have in order to be able to receive a call?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Graph.Communications.Common.Telemetry;
using Microsoft.Extensions.Logging;
using Microsoft.Graph;
using Microsoft.Graph.Communications.Calls;
using Microsoft.Graph.Communications.Calls.Media;
using Microsoft.Graph.Communications.Client;
using Microsoft.Skype.Bots.Media;
namespace sipbotcaller
{
class Program
{
private static string APP_NAME = "";
private static string APP_ID = "";
private static string APP_SECRET = "";
private static string TENANT_ID = "";
private static string CALLBACK_URI = "";
private static string CERTIFICATE_THUMBPRINT = "";
private static int MEDIA_PORT = 10000;
private static string PUBLIC_IP = "";
private static string HOSTNAME = "";
static async Task Main(string[] args)
{
Console.WriteLine("Teams Call Console:");
GraphLogger graphLogger = new GraphLogger(APP_NAME);
graphLogger.DiagnosticLevel = System.Diagnostics.TraceLevel.Verbose;
ILogger logger = new ConsoleLogger(graphLogger);
AuthenticationProvider authProvider = new AuthenticationProvider(
APP_NAME,
APP_ID,
APP_SECRET,
TENANT_ID,
graphLogger);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var users = await graphClient.Users.Request().GetAsync();
foreach (var user in users)
{
Console.WriteLine($"user Id: {user.Id}.");
Console.WriteLine($"user Display Name: {user.DisplayName}.");
}
var mediaPlatformSettings = new MediaPlatformSettings()
{
MediaPlatformInstanceSettings = new MediaPlatformInstanceSettings()
{
CertificateThumbprint = CERTIFICATE_THUMBPRINT,
InstanceInternalPort = MEDIA_PORT,
InstancePublicIPAddress = IPAddress.Parse(PUBLIC_IP),
InstancePublicPort = MEDIA_PORT,
ServiceFqdn = HOSTNAME,
},
ApplicationId = APP_ID,
};
var builder = new Microsoft.Graph.Communications.Client.CommunicationsClientBuilder(
APP_NAME,
APP_ID,
graphLogger);
builder
.SetAuthenticationProvider(authProvider)
.SetNotificationUrl(new Uri(CALLBACK_URI))
.SetMediaPlatformSettings(mediaPlatformSettings)
.SetServiceBaseUrl(new Uri(CALLBACK_URI));
var client = builder.Build();
AudioSocketSettings audioSockSettings = new AudioSocketSettings {
CallId = Guid.NewGuid().ToString(),
SupportedAudioFormat = AudioFormat.Pcm16K,
StreamDirections = StreamDirection.Sendrecv
};
AudioSocket audioSock = new AudioSocket(audioSockSettings);
var mediaConfig = MediaPlatform.CreateMediaConfiguration(audioSock);
Console.WriteLine($"media config: {mediaConfig}");
Console.WriteLine($"Attempting to call {users.First().DisplayName}.");
var call = new Call
{
CallbackUri = CALLBACK_URI,
TenantId = TENANT_ID,
Targets = new List<InvitationParticipantInfo>()
{
new InvitationParticipantInfo
{
Identity = new IdentitySet
{
User = new Identity
{
DisplayName = users.First().DisplayName,
Id = users.First().Id
},
}
}
},
RequestedModalities = new List<Modality>()
{
Modality.Audio
},
MediaConfig = new AppHostedMediaConfig()
{
Blob = mediaConfig.ToString(Newtonsoft.Json.Formatting.None)
},
};
var callResult = await client.Calls().AddAsync(call);
Console.WriteLine($"Call result {callResult.Id}.");
Console.WriteLine("Finished.");
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
}
Result:
<snip>
StatefulCall: Verbose
StatefulCall: Info
StatefulCall: Verbose
StatefulCall: Info
StatefulCall: Info
StatefulCall: Error {
"error": {
"code": "itemNotFound",
"message": "Unexpected exception returned from the service.\r\nStatus Code: NotFound"
}
}
StatefulCall: Info
I'm working on an Amazon s3 Compatible Object Storage solution (Minio).
I have an Minio server on e.g 192.168.235.143:9000
I have tried to get List of buckets on C# version of Amazon s3 Api.
Everything works fine.
When I try to Put a Bucket into this server e.g test1, Visual studio throws this request into an Exception:
Amazon.Runtime.AmazonServiceException:
'A WebException with status NameResolutionFailure was thrown.'
WebException: The remote name could not be resolved: 'test1.192.168.235.143'
here is my code:
AmazonS3Config config = new AmazonS3Config();
config.ServiceURL = "192.168.235.143:9000";
AmazonS3Client client = new AmazonS3Client(AccessKey, SecretKey, config);
PutBucketRequest request = new PutBucketRequest();
request.BucketName = "test1";
// this Line will throws above exception :
client.PutBucket(request);
but ListBuckets works for make me confused:
AmazonS3Client client = new AmazonS3Client(AccessKey, SecretKey, config);
var response = client.ListBuckets();
foreach (S3Bucket b in response.Buckets)
{
MessageBox.Show(string.Format("{0}\t{1}", b.BucketName, b.CreationDate));
}
What i have tested to check this Exception's cause:
I have Installed it on a Virtual machine and a local Version for doubly check this issue but it still persists.
I Even Changed Minio port to the port #80
I Even used "play.min.io" but has no difference
I need to use a known interface so we be able to port into another Object Storage Platform e.g Ceph, ....
I have no Idea to get it resolved yet.
Please Help me to find my mistake or a better solution
Here i have found a sample working code, Thanks to Minio GitHub Community:
using Amazon.S3;
using System;
using System.Threading.Tasks;
using Amazon;
class Program
{
private const string accessKey = "PLACE YOUR ACCESS KEY HERE";
private const string secretKey = "PLACE YOUR SECRET KEY HERE"; // do not store secret key hardcoded in your production source code!
static void Main(string[] args)
{
Task.Run(MainAsync).GetAwaiter().GetResult();
}
private static async Task MainAsync()
{
var config = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.USEast1, // MUST set this before setting ServiceURL and it should match the `MINIO_REGION` enviroment variable.
ServiceURL = "http://localhost:9000", // replace http://localhost:9000 with URL of your MinIO server
ForcePathStyle = true // MUST be true to work correctly with MinIO server
};
var amazonS3Client = new AmazonS3Client(accessKey, secretKey, config);
// uncomment the following line if you like to troubleshoot communication with S3 storage and implement private void OnAmazonS3Exception(object sender, Amazon.Runtime.ExceptionEventArgs e)
// amazonS3Client.ExceptionEvent += OnAmazonS3Exception;
var listBucketResponse = await amazonS3Client.ListBucketsAsync();
foreach (var bucket in listBucketResponse.Buckets)
{
Console.Out.WriteLine("bucket '" + bucket.BucketName + "' created at " + bucket.CreationDate);
}
if (listBucketResponse.Buckets.Count > 0)
{
var bucketName = listBucketResponse.Buckets[0].BucketName;
var listObjectsResponse = await amazonS3Client.ListObjectsAsync(bucketName);
foreach (var obj in listObjectsResponse.S3Objects)
{
Console.Out.WriteLine("key = '" + obj.Key + "' | size = " + obj.Size + " | tags = '" + obj.ETag + "' | modified = " + obj.LastModified);
}
}
}
}
For a specific VM, I want to be able to retrieve the public IP address.
I know how to get all public IP addresses for a resource group, I also know how to get a nic-id for a specific VM - but I can't figure out how to connect the two.
This is what I have:
var resourceGroupName = "My-Resource-Group";
var vmName = "MyVM";
var subscriptionId = "bzz-bzz-bzz-bzz-bzz-bzz";
var tenantId = "bar-bar-bar-bar-bar-bar";
string clientId = "foo-foo-foo-foo-foo-foo";
string clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var token = GetAccessTokenAsync(tenantId, clientId, clientSecret);
var credential = new TokenCredentials(token.Result.AccessToken);
var computeManagementClient = new ComputeManagementClient(credential) { SubscriptionId = subscriptionId };
var vmResult = await computeManagementClient.VirtualMachines.GetAsync(resourceGroupName, vmName, InstanceViewTypes.InstanceView);
//Get the NIC ID for the VM:
foreach (NetworkInterfaceReference nic in vmResult.NetworkProfile.NetworkInterfaces)
{
Console.WriteLine(" networkInterface id: " + nic.Id);
}
this gives me something like this:
/subscriptions/[guid]/resourceGroups/My-Resource-Group/providers/Microsoft.Network/networkInterfaces/myvm123
To get all public IPs for the resource group, I can do this:
using (var client = new NetworkManagementClient(credential))
{
client.SubscriptionId = subscriptionId;
foreach (var publicIpAddress in client.PublicIPAddresses.ListAll())
{
Console.WriteLine(publicIpAddress.IpAddress);
}
}
...But inspecting the properties of the nic-id and the public ip object, there are no obvious ways to get from one to the other.
Question:
How do I get from the nic-id string, to the actual public IP address for that VM/nic?
Helper function:
private static async Task<AuthenticationResult> GetAccessTokenAsync(string tenantId, string clientId, string clientSecret)
{
var cc = new ClientCredential(clientId, clientSecret);
var context = new AuthenticationContext($"https://login.windows.net/{tenantId}");
var token = context.AcquireToken("https://management.azure.com/", cc);
if (token == null)
{
throw new InvalidOperationException("Could not get the token");
}
return token;
}
I found a workaround. Not pretty, but it works.
It assumes you already have a Microsoft.Azure.Management.Compute.Models.VirtualMachine object from something like this:
VirtualMachine vmResult = await computeManagementClient.VirtualMachines.GetAsync(resourceGroupName, vmName, InstanceViewTypes.InstanceView);
Then you can take the first NIC, get the last part of that as an ID:
var firstNic = vmResult.NetworkProfile.NetworkInterfaces.First();
var nicNameParts = firstNic.Id.Split('/');
string networkIntefaceName = nicNameParts.Last();
using (var client = new NetworkManagementClient(credential))
{
client.SubscriptionId = subscriptionId;
string publicNicId = string.Empty;
//Query ALL Networkinterfaces in the client, and find the one with the matching NIC-name
var nic = client.NetworkInterfaces.ListAll().FirstOrDefault(x => x.Name == networkIntefaceName);
if (nic != null)
{
//If we find that, we can now use that to find the ID of the PublicIPAddress for said NIC
publicNicId = nic.IpConfigurations[0].PublicIPAddress.Id;
//...And when we have that, we can now query all public IP addresses for that specific public Nic ID
var publicIp = client.PublicIPAddresses.ListAll().FirstOrDefault(x => x.Id == publicNicId);
if (publicIp != null)
{
vmInfo.PublicIP = publicIp.IpAddress;
Console.WriteLine(" public ip: " + publicIp.IpAddress);
}
else
{
Console.WriteLine(" public ip: unknown");
}
}
}
Yes, it is not super elegant, it can be optimized etc - but it works, so that's a start. :)
I am trying to connect with c#.
Here is the class that submits hive queries successfully to my remote HDInsight cluster. what do i need to change here to connect to the local emulator
public class HadoopImporter : IImporter
{
public static readonly Logger log = LogManager.GetCurrentClassLogger();
public void Import(string _query)
{
try
{
log.Warn("Inside Hive submission method");
var store = new X509Store();
store.Open(OpenFlags.ReadOnly);
var cert =
store.Certificates.Cast<X509Certificate2>()
.First(item => item.Thumbprint == "MYCERTTUMBPRINT");
if (cert == null)
log.Error("no cert found");
log.Warn(cert.FriendlyName);
log.Warn("got the cert with thumbprint ", cert.Thumbprint.ToString())
;
log.Warn("trying to create credentials from cert");
var creds = new JobSubmissionCertificateCredential(new Guid("MYSUBSCRIPTIONID"),
cert, "MYSTORAGECONTAINER");
log.Warn("trying to connect with cert");
var jobClient = JobSubmissionClientFactory.Connect(creds);
log.Warn("Setting Hive job parameters");
var hiveJob = new HiveJobCreateParameters()
{
Query = _query,
StatusFolder = "/samplequeryoutput"
};
var jobResults = jobClient.CreateHiveJob(hiveJob);
log.Warn("Executing wait for jhive results");
WaitForJobCompletion(jobResults, jobClient);
using (var stream = jobClient.GetJobOutput(jobResults.JobId))
{
var reader = new StreamReader(stream);
var res = reader.ReadToEnd();
log.Warn("trying to get the job results " + res.ToString());
}
}
catch (Exception exp)
{
log.Error(exp);
}
}
private static void WaitForJobCompletion(JobCreationResults jobDetails, IJobSubmissionClient client)
{
var jobInProgress = client.GetJob(jobDetails.JobId);
while (jobInProgress.StatusCode != JobStatusCode.Completed && jobInProgress.StatusCode != JobStatusCode.Failed)
{
log.Warn("Inside the while loop waiting for hive job to complete");
jobInProgress = client.GetJob(jobInProgress.JobId);
Thread.Sleep(TimeSpan.FromSeconds(10));
}
log.Trace("HIVE Job has Imported " + jobDetails.JobId);
}
}
You should be able to connect to a local one-box using the REST implementation of the client.
You're looking for the WebHCatHttpClient interface. The code below runs a basic query against my local one-box.
var httpClient = new WebHCatHttpClient(new Uri("http://localhost:50111/"), "username", "password");
string outputDir = "basichivejob";
var task = httpClient.CreateHiveJob(#"select * from iris;", null, null, outputDir, null);
task.Wait();
var response = task.Result;
var output = response.Content.ReadAsAsync<JObject>();
output.Wait();
response.EnsureSuccessStatusCode();
string id = output.Result.GetValue("id").ToString();
httpClient.WaitForJobToCompleteAsync(id).Wait();
See the SDK docs for more info.