Как добавить устройство в облачный реестр Google с помощью С#?

введите описание изображения здесьЗдравствуйте, хотите спросить, как добавить устройство в облачный реестр Google с помощью ядра google cloud iot с C#

Я пробовал следующий код, который указан в консоли Google для добавления устройства в реестр, но получаю ошибку Google.Apis.Requests.Request Error. У вызывающего абонента нет разрешения [403]

public static CloudIotService CreateAuthorizedClient()
{
    

GoogleCredential credential =
            GoogleCredential.GetApplicationDefaultAsync().Result;
        // Inject the Cloud IoT Core Service scope
        if (credential.IsCreateScopedRequired)
        {
            credential = credential.CreateScoped(new[]
            {
                CloudIotService.Scope.CloudPlatform // Used for IoT + PubSub + IAM
                //CloudIotService.Scope.Cloudiot // Can be used if not accessing Pub/Sub
            });
        }
        return new CloudIotService(new BaseClientService.Initializer
        {
            HttpClientInitializer = credential,
            GZipEnabled = false
        });
    }

public static object CreateRsaDevice(string projectId, string cloudRegion, string registryId, string deviceId, string keyPath)
    {
        keyPath = @"E:\Downloads\thermostat-289211-bb93742bc12f.json";
        projectId= "thermostat - 289211";
        cloudRegion = "us-central1";
        registryId = "testregistry";
        deviceId = "C418B9962BC91";
        var cloudIot = CreateAuthorizedClient();
        var parent = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}";

        try
        {
            //var credentials = GoogleCredential.FromFile(keyPath);
            //String keyText = File.ReadAllText(keyPath);
            Device body = new Device()
            {
                Id = deviceId
            };
            body.Credentials = new List<DeviceCredential>();
            body.Credentials.Add(new DeviceCredential()
            {
                PublicKey = new PublicKeyCredential()
                {
                    Key = "here i am entering my public key",
                    Format = "RSA_X509_PEM"
                },
            });

            var device = cloudIot.Projects.Locations.Registries.Devices.Create(body, parent).Execute();
            Console.WriteLine("Device created: ");
            Console.WriteLine($"{device.Id}");
            Console.WriteLine($"\tBlocked: {device.Blocked == true}");
            Console.WriteLine($"\tConfig version: {device.Config.Version}");
            Console.WriteLine($"\tName: {device.Name}");
            Console.WriteLine($"\tState:{device.State}");
        }
        catch (Google.GoogleApiException e)
        {
            Console.WriteLine(e.Message);
            if (e.Error != null) return e.Error.Code;
            return -1;
        }
        return 0;
    }

прикрепление изображения ролей на странице «Я администратор», выделенной желтым цветом, — это текущая учетная запись, которую я использую


comment
Отредактируйте свой вопрос и покажите роли IAM, назначенные сервисному аккаунту.   -  person John Hanley    schedule 22.12.2020
comment
В этом документе показано, как создать реестр, в который затем можно добавлять устройства.   -  person Mahboob    schedule 22.12.2020
comment
Текущий пользователь может не иметь доступа для выполнения запрошенного действия, как описано в document, затем подтвердите, что учетная запись службы имеет разрешения на выполнение этого действия.   -  person Elba Lazo    schedule 23.12.2020
comment
Я предоставил весь доступ к управлению устройством для своего идентификатора, а также для учетной записи службы, но по-прежнему не разрешаю мне добавлять устройство, однако реестры успешно создаются.   -  person Hafiz umer    schedule 23.12.2020
comment
Убедитесь, что в вашем проекте включен IOT API, следуя инструкциям здесь support.google. .com/googleapi/answer/6158841?hl=ru, а затем создайте учетные данные приложений здесь:pantheon.corp.google.com/projectselector2/identity/ и передать их как переменные среды.   -  person Elba Lazo    schedule 24.12.2020
comment
Вам нужен аналог C# этого?   -  person Mahboob    schedule 25.12.2020
comment
API @ErickSilverio IOT включен, как передать эти учетные данные в переменные среды?   -  person Hafiz umer    schedule 26.12.2020
comment
@Mahboob да, я хочу именно это на C#   -  person Hafiz umer    schedule 26.12.2020


Ответы (1)


См.: https://cloud.google.com/iot/docs/samples/device-manager-samples#iot-core-create-rs256-csharp

QUESTION="65413853"
PROJECT="dazwilkin-$(date +%y%m%d)-${QUESTION}"
REGION="us-central1"
REGISTRY="test"

BILLING=$(\
  gcloud alpha billing accounts list \
  --format="value(name)")

gcloud projects create ${PROJECT}
gcloud beta billing projects link ${PROJECT} \
--billing-account=${BILLING}

# Enable Cloud IOT
gcloud services enable cloudiot.googleapis.com \
--project=${PROJECT}

# Create Registry
gcloud iot registries create ${REGISTRY} \
--region=${REGION} \
--project=${PROJECT}

