开始使用 Predix - 开发者之旅 - 第一集
在第一集中,我们将处理第一件事:安全。我们正处于一段旅程的开始。我们将学习许多 Predix 服务和组件。我们将发现好、坏和丑,并一路抱怨。在安全之后,我们将接触资产和分析。
Predix 是通用电气 (GE) 面向工业互联网的应用平台。Predix 基于 Cloud Foundry 构建,针对云端和边缘的安全连接和大规模分析进行了优化。.
Pirsig 写道:“机器的考验在于它给你带来的满意度。没有其他的考验。”本集旨在通过帮助您顺利连接服务来提高您对 Predix 的满意度。大家好,我是 Rich Dost,我正在 Predix 上构建应用程序并撰写博客。
在第一集中,我们将处理第一件事:安全。我们正处于一段旅程的开始。我们将学习许多 Predix 服务和组件。我们将发现好、坏和丑,并一路抱怨。在安全之后,我们将接触资产和分析。然后我们将从那里继续前进。
您应该关心吗?您应该继续阅读吗?“好工匠凭工具而知”。我们的工具是 Predix。我们将让 Predix 运转起来,我们将一起完成。这够了吗?
准备好为工业互联网编写代码了吗?在此处注册免费试用版 here。
关于 Rich
他们说“吹嘘会说服你”……我做开发者已经三十年了,而且我一直在进步。我现在比几年前更好了。那时我比几年前更好。以此类推,回溯三十年。大脑是可塑的,而我的大脑针对开发进行了优化。这并非自动发生。只有当你关心质量时,它才会发生。
在 GE,我曾帮助开发 Predix Asset。我的首次亮相是在晚上重写了整个 UI。新 UI 亮相后,获得了许多掌声,也有一些敌意,以及他们的赞扬。我们的参考客户认为它“棒极了!”一位同行宣称我是“GE 有史以来最酷的新员工!”我获得了 GE 的一项特别奖,表彰我“……跳出框框思考、解决难题的能力……想法和交付让你与众不同……”。很棒的东西。
第二年,我完成了 25% 的故事,作为 18 人小组中的一员,同时成功领导了 UI 工作,按期完成了主要 UI 架构师曾宣称不可能完成的任务。这也得到了认可。“你就是一支军队!”一位同事开发者说。
去年,我制作的优质产品包括 Asset 脚本引擎,灵感来源于我对 Lambda 的热爱,并获得了 GE 的专利。感觉最好。然而,Spotlight(下图),一个快速而粗糙的基于 D3 的工具,用于在资产网络中可视化 GEL 查询,在几个晚上完成,却获得了最多的关注。华而不实的东西确实有效。
现在我不知何故成为了 Predix Builder。这是怎么发生的?这是让我写这篇博客的诡计吗?
最重要的是,为了您的娱乐,我是一个反传统者,这是一种花哨的说法,意思是我是个麻烦制造者。我常常惹麻烦,因为我关心质量,这也不错。但将其与这篇博客结合起来,将是我的末日。看着这一切,是不是很有趣?
设置安全
那么,让我们开始构建 Predix 应用程序的旅程吧!创造价值的前景令人兴奋!各种想法涌上心头。但在创造任何价值之前,我们需要处理安全问题。
设置安全是这篇博客文章的主题。Predix 对安全非常重视,这在如今很难反驳。安全必须在任何其他事情之前设置,而且这样做很容易出问题。这很不幸,也很讽刺,因为一旦通过安全,Predix 就易于使用。
在《禅与摩托车维修艺术》中有一个小插曲。法厄德斯有一个详细的计划。他的思维超前。但他一开始连发动机盖都打不开!这让他很沮丧。他犯了错误,浪费了时间。那里有禅意。我希望能让您免于法厄德斯的经历。
在项目开始时,我们只需要开始所需的步骤。这不是一些人所期望的,但这就是敏捷的运作方式。设置一个绑定到 Predix 微服务的 UAA 就足够了。首先,我们将逐步完成这些步骤。稍后,我们将创建一个可扩展的脚本框架,以添加其他微服务。
命令
执行以下命令后,在您的笔记本电脑本地运行的代码将能够访问 Predix Asset。Predix Asset 是我们将使用的微服务。根据我的经验,这是一个合理的起点。
Cloud Foundry 登录
凭证应该存储在哪里?有些人把它们放在脚本中,然后不小心推送到 GitHub!这可能会导致巨额账单。就我个人而言,我喜欢把它们存储在一个单独的文件中。稍后我们编写脚本时再考虑这个问题。
让我们也在一个干净的目录中工作。“整洁近乎神圣”,这有助于我们稍后推送一个虚拟应用程序。
1> mkdir ~/tempForBlog1; cd ~/tempForBlog1 2> cf login # with your credentials
创建 UAA 服务
Predix Asset,就像所有 Predix 服务一样,需要一个绑定的 UAA。当您发出请求时,Asset 微服务通过与 UAA 通信来验证您的令牌。让我们创建 UAA。重要提示:您需要记住 UAA 密钥,在本例中为“my-secret”。不要丢失它,否则您将不得不重新进行此过程。您还需要服务名称,下面是 my-uaa。但如果您忘记了,可以使用 bash 命令 > cf s 轻松恢复。
3> cf create-service predix-uaa Tiered my-uaa -c '{"adminClientSecret":"my-secret"}'
获取 UAA 要点
我们需要获取新 UAA 的环境变量。一种实现方法是绑定到一个虚拟应用程序。这里我们创建一个简单的空 HTML 文件作为我们的虚拟应用程序。环境变量是从下面的 cf env 命令输出的。我们需要的是 URL 和 issuerId。稍后我们真正需要它们时,将进一步介绍它们。
应用程序名称必须是唯一的,因为应用程序 URL 遵循 appname... 的模式,并且 URL 必须是唯一的。这里我们使用 `whoami` 命令生成一个唯一的名称。如果 `whoami` 对您不起作用,只需用您的姓名首字母代替 whoami。
4> appname=`whoami`.temp.html # need unique name 5> touch $appname 6> cf push --no-start $appname 7> cf bs $appname my-uaa 8> cf env $appname # Output is environment variables 9> cf delete $appname --f
创建资产服务
我们准备好创建资产了。UAA 的 URL 已从上面的 cf env 命令输出。您会在 `VCAP_SERVICES.predix-uaa.issuerId` 键的右侧找到它。它应该包含字符串 "predix-uaa"。将您找到的 URL 作为数组的唯一成员放置在下面 "trustedIssuerIds" 键的右侧,替换现有 URL。然后运行命令。
10> cf create-service predix-asset Tiered my-asset -c '{"trustedIssuerIds":["https://2edfb28e-e02c-4ae9-a7cd-818c263128d8.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token"]}'
获取资产要点
我们再次需要环境变量,这次是针对 Asset 的。命令与我们上面用于 UAA 的命令相似。我们需要从下面 `cf env` 命令的输出中获取 `VCAP_SERVICES.predix-asset.instanceId` 值。
11> touch $appname 12> cf push --no-start $appname 13> cf bs $appname my-asset 14> cf env $appname
UAAC 目标 UAA
如果您尚未安装 UAAC,请立即安装。
UAAC 目标命令中的 URL 是 UAA 的基本 URL。它与我们上面在命令 10 (cf create-service predix-asset...) 中使用的 URL 相同,只是我们需要从末尾截断 "/oauth/token"。然后将令牌获取到 UAA 中。
15> uaac target https://2edfb28e-e02c-4ae9-a7cd-818c263128d8.predix-uaa.run.aws-usw02-pr.ice.predix.io 16> uaac token client get admin --secret my-secret # gets the admin token, NOT usable for asset
添加 UAAC 客户端
我们需要使用资产的实例 ID,有时称为 Predix 区域 ID。它是上面命令 14 (cf env...) 输出中的 `VCAP_SERVICES.predix-asset.instanceId` 值。将命令 17 (uaac client add asset-client...) 中 "predix-asset.zones" 和 ".user" 之间的 UUID 替换掉。有两处需要替换。很容易使用错误的服务的 instanceId,这会导致问题。
17> uaac client add asset-client --authorities openid,uaa.none,uaa.resource,predix-asset.zones.6827f028-5b6b-439e-ae08-9587cedb6f56.user --scope uaa.none,openid,predix-asset.zones.6827f028-5b6b-439e-ae08-9587cedb6f56.user --autoapprove openid --authorized_grant_types authorization_code,client_credentials,refresh_token,password --secret my-secret --name asset-client
获取然后显示令牌
运行下面的命令并查找“access_token”键。它的值就是令牌。在将其与 Asset 一起使用之前,我们需要在它前面加上字符串“bearer ”。当令牌过期时,重复这两个命令。
18> uaac token client get asset-client --secret my-secret # if token expires then do this again 19> uaac context
通过与 Asset 通信进行验证
上面“获取资产要点”下的 `13> cf env` 输出中包含资产的 URL。查找 `VCAP_SERVICES.predix-asset[0].uri` 的 URI 值。使用该 URL 访问资产。
curl https://predix-asset.run.aws-usw02-pr.ice.predix.io
您应该会看到一条消息,内容为“...PA_TENANT_NOT_PRESENT”,“message”:“The predix-zone-id header was not provided...”。如果没有,则表示您没有访问到 Asset。检查 URL。该消息表示我们需要添加 predix-zone-id。这是上面 `VCAP_SERVICES.predix-asset[0].instanceId` 的值。我们将其添加到 curl 中。
curl -H "predix-zone-id: 5aacd7de-f6da-42f6-8e3f-6c6c6dd595fd" https://predix-asset.run.aws-usw02-pr.ice.predix.io
资产仍然不响应,嘟囔着“Authorization header is missing”。每当您访问微服务时,您都会提供一个令牌。在幕后,微服务会与 UAA 核对以验证令牌。令牌放在“Authorization”头中。使用 `17> uaac context` 获取令牌。然后加上“bearer”。它又大又丑,但您可以做到。
curl -H "predix-zone-id: 5aacd7de-f6da-42f6-8e3f-6c6c6dd595fd" -H "Authorization: bearer eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI1MzI5NjhlZS0yODgzLTQ2MTUtOGQ4Ny05OTI1NzhiZDcyNjAiLCJzdWIiOiJhZG1pbiIsInNjb3BlIjpbImNsaWVudHMucmVhZCIsInpvbmVzLjFmNmNkZGJkLTMzZTMtNDYwMy1iYzhmLTllYzVmNTMyM2FhNS5hZG1pbiIsImNsaWVudHMuc2VjcmV0IiwiaWRwcy53cml0ZSIsInVhYS5yZXNvdXJjZSIsImNsaWVudHMud3JpdGUiLCJjbGllbnRzLmFkbWluIiwiaWRwcy5yZWFkIiwic2NpbS53cml0ZSIsInNjaW0ucmVhZCJdLCJjbGllbnRfaWQiOiJhZG1pbiIsImNpZCI6ImFkbWluIiwiYXpwIjoiYWRtaW4iLCJncmFudF90eXBlIjoiY2xpZW50X2NyZWRlbnRpYWxzIiwicmV2X3NpZyI6IjFjODQ5ZTE1IiwiaWF0IjoxNDcyMTU2Mzc5LCJleHAiOjE0NzIxOTk1NzksImlzcyI6Imh0dHBzOi8vMWY2Y2RkYmQtMzNlMy00NjAzLWJjOGYtOWVjNWY1MzIzYWE1LnByZWRpeC11YWEucnVuLmF3cy11c3cwMi1wci5pY2UucHJlZGl4LmlvL29hdXRoL3Rva2VuIiwiemlkIjoiMWY2Y2RkYmQtMzNlMy00NjAzLWJjOGYtOWVjNWY1MzIzYWE1IiwiYXVkIjpbImFkbWluIiwiY2xpZW50cyIsInpvbmVzLjFmNmNkZGJkLTMzZTMtNDYwMy1iYzhmLTllYzVmNTMyM2FhNSIsImlkcHMiLCJ1YWEiLCJzY2ltIl19.PefjwSI-x43lZebZRBxJ93IrSxz9Ha9rgpILCUI41th-i4G3PGqatjckAgdgdtpcVsT4sLs_nYZQxqHstiH5_B2Bs6crmhTkr1-owAGhL3U_hB4T5Jia3ahHHnsTjE768Nq6pw-pL6KvgZkcf5RiwoUtaKmSrtpeziUw8RLE-JJFNq-rTWd_yNh7YqzjzsxNuZ56vufRWq2KLhZEddwGAr_9EFQ4g2bDypmC5xrpFzB2CxGIx-5WDklMdYH-9TJ5BYt06gCh0ctd1ryWhV3gSs4-QM2D1w7Nvub4m9yFYFaJ5_6EizAMkTASOPLaF8JaWxo_pADf66_DgU-eH2if7Q" https://predix-asset.run.aws-usw02-pr.ice.predix.io
如果您做得一切正确,您将得到 `[]` 的返回值。我告诉您这篇博客值得您花时间阅读。您的麻烦得到了一个空数组的回报!
说真的,这是 Asset 告诉您数据库中没有任何内容的方式。让我们发布一个对象。我们将添加一个“`Content-Type: Application/json`”标头,以及一个由数组包围的 JSON 对象。对于发布,Asset 要求 URL 以与对象的 URI 属性匹配的集合结尾。集合由发布创建,因此这是一个很好的、一步到位的过程。我们不需要架构等。对于此示例,我们将创建资源 `/tests/my-first-test`,其中包含一些随机数据。
为简洁起见,我们将使用“”代替下面又大又丑的。当然,您仍然需要使用您的真实令牌,否则您会收到权限错误。
curl -X POST -d '[{ "uri": "/tests/my-first-test", "foo": true, "bar": [34,56] }]' -H "Content-Type: application/json" -H "predix-zone-id: 87af97a0-c4a9-49fd-a002-240aacb3c540" -H "Authorization: <BEARER-TOKEN>" https://predix-asset.run.aws-usw02-pr.ice.predix.io/tests
Asset 不会回复太多,除了一个状态。所以让我们把我们的资源取回来。您应该会看到已发布的 JavaScript 对象。
curl -H "predix-zone-id: 87af97a0-c4a9-49fd-a002-240aacb3c540" -H "Authorization: <BEARER-TOKEN>" https://predix-asset.run.aws-usw02-pr.ice.predix.io/tests/my-first-test
为了完成循环,让我们再次获取基础页面。上次返回了一个空数组。现在应该有更多内容。
curl -H "predix-zone-id: 5aacd7de-f6da-42f6-8e3f-6c6c6dd595fd" -H "Authorization: <BEARER-TOKEN>" https://predix-asset.run.aws-usw02-pr.ice.predix.io
您应该会看到 `[{"collection":"tests","count":1}]`。这意味着有一个名为 tests 的集合,其中包含一个资源。
故障排除
解码令牌
最常见的错误是使用错误的令牌。令牌包含编码信息。您可以使用 UAAC token decode 命令解码令牌。有些人喜欢使用 jwt.io 网站。特别验证 aud 和 sub。
>uaac token decode Note: no key given to validate token signature jti: 50bff558-ff1f-4022-a365-2910d43e843f sub: my-asset-client scope: uaa.resource openid uaa.none predix-asset.zones.87af97a0-c4a9-49fd-a002-240aacb3c540.user client_id: my-asset-client cid: my-asset-client azp: my-asset-client grant_type: client_credentials rev_sig: b35a26d7 iat: 1472492881 exp: 1472536081 iss: https://15c87001-2030-424d-99d8-5778cd314f46.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token zid: 15c87001-2030-424d-99d8-5778cd314f46 aud: my-asset-client uaa openid predix-asset.zones.87af97a0-c4a9-49fd-a002-240aacb3c540
检索 InstanceIds
您可以使用 cf service 命令检索您的实例 ID。
>cf s Getting services in org dost@ge.com / space dev as dost@ge.com... OK name service plan bound apps last operation my-asset predix-asset Tiered create succeeded my-uaa predix-uaa Tiered create succeeded >cf service my-uaa --guid 15c87001-2030-424d-99d8-5778cd314f46 >cf service my-asset --guid 87af97a0-c4a9-49fd-a002-240aacb3c540 >uaac token get client my-asset-client--secret my-secret >uaac token get client my-asset-client --secret my-secret
跟踪 CF 命令
您可以使用 `CF_TRACE` 了解 cf 命令在底层做了什么。先不使用跟踪,然后再使用跟踪尝试一个命令。
>cf service my-asset >CF_TRACE=true cf service my-asset
跟踪 UAAC 命令
UAAC 会调用 UAA REST 端点来执行其工作。有些人喜欢直接使用这种方式。要查看 UAAC 对 UAA 发出的 REST 调用,只需添加 `--trace` 命令选项。下面我们首先不使用 `--trace`,然后使用 `--trace` 执行 uaac groups。
>uaac groups error response: { "error": "insufficient_scope", "error_description": "Insufficient scope for this resource", "scope": "scim.read zones.15c87001-2030-424d-99d8-5778cd314f46.admin" } >uaac --trace groups ---> request: get https://15c87001-2030-424d-99d8-5778cd314f46.predix-uaa.run.aws-usw02-pr.ice.predix.io/Groups?startIndex=1 headers: {"authorization"=>"bearer eyJhbGc... ...OVejRJfw", "accept"=>"application/json;charset=utf-8"} <--- response: 403 headers: {"cache-control"=>"no-cache, no-store, max-age=0, must-revalidate, no-store", "content-type"=>"application/json;charset=utf-8", "correlation-id"=>"f8924b82-e0d6-404c-a89a-c36b1f6e6616", "date"=>"Mon, 29 Aug 2016 21:04:03 GMT", "expires"=>"0", "pragma"=>"no-cache, no-cache", "server"=>"Apache-Coyote/1.1", "strict-transport-security"=>"max-age=31536000 ; includeSubDomains", "www-authenticate"=>"Bearer error=\"insufficient_scope\", error_description=\"Insufficient scope for this resource\", scope=\"scim.read zones.15c87001-2030-424d-99d8-5778cd314f46.admin\"", "x-content-type-options"=>"nosniff", "x-frame-options"=>"DENY", "x-vcap-request-id"=>"eb1fb8b7-1188-4417-537d-511361d56830", "x-xss-protection"=>"1; mode=block", "content-length"=>"158", "connection"=>"Close"} body: {"error":"insufficient_scope","error_description":"Insufficient scope for this resource","scope":"scim.read zones.15c87001-2030-424d-99d8-5778cd314f46.admin"} error response: { "error": "insufficient_scope", "error_description": "Insufficient scope for this resource", "scope": "scim.read zones.15c87001-2030-424d-99d8-5778cd314f46.admin" }
相关资源
以下是我认为对理解安全系统有价值的资源。
- 如果您是 Cloud Foundry 的新手,请花些时间仔细阅读 cf help。
- Cloud Foundry UAA 存储库和文档
- 一篇关于 UAA 和 所有组件如何协同工作 的好文章,来自 Cloud Foundry 文档。
- Predix.io UAA 服务文档非常有用。
- UAAC 是一个 UAA 命令行工具。
- 采纳团队创建了一个名为 Predix 工具包 的出色基于 Web 的工具。
- 有一个基于网络的 UAA 仪表板可以帮助管理您的实例。登录 Predix.io,选择您的空间,然后选择服务,例如 UAA。
- 一本关于质量的书
敬请期待
在不久的将来,我们将拥有许多 Predix 服务,它们将协同工作。手动使用 cf 命令进行设置很容易出错。认真的开发需要可重复性和自动化。在未来的剧集中,我们将创建一个可扩展的脚本框架来满足这一需求。
您可以在此处注册 Predix 帐户,并在Predix.io开始您的工业互联网之旅。