Repository: hetznercloud/hcloud-go
Pull request #102 (2018-11-14 07:39:50)

Add `NextActions`


Patch:
diff --git a/CHANGES.md b/CHANGES.md
index f3425ca..10919a1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,9 @@
 # Changes
 
+## master
+
+* Add `NextActions` to `ServerCreateResult` and `VolumeCreateResult`
+
 ## v1.10.0
 
 * Add `WithApplication()` client option to provide an application name and version
diff --git a/hcloud/schema.go b/hcloud/schema.go
index 828033c..47a194f 100644
--- a/hcloud/schema.go
+++ b/hcloud/schema.go
@@ -35,6 +35,15 @@ func ActionFromSchema(s schema.Action) *Action {
 	return action
 }
 
+// ActionsFromSchema converts a slice of schema.Action to a slice of Action.
+func ActionsFromSchema(s []schema.Action) []*Action {
+	var actions []*Action
+	for _, a := range s {
+		actions = append(actions, ActionFromSchema(a))
+	}
+	return actions
+}
+
 // FloatingIPFromSchema converts a schema.FloatingIP to a FloatingIP.
 func FloatingIPFromSchema(s schema.FloatingIP) *FloatingIP {
 	f := &FloatingIP{
diff --git a/hcloud/schema/server.go b/hcloud/schema/server.go
index f58e3b8..edaf54c 100644
--- a/hcloud/schema/server.go
+++ b/hcloud/schema/server.go
@@ -90,9 +90,10 @@ type ServerCreateRequest struct {
 // ServerCreateResponse defines the schema of the response when
 // creating a server.
 type ServerCreateResponse struct {
-	Server       Server  `json:"server"`
-	Action       Action  `json:"action"`
-	RootPassword *string `json:"root_password"`
+	Server       Server   `json:"server"`
+	Action       Action   `json:"action"`
+	RootPassword *string  `json:"root_password"`
+	NextActions  []Action `json:"next_actions"`
 }
 
 // ServerUpdateRequest defines the schema of the request to update a server.
diff --git a/hcloud/schema/volume.go b/hcloud/schema/volume.go
index aa6c699..a8aa793 100644
--- a/hcloud/schema/volume.go
+++ b/hcloud/schema/volume.go
@@ -28,8 +28,9 @@ type VolumeCreateRequest struct {
 // VolumeCreateResponse defines the schema of the response
 // when creating a volume.
 type VolumeCreateResponse struct {
-	Volume Volume  `json:"volume"`
-	Action *Action `json:"action"`
+	Volume      Volume   `json:"volume"`
+	Action      *Action  `json:"action"`
+	NextActions []Action `json:"next_actions"`
 }
 
 // VolumeListResponse defines the schema of the response
diff --git a/hcloud/server.go b/hcloud/server.go
index 8707ed4..ad0b16e 100644
--- a/hcloud/server.go
+++ b/hcloud/server.go
@@ -229,6 +229,7 @@ type ServerCreateResult struct {
 	Server       *Server
 	Action       *Action
 	RootPassword string
+	NextActions  []*Action
 }
 
 // Create creates a new server.
@@ -287,8 +288,9 @@ func (c *ServerClient) Create(ctx context.Context, opts ServerCreateOpts) (Serve
 		return ServerCreateResult{}, resp, err
 	}
 	result := ServerCreateResult{
-		Server: ServerFromSchema(respBody.Server),
-		Action: ActionFromSchema(respBody.Action),
+		Server:      ServerFromSchema(respBody.Server),
+		Action:      ActionFromSchema(respBody.Action),
+		NextActions: ActionsFromSchema(respBody.NextActions),
 	}
 	if respBody.RootPassword != nil {
 		result.RootPassword = *respBody.RootPassword
diff --git a/hcloud/volume.go b/hcloud/volume.go
index 8a74081..735f391 100644
--- a/hcloud/volume.go
+++ b/hcloud/volume.go
@@ -161,8 +161,9 @@ func (o VolumeCreateOpts) Validate() error {
 
 // VolumeCreateResult is the result of creating a volume.
 type VolumeCreateResult struct {
-	Volume *Volume
-	Action *Action
+	Volume      *Volume
+	Action      *Action
+	NextActions []*Action
 }
 
 // Create creates a new volume with the given options.
@@ -209,8 +210,9 @@ func (c *VolumeClient) Create(ctx context.Context, opts VolumeCreateOpts) (Volum
 	}
 
 	return VolumeCreateResult{
-		Volume: VolumeFromSchema(respBody.Volume),
-		Action: action,
+		Volume:      VolumeFromSchema(respBody.Volume),
+		Action:      action,
+		NextActions: ActionsFromSchema(respBody.NextActions),
 	}, resp, nil
 }
 


Test patch:
diff --git a/hcloud/schema_test.go b/hcloud/schema_test.go
index c103364..1ef9802 100644
--- a/hcloud/schema_test.go
+++ b/hcloud/schema_test.go
@@ -70,6 +70,27 @@ func TestActionFromSchema(t *testing.T) {
 	}
 }
 
+func TestActionsFromSchema(t *testing.T) {
+	data := []byte(`[
+		{
+			"id": 13,
+			"command": "create_server"
+		},
+		{
+			"id": 14,
+			"command": "start_server"
+		}
+	]`)
+	var s []schema.Action
+	if err := json.Unmarshal(data, &s); err != nil {
+		t.Fatal(err)
+	}
+	actions := ActionsFromSchema(s)
+	if len(actions) != 2 || actions[0].ID != 13 || actions[1].ID != 14 {
+		t.Fatal("unexpected actions")
+	}
+}
+
 func TestFloatingIPFromSchema(t *testing.T) {
 	t.Run("IPv6", func(t *testing.T) {
 		data := []byte(`{
diff --git a/hcloud/server_test.go b/hcloud/server_test.go
index 5eb74ac..283c87b 100644
--- a/hcloud/server_test.go
+++ b/hcloud/server_test.go
@@ -269,6 +269,9 @@ func TestServersCreateWithSSHKeys(t *testing.T) {
 			Server: schema.Server{
 				ID: 1,
 			},
+			NextActions: []schema.Action{
+				{ID: 2},
+			},
 		})
 	})
 
@@ -294,6 +297,9 @@ func TestServersCreateWithSSHKeys(t *testing.T) {
 	if result.RootPassword != "" {
 		t.Errorf("expected no root password, got: %v", result.RootPassword)
 	}
+	if len(result.NextActions) != 1 || result.NextActions[0].ID != 2 {
+		t.Errorf("unexpected next actions: %v", result.NextActions)
+	}
 }
 
 func TestServersCreateWithoutSSHKeys(t *testing.T) {
diff --git a/hcloud/volume_test.go b/hcloud/volume_test.go
index 77180df..d77af54 100644
--- a/hcloud/volume_test.go
+++ b/hcloud/volume_test.go
@@ -242,7 +242,27 @@ func TestVolumeClientCreateWithServer(t *testing.T) {
 						"type": "volume"
 					}
 				]
-			}
+			},
+			"next_actions": [
+				{
+					"id": 3,
+					"command": "attach_volume",
+					"status": "running",
+					"progress": 0,
+					"started": "2016-01-30T23:50:15+00:00",
+					"finished": null,
+					"resources": [
+						{
+							"id": 42,
+							"type": "server"
+						},
+						{
+							"id": 1,
+							"type": "volume"
+						}
+					]
+				}
+			]
 		}`)
 	})
 
@@ -262,6 +282,9 @@ func TestVolumeClientCreateWithServer(t *testing.T) {
 	if result.Action.ID != 2 {
 		t.Errorf("unexpected action ID: %v", result.Action.ID)
 	}
+	if len(result.NextActions) != 1 || result.NextActions[0].ID != 3 {
+		t.Errorf("unexpected next actions: %v", result.NextActions)
+	}
 }
 
 func TestVolumeClientCreateWithLocation(t *testing.T) {