在現代化的虛擬化環境中,自動化管理虛擬機器的需求日益增長。本文將探討如何使用 Python 結合 vCenter API,實作虛擬機器資訊的自動化提取。首先,我們會透過 requests 函式庫與 vCenter API 建立連線,並取得必要的驗證資訊。接著,利用 pyVimpyVmomi 函式庫與 vCenter 伺服器建立連線,並透過 RetrieveContent() 方法取得 vCenter 中所有物件的內容。藉由遍歷容器檢視,我們可以找到目標虛擬機器,並提取其相關資訊,例如 VM ID、虛擬機器名稱、作業系統全名、作業系統 ID、資源池、網路和資料存放區等。這些資訊可以作為後續自動化操作的依據,例如組態管理、資源排程和監控等。此方法能有效提升虛擬機器管理效率,並減少人工操作的錯誤率。

透過 Python 與 vCenter API 的整合,我們可以輕鬆地取得虛擬機器的詳細資訊。程式碼中示範瞭如何使用 requests 函式庫傳送 HTTP 請求到 vCenter API,並處理 API 回應。同時,也示範瞭如何使用 pyVimpyVmomi 函式庫連線 vCenter 伺服器,並操作 vCenter 中的物件。透過這些技術,我們可以實作虛擬機器資訊的自動化提取,並為後續的自動化操作奠定基礎。

與 vCenter 驗證以取得 VM ID

def auth_vcenter(username, password): resp = requests.post( ‘{}/com/vmware/cis/session’.format(app_settings[‘api_url’]), auth=(app_settings[‘api_user’], app_settings[‘api_pass’]), verify=False ) if resp.status_code != 200: print(‘錯誤!API 傳回狀態碼: {}’.format(resp.status_code)) return return resp.json()[‘value’]

def get_api_data(req_url): sid = auth_vcenter(app_settings[‘api_user’], app_settings[‘api_pass’]) resp = requests.get(req_url, verify=False, headers={‘vmware-api-session-id’: sid}) if resp.status_code != 200: print(‘錯誤!API 傳回狀態碼: {}’.format(resp.status_code)) return return resp

取得虛擬機器詳細資訊,包括 VM ID

def get_vm(vm_name): resp = get_api_data(’{}/vcenter/vm?filter.names={}’.format(app_settings[‘api_url’], vm_name)) j = resp.json() return j

requests.packages.urllib3.disable_warnings(InsecureRequestWarning) vmdetails = get_vm(app_settings[‘VM_name’]) vmid = vmdetails[‘value’][0][‘vm’]

s = ssl._create_unverified_context() service_instance = connect.SmartConnect( host=app_settings[‘vcenter_ip’], user=app_settings[‘api_user’], pwd=app_settings[‘api_pass’], sslContext=s ) content = service_instance.RetrieveContent() container = content.rootFolder # 查詢起點 viewType = [vim.VirtualMachine] # 搜尋的物件型別 recursive = True # 是否遞迴查詢 containerView = content.viewManager.CreateContainerView(container, viewType, recursive) # 建立容器檢視 children = containerView.view

for child in children: if str(vmid) in str(child): vm_summary = child.summary # 欲匯入虛擬機器的摘要資訊 vm_config = child.config # 虛擬機器完整組態資料及子項值 vm_resourcepool = child.resourcePool # 資源池詳細資訊 vm_network = child.network # 虛擬機器網路詳細資訊 vm_datastore = child.datastore # 資料存放區詳細資訊 vm_parent = child.parent # 虛擬機器父專案詳細資訊 vm_name = child.name

print(“虛擬機器名稱: “, vm_name) print(“虛擬機器作業系統全名: “, vm_config.guestFullName) print(“虛擬機器作業系統 ID: “, vm_config.guestId)


#### 內容解密:
在這段程式碼中,玄貓首先定義了一些應用程式設定,包含 API 認證、URL  vCenter IP 地址等重要資訊。接著,玄貓定義了兩個主要的函式:`auth_vcenter` 用於與 vCenter 驗證並取得 session ID`get_api_data` 用於從 vCenter API 請求資料。

`get_vm` 函式則用來取得特定虛擬機器的詳細資訊,包括 VM ID。這是反向工程過程中的關鍵步驟,因為 VM ID 是唯一標識每個虛擬機器的鑰匙。

在主程式邏輯中,玄貓使用 `requests` 函式庫來停用不安全請求警告,並從 vCenter API 中取得所需的虛擬機器資訊。然後,使用 `pyVim`  `pyVmomi` 函式庫來連線到 vCenter 機器並檢索容器檢視中的所有虛擬機器。

