summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHentioe <me@bluerain.io>2020-12-10 22:07:43 +0800
committerHentioe <me@bluerain.io>2020-12-10 22:07:43 +0800
commit4dbe70773b31f06f20c2c600d8c9d00b33624008 (patch)
treec2573955b3d0b72a78d23c0875cbf336804aa9c5
parentAdd run command related APIs (diff)
parentFix publish (diff)
Merge branch 'master' of github.com:Hentioe/azure_ex
-rw-r--r--README.md226
-rw-r--r--lib/azure_ex/token_hosting.ex18
-rw-r--r--mix.exs24
-rw-r--r--mix.lock5
4 files changed, 260 insertions, 13 deletions
diff --git a/README.md b/README.md
index 57c3475..3dded49 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,227 @@
# AzureEx
-WIP \ No newline at end of file
+[![Hex.pm](https://img.shields.io/hexpm/v/azure_ex.svg)](http://hex.pm/packages/azure_ex)
+
+An Azure API client.
+
+## Current state
+
+Due to the huge number of Azure APIs, this library only provides a small part of the API. For similar reasons, models and model fields are also very lacking!
+
+Therefore, I very much need your contributions to finally complete this library. Just like me, just submit the part you need!
+
+## Installation
+
+Add Telegex to your mix.exs dependencies:
+
+```elixir
+def deps do
+ [{:azure_ex, "~> 0.1.0-rc.0"}]
+end
+```
+
+Run the `mix deps.get` command to install.
+
+## Configuration
+
+Obtain the necessary parameters for applying for Token through [this article](https://mauridb.medium.com/calling-azure-rest-api-via-curl-eb10a06127), and fill in the following template:
+
+```elixir
+config :azure_ex,
+ tenant: "<Tenant ID>",
+ client_id: "<App ID>",
+ client_secret: "<Password>"
+```
+
+You can also learn about the role and creation process of the service principal based on this [official document](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli).
+
+## Usage
+
+We use a sample code to show how to create a virtual machine. Please prepare the values of some variables, including the subscription ID of your Azure account, the name of the resource group, and your local SSH public key data.
+
+```elixir
+def create_virtual_machine() do
+ alias AzureEx.Model.{
+ VirtualNetworks,
+ Subnets,
+ PublicIPAddress,
+ NetworkInterfaces,
+ VirtualMachines
+ }
+
+ # Initialize some variables.
+ location = "eastasia"
+ subscription_id = "<Subscription ID>"
+ resource_group = "<Resource group>"
+ os_username = "ubuntu"
+ vm_name = "ubuntu20-test"
+ vm_size = "Standard_B1s"
+ ssh_public_key_data = "<SSH public key data>"
+
+ # Create a virtual network.
+ virutal_network_data = %VirtualNetworks.CreateOrUpdate{
+ location: location,
+ properties: %VirtualNetworks.CreateOrUpdate.Properties{
+ addressSpace: %VirtualNetworks.CreateOrUpdate.AddressSpace{
+ addressPrefixes: ["10.0.0.0/16"]
+ }
+ }
+ }
+
+ {:ok, _} =
+ AzureEx.create_or_update_virtual_networks(
+ subscription_id,
+ resource_group,
+ "#{resource_group}-vnet-#{location}",
+ data: virutal_network_data
+ )
+
+ # Create a default subnet.
+ subnet_data = %Subnets.CreateOrUpdate{
+ name: "default",
+ properties: %Subnets.CreateOrUpdate.Properties{
+ addressPrefix: "10.0.0.0/16"
+ }
+ }
+
+ AzureEx.create_or_update_subnets(
+ subscription_id,
+ resource_group,
+ "#{resource_group}-vnet-#{location}",
+ "default",
+ data: subnet_data
+ )
+
+ # Create a public IP address.
+ public_ip_address_data = %PublicIPAddress.CreateOrUpdate{
+ location: location,
+ properties: %PublicIPAddress.CreateOrUpdate.Properties{
+ publicIPAddressVersion: "ipv4"
+ }
+ }
+
+ {:ok, public_ip_address} =
+ AzureEx.create_or_update_public_ip_address(
+ subscription_id,
+ resource_group,
+ "#{vm_name}-ip",
+ data: public_ip_address_data
+ )
+
+ # Create a network interface.
+ network_interface_data = %NetworkInterfaces.CreateOrUpdate{
+ location: location,
+ properties: %NetworkInterfaces.CreateOrUpdate.Properties{
+ ipConfigurations: [
+ %NetworkInterfaces.CreateOrUpdate.NetworkInterfaceIPConfiguration{
+ name: "#{vm_name}-ic",
+ properties:
+ %NetworkInterfaces.CreateOrUpdate.NetworkInterfaceIPConfiguration.Properties{
+ subnet: %NetworkInterfaces.CreateOrUpdate.Subnet{
+ id:
+ "/subscriptions/#{subscription_id}/resourceGroups/#{resource_group}/providers/Microsoft.Network/virtualNetworks/#{
+ resource_group
+ }-vnet-#{location}/subnets/default"
+ },
+ publicIPAddress: %NetworkInterfaces.CreateOrUpdate.PublicIPAddress{
+ id: public_ip_address[:id]
+ }
+ }
+ }
+ ]
+ }
+ }
+
+ {:ok, network_interface} =
+ AzureEx.create_or_update_network_interfaces(
+ subscription_id,
+ resource_group,
+ "#{vm_name}-ni",
+ data: network_interface_data
+ )
+
+ # Create a virtual machine.
+ virtual_machine_data = %VirtualMachines.CreateOrUpdate{
+ location: location,
+ properties: %VirtualMachines.CreateOrUpdate.Properties{
+ hardwareProfile: %VirtualMachines.CreateOrUpdate.HardwareProfile{
+ vmSize: vm_size
+ },
+ networkProfile: %VirtualMachines.CreateOrUpdate.NetworkProfile{
+ networkInterfaces: [
+ %VirtualMachines.CreateOrUpdate.NetworkInterfaceReference{
+ id: network_interface[:id]
+ }
+ ]
+ },
+ storageProfile: %VirtualMachines.CreateOrUpdate.StorageProfile{
+ osDisk: %VirtualMachines.CreateOrUpdate.OSDisk{
+ name: "#{vm_name}-disk",
+ createOption: "FromImage"
+ },
+ imageReference: %VirtualMachines.CreateOrUpdate.ImageReference{
+ offer: "0001-com-ubuntu-server-focal",
+ publisher: "canonical",
+ sku: "20_04-lts",
+ version: "latest"
+ }
+ },
+ osProfile: %VirtualMachines.CreateOrUpdate.OSProfile{
+ adminUsername: os_username,
+ computerName: vm_name,
+ linuxConfiguration: %VirtualMachines.CreateOrUpdate.LinuxConfiguration{
+ ssh: %VirtualMachines.CreateOrUpdate.SshConfiguration{
+ publicKeys: [
+ %VirtualMachines.CreateOrUpdate.SshPublicKey{
+ path: "/home/ubuntu/.ssh/authorized_keys",
+ keyData: ssh_public_key_data
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+
+ {:ok, _} =
+ AzureEx.create_or_update_virtual_machines(
+ subscription_id,
+ resource_group,
+ "#{vm_name}-vm",
+ data: virtual_machine_data
+ )
+end
+```
+
+Call this function:
+
+```elixir
+iex> AzureEx.create_virtual_machine()
+{:ok, %{...}}
+```
+
+Visit https://portal.azure.com/ to view the virtual machine and associated resources just created.
+
+## Documentation
+
+All necessary parameters in the API are the path parameters of the URL. In addition, each API has an optional parameter.
+
+The `options` parameter in all APIs:
+
+- `data`: Create or update the required data model, the type is `map`. It will eventually be converted into a JSON string and sent as the request body.
+- `params`: A list of keywords, used as query parameters to construct the complete URL of the API. For example, you can override the default value of the `api-version` parameter: `callAPI(arg1, arg2, params: ["api-version": "2010-06-01"])`
+
+## Development
+
+This library uses a well-designed macro to parse the original URI in the Azure document during compilation and create the corresponding API, so you only need to copy it (via the Copy it button in the document page) to add a new API. E.g:
+
+```
+defendpoint(
+ "ListByResourceGroupResources",
+ "GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/resources?api-version=2020-06-01"
+)
+```
+
+The `defendpoint/2` call needs to be defined in the `lib/azure.ex` file.
+
+In addition, APIs involved in creating or updating also include data models. You should define them under the `lib/model` directory.
diff --git a/lib/azure_ex/token_hosting.ex b/lib/azure_ex/token_hosting.ex
index e659fd5..6c0a4c8 100644
--- a/lib/azure_ex/token_hosting.ex
+++ b/lib/azure_ex/token_hosting.ex
@@ -1,14 +1,14 @@
defmodule AzureEx.TokenHosting do
@moduledoc false
- # TODO: 轮询检查令牌有效性。
-
use GenServer
require Logger
defmodule Token do
- @moduledoc false
+ @moduledoc """
+ Azure API token.
+ """
defstruct [:access_token, :expires_in, :created_at]
@@ -26,7 +26,9 @@ defmodule AzureEx.TokenHosting do
end
defmodule Params do
- @moduledoc false
+ @moduledoc """
+ Parameters for applying token.
+ """
defstruct [:tenant, :client_id, :client_secret]
@@ -75,12 +77,8 @@ defmodule AzureEx.TokenHosting do
apply_token(params)
- {:error, e} ->
- # TODO: 抽象出错误模型
- Logger.error("Token application failed, details: #{inspect(e)}")
- :timer.sleep(500)
-
- apply_token(params)
+ e ->
+ e
end
end
diff --git a/mix.exs b/mix.exs
index 6ffcc09..b95fcce 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,13 +1,32 @@
defmodule AzureEx.MixProject do
use Mix.Project
+ @version "0.1.0-rc.0"
+ @description "Azure API client"
+
def project do
[
app: :azure_ex,
- version: "0.1.0",
+ version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
- deps: deps()
+ deps: deps(),
+ description: @description,
+ package: package(),
+ name: "AzureEx",
+ source_url: "https://github.com/Hentioe/azure_ex",
+ docs: [
+ # The main page in the docs
+ main: "readme",
+ extras: ["README.md"]
+ ]
+ ]
+ end
+
+ defp package do
+ [
+ licenses: ["MIT"],
+ links: %{"GitHub" => "https://github.com/Hentioe/azure_ex"}
]
end
@@ -22,6 +41,7 @@ defmodule AzureEx.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
+ {:ex_doc, "~> 0.23.0"},
{:httpoison, "~> 1.7"},
{:typed_struct, "~> 0.2.1"},
{:dialyxir, "~> 1.0", only: [:dev], runtime: false},
diff --git a/mix.lock b/mix.lock
index 0b98f11..4769168 100644
--- a/mix.lock
+++ b/mix.lock
@@ -3,14 +3,19 @@
"certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
"credo": {:hex, :credo, "1.4.1", "16392f1edd2cdb1de9fe4004f5ab0ae612c92e230433968eab00aafd976282fc", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "155f8a2989ad77504de5d8291fa0d41320fdcaa6a1030472e9967f285f8c7692"},
"dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
+ "earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
+ "ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
"file_system": {:hex, :file_system, "0.2.9", "545b9c9d502e8bfa71a5315fac2a923bd060fd9acb797fe6595f54b0f975fd32", [:mix], [], "hexpm", "3cf87a377fe1d93043adeec4889feacf594957226b4f19d5897096d6f61345d8"},
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
"httpoison": {:hex, :httpoison, "1.7.0", "abba7d086233c2d8574726227b6c2c4f6e53c4deae7fe5f6de531162ce9929a0", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "975cc87c845a103d3d1ea1ccfd68a2700c211a434d8428b10c323dc95dc5b980"},
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
+ "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
+ "makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
+ "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"typed_struct": {:hex, :typed_struct, "0.2.1", "e1993414c371f09ff25231393b6430bd89d780e2a499ae3b2d2b00852f593d97", [:mix], [], "hexpm", "8f5218c35ec38262f627b2c522542f1eae41f625f92649c0af701a6fab2e11b3"},