Google compute engine 谷歌计算引擎虚拟机上的gsutil可以';t对密钥文件使用服务帐户身份验证

Google compute engine 谷歌计算引擎虚拟机上的gsutil可以';t对密钥文件使用服务帐户身份验证,google-compute-engine,google-api-dotnet-client,Google Compute Engine,Google Api Dotnet Client,我正在从google.NETAPI启动一个实例,尽管我尽了最大的努力,我还是无法让它在存储中复制任何内容。目前,我正在使用开发人员控制台服务帐户进行身份验证,如下所示:- string ServiceAccountEmail = "blahblah@developer.gserviceaccount.com"; var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exporta

我正在从google.NETAPI启动一个实例,尽管我尽了最大的努力,我还是无法让它在存储中复制任何内容。目前,我正在使用开发人员控制台服务帐户进行身份验证,如下所示:-

string ServiceAccountEmail = "blahblah@developer.gserviceaccount.com";

var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

ServiceAccountCredential credential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer(ServiceAccountEmail)
    {
        Scopes = new[] { ComputeService.Scope.Compute, ComputeService.Scope.DevstorageFullControl }
    }.FromCertificate(certificate));

var cs = new ComputeService(new BaseClientService.Initializer
{
    ApplicationName = "appname",
    HttpClientInitializer = (Google.Apis.Http.IConfigurableHttpClientInitializer)credential,
});


Google.Apis.Compute.v1.Data.Instance newinst = new Google.Apis.Compute.v1.Data.Instance();
newinst.Name = "generatedinstance";
newinst.MachineType = "https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/machineTypes/n1-standard-1";

Google.Apis.Compute.v1.Data.AttachedDisk ad = new Google.Apis.Compute.v1.Data.AttachedDisk();
ad.AutoDelete = true;
ad.Boot = true;
ad.Type = "PERSISTENT";
ad.InitializeParams = new Google.Apis.Compute.v1.Data.AttachedDiskInitializeParams();
ad.InitializeParams.DiskName = "newdisk";
ad.InitializeParams.SourceImage = "https://www.googleapis.com/compute/v1/projects/projectid/global/images/customimage";
ad.InitializeParams.DiskType = "https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/diskTypes/pd-standard";
ad.Mode = "READ_WRITE";
newinst.Disks = new List<Google.Apis.Compute.v1.Data.AttachedDisk>();
newinst.Disks.Add(ad);

Google.Apis.Compute.v1.Data.NetworkInterface ni = new Google.Apis.Compute.v1.Data.NetworkInterface();
ni.Network = "https://www.googleapis.com/compute/v1/projects/projectid/global/networks/default";
ni.AccessConfigs = new List<Google.Apis.Compute.v1.Data.AccessConfig>();
ni.AccessConfigs.Add(new Google.Apis.Compute.v1.Data.AccessConfig
{
    Type = "ONE_TO_ONE_NAT",
    Name = "External NAT",
});
newinst.NetworkInterfaces = new List<Google.Apis.Compute.v1.Data.NetworkInterface>();
newinst.NetworkInterfaces.Add(ni);
var start = new Google.Apis.Compute.v1.Data.Metadata.ItemsData();
start.Key = "startup-script";
start.Value = "*startup script* includes gsutil cp which won't work without service account attached";
newinst.Metadata = new Google.Apis.Compute.v1.Data.Metadata();
newinst.Metadata.Kind = "compute#metadata";
newinst.Metadata.Items = new List<Google.Apis.Compute.v1.Data.Metadata.ItemsData>();
newinst.Metadata.Items.Add(start);
newinst.ServiceAccounts = new List<Google.Apis.Compute.v1.Data.ServiceAccount>();

//var sa = new Google.Apis.Compute.v1.Data.ServiceAccount();|with this section
//sa.Email = "blahblah@developer.gserviceaccount.com";      |the instance won't
//sa.Scopes = new[] { ComputeService.Scope.Compute,         |start. (An equivalent
    ComputeService.Scope.DevstorageFullControl };           |is found in instance
//newinst.ServiceAccounts.Add(sa);                          |start REST request)