# Create Service Account with permissions for IoT
ROBOT="dellian"
EMAIL="${ROBOT}@${PROJECT}.iam.gserviceaccount.com"

gcloud iam service-accounts create ${ROBOT} \
--project=${PROJECT}

gcloud iam service-accounts keys create ./${ROBOT}.json \
--iam-account=${EMAIL}

gcloud projects add-iam-policy-binding ${PROJECT} \
--member=serviceAccount:${EMAIL} \
--role=roles/cloudiot.provisioner

# Create RSA key
openssl req -x509 -nodes \
-newkey rsa:2048 \
-keyout rsa_private.pem \
-out rsa_cert.pem \
-subj /CN=cloudiot

docker run \
--interactive --tty \
--env=PROJECT=${PROJECT} \
--env=REGION=${REGION} \
--env=REGISTRY=${REGISTRY} \
--volume=${PWD}/app:/app \
--volume=${PWD}/${ROBOT}.json:/secrets/${ROBOT}.json \
--env=GOOGLE_APPLICATION_CREDENTIALS=/secrets/${ROBOT}.json \
--workdir=/app mcr.microsoft.com/dotnet/sdk:5.0 bash

Затем:

С app.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Google.Apis.Auth" Version="1.49.0" />
    <PackageReference Include="Google.Apis.CloudIot.v1" Version="1.49.0.2161" />
  </ItemGroup>

</Project>

и:

using Google.Apis.Auth.OAuth2;
using Google.Apis.CloudIot.v1;
using Google.Apis.CloudIot.v1.Data;
using Google.Apis.Services;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace IoTSample
{
    public class IoTExample
    {
        public static void Main(string[] args){

            string projectId = Environment.GetEnvironmentVariable("PROJECT");
            string region = Environment.GetEnvironmentVariable("REGION");
            string registryId = Environment.GetEnvironmentVariable("REGISTRY");
            string deviceId = Environment.GetEnvironmentVariable("DEVICE");
            string keyPath = Environment.GetEnvironmentVariable("KEY");

            GoogleCredential credential = GoogleCredential.GetApplicationDefaultAsync().Result;
            if (credential.IsCreateScopedRequired) {
                credential = credential.CreateScoped(new[]{
                    CloudIotService.Scope.CloudPlatform // Used for IoT + PubSub + IAM
                    //CloudIotService.Scope.Cloudiot // Can be used if not accessing Pub/Sub
                });
            }
            CloudIotService service = new CloudIotService(new BaseClientService.Initializer{
                HttpClientInitializer = credential,
                GZipEnabled = false
            });

            var parent = $"projects/{projectId}/locations/{region}/registries/{registryId}";
            var keyText = File.ReadAllText(keyPath);

            try
            {
                Device body = new Device()
                {
                    Id = deviceId
                };
                body.Credentials = new List<DeviceCredential>();
                body.Credentials.Add(new DeviceCredential()
                {
                    PublicKey = new PublicKeyCredential()
                    {
                        Key = keyText,
                        Format = "RSA_X509_PEM"
                    },
                });

                var device = service.Projects.Locations.Registries.Devices.Create(body, parent).Execute();
                Console.WriteLine("Device created: ");
                Console.WriteLine($"{device.Id}");
                Console.WriteLine($"\tBlocked: {device.Blocked == true}");
                Console.WriteLine($"\tConfig version: {device.Config.Version}");
                Console.WriteLine($"\tName: {device.Name}");
                Console.WriteLine($"\tState:{device.State}");
            }
            catch (Google.GoogleApiException e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

Ваш реестр Cloud IoT (в данном случае test) должен существовать в проекте.

См.: https://cloud.google.com/iot/docs/how-tos/credentials/keys#generating_an_rsa_key_with_a_self-signed_x509_certificate

export DEVICE="device-01"
export KEY="rsa_cert.pem"

dotnet run

Урожайность:

Device created: 
test
    Blocked: False
    Config version: 1
    Name: projects/.../devices/2553842783141685
    State:

и:

gcloud iot devices list \
--registry=test \
--region=us-central1 \
--project=${PROJECT}

ID     NUM_ID            BLOCKED
test   2553842783141685

Обновление 2020-12-31

Вы также можете создать устройство с помощью командной строки. Это был бы полезный тест, чтобы убедиться, что вы все правильно настроили:

DEVICE="test-02"
KEY="${PWD}/app/rsa_cert.pem"

gcloud iot devices create ${DEVICE} \
--registry=${REGISTRY} \
--public-key=path=${KEY},type=RSA-X509-PEM \
--region=${REGION} \
--project=${PROJECT}

Должен дать:

Created device [${DEVICE}].
person DazWilkin    schedule 28.12.2020
comment
Не могли бы вы объяснить, какие шаги я написал тот же код, а также то же самое, что и ваш комментарий, но все равно получаю ту же ошибку - person Hafiz umer; 31.12.2020
comment
Добавлю больше деталей к моему ответу - person DazWilkin; 31.12.2020