diff --git a/hcloud/server.go b/hcloud/server.go index 142e8429..00bcb903 100644 --- a/hcloud/server.go +++ b/hcloud/server.go @@ -348,8 +348,9 @@ func (o ServerCreateOpts) Validate() error { return errors.New("location and datacenter are mutually exclusive") } if o.PublicNet != nil { - if !o.PublicNet.EnableIPv4 && !o.PublicNet.EnableIPv6 && len(o.Networks) == 0 { - return errors.New("missing networks when EnableIPv4 and EnableIPv6 is false") + if !o.PublicNet.EnableIPv4 && !o.PublicNet.EnableIPv6 && + len(o.Networks) == 0 && (o.StartAfterCreate == nil || *o.StartAfterCreate) { + return errors.New("missing networks or StartAfterCreate == false when EnableIPv4 and EnableIPv6 is false") } } return nil diff --git a/hcloud/server_test.go b/hcloud/server_test.go index 4add328b..81681cdc 100644 --- a/hcloud/server_test.go +++ b/hcloud/server_test.go @@ -902,6 +902,24 @@ func TestServersCreateWithoutStarting(t *testing.T) { } } +func TestServersCreateFailIfNoIPsAndNetworksAssigned(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + ctx := context.Background() + _, _, err := env.Client.Server.Create(ctx, ServerCreateOpts{ + Name: "test", + ServerType: &ServerType{ID: 1}, + Image: &Image{ID: 2}, + PublicNet: &ServerCreatePublicNet{ + EnableIPv4: false, + EnableIPv6: false, + }, + }) + if err == nil { + t.Fatal(err) + } +} + func TestServerCreateWithPlacementGroup(t *testing.T) { env := newTestEnv() defer env.Teardown() @@ -951,6 +969,55 @@ func TestServerCreateWithPlacementGroup(t *testing.T) { } } +func TestServerCreateWithoutPrimaryIPsButNetwork(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { + var reqBody schema.ServerCreateRequest + if err := json.NewDecoder(r.Body).Decode(&reqBody); err != nil { + t.Fatal(err) + } + if reqBody.PublicNet.EnableIPv4 != false && reqBody.PublicNet.EnableIPv6 != false { + t.Errorf("unexpected public net %v", reqBody.PublicNet) + } + json.NewEncoder(w).Encode(schema.ServerCreateResponse{ + Server: schema.Server{ + ID: 1, + }, + NextActions: []schema.Action{ + {ID: 2}, + }, + }) + }) + + ctx := context.Background() + result, _, err := env.Client.Server.Create(ctx, ServerCreateOpts{ + Name: "test", + ServerType: &ServerType{ID: 1}, + Image: &Image{ID: 2}, + Networks: []*Network{ + {ID: 1}, + }, + PublicNet: &ServerCreatePublicNet{ + EnableIPv4: false, + EnableIPv6: false, + }, + }) + if err != nil { + t.Fatal(err) + } + if result.Server == nil { + t.Fatal("no server") + } + if result.Server.ID != 1 { + t.Errorf("unexpected server ID: %d", result.Server.ID) + } + if len(result.NextActions) != 1 || result.NextActions[0].ID != 2 { + t.Errorf("unexpected next actions: %v", result.NextActions) + } +} + func TestServersDelete(t *testing.T) { env := newTestEnv() defer env.Teardown()