var instinsert = new InstancesResource.InsertRequest(cs, newinst, "projectid", "zone");
var insertresponse = instinsert.Execute();
string ServiceAccountEmail=”blahblah@developer.gserviceaccount.com";
var证书=新的X509Certificate2(@“key.p12”,“notasecret”,X509keystrageFlags.Exportable);
ServiceAccountCredential credential=新ServiceAccountCredential(
新ServiceAccountCredential.初始值设定项(ServiceAccountEmail)
{
Scopes=new[]{ComputeService.Scope.Compute,ComputeService.Scope.DevStorage FullControl}
}.FromCertificate(证书));
var cs=new ComputeService(new BaseClientService.Initializer
{
ApplicationName=“appname”,
HttpClientInitializer=(Google.api.Http.IConfigurableHttpClientInitializer)凭据,
});
Google.api.Compute.v1.Data.Instance newinst=new Google.api.Compute.v1.Data.Instance();
newinst.Name=“generatedinstance”;
newinst.MachineType=”https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/machineTypes/n1-standard-1";
Google.api.Compute.v1.Data.attachedisk ad=新的Google.api.Compute.v1.Data.attachedisk();
ad.AutoDelete=true;
ad.Boot=true;
ad.Type=“持久”;
ad.InitializeParams=new Google.api.Compute.v1.Data.AttachedDiskInitializeParams();
ad.InitializeParams.DiskName=“newdisk”;
ad.InitializeParams.SourceImage=”https://www.googleapis.com/compute/v1/projects/projectid/global/images/customimage";
ad.InitializeParams.DiskType=”https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/diskTypes/pd-standard";
ad.Mode=“读写”;
newinst.Disks=新列表();
新安装磁盘添加(ad);
Google.api.Compute.v1.Data.NetworkInterface ni=新的Google.api.Compute.v1.Data.NetworkInterface();
网络=”https://www.googleapis.com/compute/v1/projects/projectid/global/networks/default";
ni.AccessConfigs=新列表();
ni.AccessConfigs.Add(新的Google.api.Compute.v1.Data.AccessConfig
{
Type=“一对一”,
Name=“外部NAT”,
});
newinst.NetworkInterfaces=新列表();
新增网络接口(ni);
var start=new Google.api.Compute.v1.Data.Metadata.ItemsData();
start.Key=“启动脚本”;
start.Value=“*启动脚本*包括gsutil cp,如果没有附加服务帐户,它将无法工作”;
newinst.Metadata=new Google.api.Compute.v1.Data.Metadata();
newinst.Metadata.Kind=“计算#元数据”;
newinst.Metadata.Items=新列表();
newinst.Metadata.Items.Add(开始);
newinst.ServiceAccounts=新列表();
//var sa=new Google.api.Compute.v1.Data.ServiceAccount()|与本节一起
//sa.Email=”blahblah@developer.gserviceaccount.com";      |该实例将不会
//sa.Scopes=new[]{ComputeService.Scope.Compute,| start。(等效)
在实例中找到ComputeService.Scope.devStorage FullControl}
//newinst.ServiceAccounts.Add(sa);|启动REST请求)
var instinsert=newinstancesresource.InsertRequest(cs,newinst,“projectid”,“zone”);
var insertresponse=instinsert.Execute();

当我尝试使用
gsutil cp
时,收到的消息是“您当前未选择活动帐户”。有人能告诉我哪里出了问题吗?

您需要运行
gcloud auth activate服务帐户blahblah@developer.gserviceaccount.com--key file path_to_key.p12
告诉云SDK(包括gsutil)关于您的服务帐户。

根据提供的代码,我可以看到示例

var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

我注意到您的代码中缺少“@”。我对.Net不是很熟悉。我已经在和中测试了这些示例。创建我的实例时,我添加了GCS的服务帐户,文件已正确上载。

好的!问题解决了。我弄错的部分是问题中被注释掉的部分-

var sa = new Google.Apis.Compute.v1.Data.ServiceAccount();
sa.Email = "blahblah@developer.gserviceaccount.com";
sa.Scopes = new[] { ComputeService.Scope.Compute,
    ComputeService.Scope.DevstorageFullControl };
newinst.ServiceAccounts.Add(sa);
在本节中,我需要开发人员控制台的主服务帐户的电子邮件,而不是我用来创建凭据的同一个服务帐户,但不要问我为什么。关键是实例启动了,gsutil现在正在愉快地复制。
谢谢你的时间和帮助大家

Ross

您是否从“gcloud config list”命令获得帐户和项目名称?@PaoloP。只是一个项目名称,也许您必须执行“gcloud auth login”并使用您的凭据进行身份验证。希望这有帮助。他不需要运行gcloud auth activate服务帐户,因为他正在尝试使用API创建一个实例,并且在VMI中有一个启动脚本。他尝试从一个单独的实例激活服务帐户,但这只意味着我可以将其用于该实例。我无法在当前实例上激活它,因为我无法上载密钥文件。对不起,实际代码中有@吗?我忘记将其包含在问题中。我是否需要将我的服务帐户及其作用域添加到插入请求的“服务帐户”字段?在开发人员控制台中找到的RESTAPI中似乎是这样做的,但当我这样做时,实例不会启动