问题描述
我正在尝试通过Python脚本在Google Cloud上创建IoT设备。
我已经设置了项目,IoT注册表并验证了我的GCloud,并将GOOGLE_APPLICATION_CREDENTIALS从相应的服务帐户链接到json。
为什么我使用命令行创建帐户,例如
gcloud iot devices create dev01 --project=... --region=... --registry=...
,
有用。
但是,我的Python脚本(通过命令提示符运行)似乎无法产生相同的结果。我使用https://cloud.google.com/iot/docs/samples/device-manager-samples#iot-core-create-rs256-python作为iot_v1参考。
# Generate Key
key = rsa.generate_private_key(backend=default_backend(),public_exponent=65537,key_size=2048)
# Get Public
public_key = key.public_key().public_bytes(serialization.Encoding.OpenSSH,serialization.PublicFormat.OpenSSH)
# Get Private
pem = key.private_bytes(encoding=serialization.Encoding.PEM,format=serialization.PrivateFormat.TraditionalOpenSSL,encryption_algorithm=serialization.NoEncryption())
# Decode to UTF-8
private_key_str = pem.decode('utf-8')
public_key_str = public_key.decode('utf-8')
# Write keys
with open('Key Pairs/'+deviceName+'_private.pem','wb') as file:
file.write(pem)
with open('Key Pairs/' + deviceName + '_public.pem','wb') as file:
file.write(public_key)
# Create Device
client = iot_v1.DeviceManagerClient()
parent = client.registry_path(PROJECTID,REGION,REGISTRY)
deviceTemplate = {
'id': deviceName,"credentials": [
{
"public_key": {
"format": iot_v1.PublicKeyFormat.RSA_X509_PEM,"key": public_key_str,}
}
]
}
client.create_device(request={'parent': parent,'device': deviceTemplate})
错误回溯是
File "commissioning.py",line 46,in <module>
client.create_device(request={'parent': parent,'device': deviceTemplate})
File "C:\Users\Niels\AppData\Local\Programs\Python\python38\lib\site-packages\google\cloud\iot_v1\services\device_manager\client.py",line 728,in create_device
response = rpc(request,retry=retry,timeout=timeout,Metadata=Metadata,)
File "C:\Users\Niels\AppData\Local\Programs\Python\python38\lib\site-packages\google\api_core\gapic_v1\method.py",line 145,in __call__
return wrapped_func(*args,**kwargs)
File "C:\Users\Niels\AppData\Local\Programs\Python\python38\lib\site-packages\google\api_core\grpc_helpers.py",line 59,in error_remapped_callable
six.raise_from(exceptions.from_grpc_error(exc),exc)
File "<string>",line 3,in raise_from
google.api_core.exceptions.PermissionDenied: 403 The caller does not have permission
我想这可能是我使用iot_v1的方式存在问题,还是具有Python的权限。任何帮助/提示将不胜感激!
解决方法
确保用于创建客户端的服务帐户至少分配了roles/cloudiot.provisioner
角色(如果继续收到权限错误,请尝试向服务帐户添加roles/cloudiot.admin
角色,因为它应该授予对所有IoT设备的完全控制权,找到有关所有可用权限here的更多信息。)
一旦您确定服务帐户具有正确的权限,就可以利用iot_v1.DeviceManagerClient() class提供的credentials
参数来确保您指向服务帐户密钥文件,如上所述。文档的Authentication部分。