當找到目標虛擬機器時,玄貓會提取其摘要、組態、資源池、網路和存放區等詳細資訊,並列印出虛擬機器名稱、作業系統全名和作業系統 ID

這些步驟展示瞭如何透過反向工程技術從 VMware MOB 中提取所需的組態引數,以便生成組態檔案或進行其他自動化操作。

### 摘要

在這一章節中,玄貓重點介紹了反向工程的基本概念及其在 Terraform 自動化工作流程中的應用。透過實際範例,玄貓展示瞭如何使用 Python 指令碼從 VMware 的管理物件瀏覽器(MOB)中提取虛擬機器的組態引數。

這些引數可以用來生成 Terraform 需要的組態檔案,從而實作自動化匯入現有 VMware 虛擬機器的功能。這樣的反向工程技術不僅能夠解決 Terraform 在自動化過程中的一些不足之處,還能夠大大提升基礎設施管理的效率和準確性。

### 下一步

在下一章節中,玄貓將探討如何使用 Terraform 完成這些反向工程步驟。玄貓會詳細說明每個階段的操作細節,並提供更多實際範例和自動化指令碼。讓我們繼續深入探索吧!

#### 次段落標題(包含「內容解密:」)

##### 小段落標題

## Terraform 構架與資訊提取

在前一章中,我們探討了反向工程的三個基本步驟。第一步是資訊提取,這裡我們需要收集有關產品設計和運作的資訊。在此,我們將探討 Terraform 架構,並解釋如何利用這些架構來模擬我們所需的資訊,進而構建反向工程解決方案。我們將討論的架構是通用的,旨在解釋 Terraform 的核心功能及其與不同基礎設施平台的互動方式。本文的目標是讓讀者瞭解 Terraform 與「真實來源」的運作方式。

### Terraform 架構概述

Terraform 目前支援多種提供者(providers),並且有超過 800 個提供者二進位檔案。為了管理這些多樣的提供者二進位檔案,HashiCorp 必須對每一個進行管理,這將會非常困難。相反地,HashiCorp  Terraform 架構設計為可擴充套件的架構。這意味著相應的平台可以提供對 Terraform 核心的支援,並維護它們自己的提供者外掛及其生命週期。Terraform 提供「提供者 SDK」,這是一個軟體開發工具包,定義了 Terraform 核心如何與特定平台所撰寫的外掛互動。此外,為了支援撰寫提供者(這些提供者專屬於每個平台),Terraform 提供了「Terraform-provider-scaffolding」,這是一個程式碼儲存函式庫,提供了一個範本,定義瞭如何撰寫一個提供者。此範本包含以下內容:

- 資源和資料來源(internal/provider/
- 範例(examples/)和產生的檔案(docs/
- 各種元檔

這些由 HashiCorp 提供的範本包含了您需要編輯以建立自己的 Terraform 提供者所需的樣板程式碼。一旦撰寫完成,平台供應商需要將其釋出到由 HashiCorp 維護的 Terraform 登入檔中,以便該提供者可以被廣泛使用。

由於 Terraform 是根據外掛的架構,因此這些 Terraform 外掛使所有開發者都能透過撰寫新外掛或編譯現有外掛來擴充套件 Terraform 的使用。如圖 4-1 所示,「Terraform 架構」圖中展示了兩個主要組成部分:Terraform 核心和 Terraform 外掛。Terraform 核心透過遠端程式呼叫(RPCs)與外掛進行互動,並且提供多種方式來發現和載入外掛以進一步與目標平台進行互動。正是這些 Terraform 外掛使得 Terraform 能夠為特定服務(例如 AzureVMwareGCP 等)暴露實作。

#### 此圖示
```mermaid
graph TD;
    A[Terraform Core] --> B[Providers];
    A --> C[Provisioners];
    A --> D[Plugins];
    A --> E[Golang];
    A --> F[Client Library];
    A --> G[HTTP(S)];
    A --> H[RPC];

    B --> I[Azure];
    B --> J[VMware];
    B --> K[GCP];

Terraform 核心

Terraform 核心是開源程式碼且託管在 GitHub 上(https://github.com/hashicorp/Terraform)。它是一組由 Go 語言編譯而成的一致列表二進位檔案。這些編譯後的二進位檔案稱為 Terraform CLI。CLI 使用 RPCs 與 Terraform 外掛通訊並提供多種方式來發現和載入外掛以進行使用。以下是 Terraform 核心的一些關鍵功能:

  • 模擬基礎設施即程式碼(IaC)。它使得讀取和內插組態檔案和 Terraform 模組成為可能。
  • 管理由 Terraform 控制的資源狀態。
  • 建立依賴圖從 Terraform 組態檔案並遍歷此圖以生成 Terraform 暨計劃、重新整理狀態等。
  • 執行 Terraform 暨計劃。
  • 透過 RPCs 與外掛通訊。

如圖 4-2所示,「Terraform 核心與外掛互動」圖中展示了一些關鍵命令,例如 Diff()、Apply() 和 Refresh(),其中TerraForm Core 和 Providers透過RPCs進行互動。

此圖示

  graph TD;
    A[Core] --> B[Providers]
    A --> C[Plugins]
    A --> D[Upstream APIs]

    subgraph Providers
        direction TB
        E[Azure]
        F[VMware]
        G[GCP]
    end

    subgraph Plugins
        direction TB
        H[Provisioners]
        I[Provisioners]
        J[Provisioners]
    end

Provisioners

在本章節中,我們已經探討過TerraForm Provisioners 裝置在第二章裡面;它們允許遠端執行自定義程式碼直接在支援平台上。每個外掛會暴露特定服務(例如 Azure、GCP、VMware)的實作。

最終使用者在建立組態檔案時會定義相應的 Provisioners 和 Providers ,進一步允許透過 RPCs 與目標平台進行互動作用。當使用者建立組態檔案時也必須考慮到 terrafrom 的原則;也就是說不可以隨意更改或修改現有設定。

Provider 外掛

Provider 外掛包含一些關鍵組成部分:Providers 和 Provisions ,Providers 是由開發人員用 Go 語言撰寫的程式碼。它們是可執行二進位檔案,由 TerraForm Core 透過 RPCs 呼叫。我們已經在第二章中探討過 Provisions ,它允許遠端執行自定義程式碼直接在支援平台上。

Provider 外掛有一些關鍵責任包括初始化任何包含客戶端特定函式庫以進行 API 呼叫給上游 API 平台、授權給支援基礎設施平台以及定義與特定服務對應之管理資源等責任。

如圖4-2所示,一些重要函式能夠讓 Providers 與上游 API(Upstream APIs)進行互動作用包括:create(), Read(), Delete(), 和 Update()。

此外 Providers 的另一個關鍵責任包括:執行指令或指令碼給指定資源後續建立或遺棄。

各型別外掛

首先我們先來瞭解一些TerraForm Plugin 的種類別:

  1. Provider Plugins : 主要負責處理特定服務(如 AWS, Azure, GCP等)。
  2. Provisioner Plugins : 主要負責處理組態階段之外執行任務。
  3. Backend Plugins : 主要負責儲存和操作狀態資料。
  4. Helper Plugins : 主要負責協助其他外掛來處理常見任務。

Provider 和 Provisioners 責任

以下是 Provider 和 Provisioner 的一些主要責任:

  1. Provider
    • 初始化任何包含客戶端特定函式庫以進行 API 呼叫給上游 API 平台。
    • 授權給支援基礎設施平台。
    • 對映到特定服務之管理資源。
  2. Provisioner
    • 執行命令或指令碼在指定資源後續建立或遺棄。

Provider 和 Provisioner 的重要函式

以下是一些重要函式能夠讓 Providers 與上游 API(Upstream APIs)進行互動作用包括:

  1. create()
  2. Read()
  3. Delete()
  4. Update()

總結來說,理解Provider 和 Provisioner如何運作以及他們之間關係是很重要的一環;這樣才能夠更好地使用TerraForm來操作各種基礎設施服務。

使用案例分析及考量

假設我們有一個企業級雲端應用程式,需要佈署到多個雲端服務供應商如 AWS、Azure 和 GCP。我們可以利用TerraForm來達到這個目標;首先我們必須去選擇支援TerraForm Provider並且符合我們需求之雲端供應商。接下來我們就可以開始撰寫組態檔案;在組態檔案中我們必須明確指出雲端供應商、Region、VPC、Subnet等相關資訊;同時也必須考慮到安全性問題;比如說金鑰管理、網路安全群組等相關問題也必須要好好的考量清楚才行。

另外值得注意的一點就是當我們要更改某些設定時請務必注意不要隨意修改已經存在之設定;因為當我們隨意修改已經存在之設定時可能會導致出現不符合預期之結果甚至導致整個系統當機而無法正常執行。