diff --git a/.changelog/1333.txt b/.changelog/1333.txt new file mode 100644 index 0000000000..81026e8158 --- /dev/null +++ b/.changelog/1333.txt @@ -0,0 +1,47 @@ +```release-note:breaking-change +rulesets: `GetZoneRuleset` is removed in favour of `GetRuleset` +``` + +```release-note:breaking-change +rulesets: `GetAccountRuleset` is removed in favour of `GetRuleset` +``` + +```release-note:breaking-change +rulesets: `CreateZoneRuleset` is removed in favour of `CreateRuleset` +``` + +```release-note:breaking-change +rulesets: `CreateAccountRuleset` is removed in favour of `CreateRuleset` +``` + +```release-note:breaking-change +rulesets: `DeleteZoneRuleset` is removed in favour of `DeleteRuleset` +``` + +```release-note:breaking-change +rulesets: `DeleteAccountRuleset` is removed in favour of `DeleteRuleset` +``` + +```release-note:breaking-change +rulesets: `UpdateZoneRuleset` is removed in favour of `UpdateRuleset` +``` + +```release-note:breaking-change +rulesets: `UpdateAccountRuleset` is removed in favour of `UpdateRuleset` +``` + +```release-note:breaking-change +rulesets: `GetZoneRulesetPhase` is removed in favour of `GetEntrypointRuleset` +``` + +```release-note:breaking-change +rulesets: `GetAccountRulesetPhase` is removed in favour of `GetEntrypointRuleset` +``` + +```release-note:breaking-change +rulesets: `UpdateZoneRulesetPhase` is removed in favour of `UpdateEntrypointRuleset` +``` + +```release-note:breaking-change +rulesets: `UpdateAccountRulesetPhase` is removed in favour of `UpdateEntrypointRuleset` +``` diff --git a/rulesets.go b/rulesets.go index 72a7a4f3bf..80ebed208c 100644 --- a/rulesets.go +++ b/rulesets.go @@ -10,6 +10,10 @@ import ( "time" ) +var ( + ErrMissingRulesetPhase = errors.New("missing required phase") +) + const ( RulesetKindCustom RulesetKind = "custom" RulesetKindManaged RulesetKind = "managed" @@ -711,24 +715,40 @@ type UpdateRulesetResponse struct { Result Ruleset `json:"result"` } -// ListZoneRulesets fetches all rulesets for a zone. -// -// API reference: https://api.cloudflare.com/#zone-rulesets-list-zone-rulesets -func (api *API) ListZoneRulesets(ctx context.Context, zoneID string) ([]Ruleset, error) { - return api.listRulesets(ctx, ZoneRouteRoot, zoneID) +type ListRulesetsParams struct{} + +type CreateRulesetParams struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Kind string `json:"kind,omitempty"` + Version *string `json:"version,omitempty"` + Phase string `json:"phase,omitempty"` + Rules []RulesetRule `json:"rules"` + ShareableEntitlementName string `json:"shareable_entitlement_name,omitempty"` } -// ListAccountRulesets fetches all rulesets for an account. -// -// API reference: https://api.cloudflare.com/#account-rulesets-list-account-rulesets -func (api *API) ListAccountRulesets(ctx context.Context, accountID string) ([]Ruleset, error) { - return api.listRulesets(ctx, AccountRouteRoot, accountID) +type UpdateRulesetParams struct { + ID string `json:"-"` + Description string `json:"description"` + Rules []RulesetRule `json:"rules"` } -// listRulesets lists all Rulesets for a given zone or account depending on the -// identifier type provided. -func (api *API) listRulesets(ctx context.Context, identifierType RouteRoot, identifier string) ([]Ruleset, error) { - uri := fmt.Sprintf("/%s/%s/rulesets", identifierType, identifier) +type UpdateEntrypointRulesetParams struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Kind string `json:"kind,omitempty"` + Version *string `json:"version,omitempty"` + Phase string `json:"-"` + Rules []RulesetRule `json:"rules"` +} + +// ListRulesets lists all Rulesets for a given zone or account depending on the +// ResourceContainer type provided. +// +// API reference: https://api.cloudflare.com/#zone-rulesets-list-zone-rulesets +// API reference: https://api.cloudflare.com/#account-rulesets-list-account-rulesets +func (api *API) ListRulesets(ctx context.Context, rc *ResourceContainer, params ListRulesetsParams) ([]Ruleset, error) { + uri := fmt.Sprintf("/%s/%s/rulesets", rc.Level, rc.Identifier) res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { @@ -743,24 +763,12 @@ func (api *API) listRulesets(ctx context.Context, identifierType RouteRoot, iden return result.Result, nil } -// GetZoneRuleset fetches a single ruleset for a zone. +// GetRuleset fetches a single ruleset. // // API reference: https://api.cloudflare.com/#zone-rulesets-get-a-zone-ruleset -func (api *API) GetZoneRuleset(ctx context.Context, zoneID, rulesetID string) (Ruleset, error) { - return api.getRuleset(ctx, ZoneRouteRoot, zoneID, rulesetID) -} - -// GetAccountRuleset fetches a single ruleset for an account. -// // API reference: https://api.cloudflare.com/#account-rulesets-get-an-account-ruleset -func (api *API) GetAccountRuleset(ctx context.Context, accountID, rulesetID string) (Ruleset, error) { - return api.getRuleset(ctx, AccountRouteRoot, accountID, rulesetID) -} - -// getRuleset fetches a single ruleset based on the zone or account, the -// identifier and the ruleset ID. -func (api *API) getRuleset(ctx context.Context, identifierType RouteRoot, identifier, rulesetID string) (Ruleset, error) { - uri := fmt.Sprintf("/%s/%s/rulesets/%s", identifierType, identifier, rulesetID) +func (api *API) GetRuleset(ctx context.Context, rc *ResourceContainer, rulesetID string) (Ruleset, error) { + uri := fmt.Sprintf("/%s/%s/rulesets/%s", rc.Level, rc.Identifier, rulesetID) res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { return Ruleset{}, err @@ -774,23 +782,13 @@ func (api *API) getRuleset(ctx context.Context, identifierType RouteRoot, identi return result.Result, nil } -// CreateZoneRuleset creates a new ruleset for a zone. +// CreateRuleset initialises a new ruleset. // // API reference: https://api.cloudflare.com/#zone-rulesets-create-zone-ruleset -func (api *API) CreateZoneRuleset(ctx context.Context, zoneID string, ruleset Ruleset) (Ruleset, error) { - return api.createRuleset(ctx, ZoneRouteRoot, zoneID, ruleset) -} - -// CreateAccountRuleset creates a new ruleset for an account. -// // API reference: https://api.cloudflare.com/#account-rulesets-create-account-ruleset -func (api *API) CreateAccountRuleset(ctx context.Context, accountID string, ruleset Ruleset) (Ruleset, error) { - return api.createRuleset(ctx, AccountRouteRoot, accountID, ruleset) -} - -func (api *API) createRuleset(ctx context.Context, identifierType RouteRoot, identifier string, ruleset Ruleset) (Ruleset, error) { - uri := fmt.Sprintf("/%s/%s/rulesets", identifierType, identifier) - res, err := api.makeRequestContext(ctx, http.MethodPost, uri, ruleset) +func (api *API) CreateRuleset(ctx context.Context, rc *ResourceContainer, params CreateRulesetParams) (Ruleset, error) { + uri := fmt.Sprintf("/%s/%s/rulesets", rc.Level, rc.Identifier) + res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params) if err != nil { return Ruleset{}, err } @@ -803,23 +801,12 @@ func (api *API) createRuleset(ctx context.Context, identifierType RouteRoot, ide return result.Result, nil } -// DeleteZoneRuleset deletes a single ruleset for a zone. +// DeleteRuleset removes a ruleset based on the ruleset ID. // // API reference: https://api.cloudflare.com/#zone-rulesets-delete-zone-ruleset -func (api *API) DeleteZoneRuleset(ctx context.Context, zoneID, rulesetID string) error { - return api.deleteRuleset(ctx, ZoneRouteRoot, zoneID, rulesetID) -} - -// DeleteAccountRuleset deletes a single ruleset for an account. -// // API reference: https://api.cloudflare.com/#account-rulesets-delete-account-ruleset -func (api *API) DeleteAccountRuleset(ctx context.Context, accountID, rulesetID string) error { - return api.deleteRuleset(ctx, AccountRouteRoot, accountID, rulesetID) -} - -// deleteRuleset removes a ruleset based on the ruleset ID. -func (api *API) deleteRuleset(ctx context.Context, identifierType RouteRoot, identifier, rulesetID string) error { - uri := fmt.Sprintf("/%s/%s/rulesets/%s", identifierType, identifier, rulesetID) +func (api *API) DeleteRuleset(ctx context.Context, rc *ResourceContainer, rulesetID string) error { + uri := fmt.Sprintf("/%s/%s/rulesets/%s", rc.Level, rc.Identifier, rulesetID) res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) if err != nil { return err @@ -835,25 +822,17 @@ func (api *API) deleteRuleset(ctx context.Context, identifierType RouteRoot, ide return nil } -// UpdateZoneRuleset updates a single ruleset for a zone. +// UpdateRuleset updates a ruleset based on the ruleset ID. // // API reference: https://api.cloudflare.com/#zone-rulesets-update-a-zone-ruleset -func (api *API) UpdateZoneRuleset(ctx context.Context, zoneID, rulesetID, description string, rules []RulesetRule) (Ruleset, error) { - return api.updateRuleset(ctx, ZoneRouteRoot, zoneID, rulesetID, description, rules) -} - -// UpdateAccountRuleset updates a single ruleset for an account. -// // API reference: https://api.cloudflare.com/#account-rulesets-update-account-ruleset -func (api *API) UpdateAccountRuleset(ctx context.Context, accountID, rulesetID, description string, rules []RulesetRule) (Ruleset, error) { - return api.updateRuleset(ctx, AccountRouteRoot, accountID, rulesetID, description, rules) -} +func (api *API) UpdateRuleset(ctx context.Context, rc *ResourceContainer, params UpdateRulesetParams) (Ruleset, error) { + if params.ID == "" { + return Ruleset{}, ErrMissingResourceIdentifier + } -// updateRuleset updates a ruleset based on the ruleset ID. -func (api *API) updateRuleset(ctx context.Context, identifierType RouteRoot, identifier, rulesetID, description string, rules []RulesetRule) (Ruleset, error) { - uri := fmt.Sprintf("/%s/%s/rulesets/%s", identifierType, identifier, rulesetID) - payload := UpdateRulesetRequest{Description: description, Rules: rules} - res, err := api.makeRequestContext(ctx, http.MethodPut, uri, payload) + uri := fmt.Sprintf("/%s/%s/rulesets/%s", rc.Level, rc.Identifier, params.ID) + res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params) if err != nil { return Ruleset{}, err } @@ -866,24 +845,9 @@ func (api *API) updateRuleset(ctx context.Context, identifierType RouteRoot, ide return result.Result, nil } -// GetZoneRulesetPhase returns a ruleset phase for a zone. -// -// API reference: TBA. -func (api *API) GetZoneRulesetPhase(ctx context.Context, zoneID, rulesetPhase string) (Ruleset, error) { - return api.getRulesetPhase(ctx, ZoneRouteRoot, zoneID, rulesetPhase) -} - -// GetAccountRulesetPhase returns a ruleset phase for an account. -// -// API reference: TBA. -func (api *API) GetAccountRulesetPhase(ctx context.Context, accountID, rulesetPhase string) (Ruleset, error) { - return api.getRulesetPhase(ctx, AccountRouteRoot, accountID, rulesetPhase) -} - -// getRulesetPhase returns a ruleset phase based on the zone or account and the -// identifier. -func (api *API) getRulesetPhase(ctx context.Context, identifierType RouteRoot, identifier, rulesetPhase string) (Ruleset, error) { - uri := fmt.Sprintf("/%s/%s/rulesets/phases/%s/entrypoint", identifierType, identifier, rulesetPhase) +// GetEntrypointRuleset returns a ruleset phase based on the resource entrypoint. +func (api *API) GetEntrypointRuleset(ctx context.Context, rc *ResourceContainer, phase string) (Ruleset, error) { + uri := fmt.Sprintf("/%s/%s/rulesets/phases/%s/entrypoint", rc.Level, rc.Identifier, phase) res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { return Ruleset{}, err @@ -897,25 +861,14 @@ func (api *API) getRulesetPhase(ctx context.Context, identifierType RouteRoot, i return result.Result, nil } -// UpdateZoneRulesetPhase updates a ruleset phase for a zone. -// -// API reference: TBA. -func (api *API) UpdateZoneRulesetPhase(ctx context.Context, zoneID, rulesetPhase string, ruleset Ruleset) (Ruleset, error) { - return api.updateRulesetPhase(ctx, ZoneRouteRoot, zoneID, rulesetPhase, ruleset) -} - -// UpdateAccountRulesetPhase updates a ruleset phase for an account. -// -// API reference: TBA. -func (api *API) UpdateAccountRulesetPhase(ctx context.Context, accountID, rulesetPhase string, ruleset Ruleset) (Ruleset, error) { - return api.updateRulesetPhase(ctx, AccountRouteRoot, accountID, rulesetPhase, ruleset) -} +// UpdateEntrypointRuleset updates a ruleset phase based on the entrypoint. +func (api *API) UpdateEntrypointRuleset(ctx context.Context, rc *ResourceContainer, params UpdateEntrypointRulesetParams) (Ruleset, error) { + if params.Phase == "" { + return Ruleset{}, ErrMissingRulesetPhase + } -// updateRulesetPhase updates a ruleset phase based on the zone or account, the -// identifier and the rules. -func (api *API) updateRulesetPhase(ctx context.Context, identifierType RouteRoot, identifier, rulesetPhase string, ruleset Ruleset) (Ruleset, error) { - uri := fmt.Sprintf("/%s/%s/rulesets/phases/%s/entrypoint", identifierType, identifier, rulesetPhase) - res, err := api.makeRequestContext(ctx, http.MethodPut, uri, ruleset) + uri := fmt.Sprintf("/%s/%s/rulesets/phases/%s/entrypoint", rc.Level, rc.Identifier, params.Phase) + res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params) if err != nil { return Ruleset{}, err } diff --git a/rulesets_test.go b/rulesets_test.go index 52e9ed88ce..d2d654a1f0 100644 --- a/rulesets_test.go +++ b/rulesets_test.go @@ -52,12 +52,12 @@ func TestListRulesets(t *testing.T) { }, } - zoneActual, err := client.ListZoneRulesets(context.Background(), testZoneID) + zoneActual, err := client.ListRulesets(context.Background(), ZoneIdentifier(testZoneID), ListRulesetsParams{}) if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.ListAccountRulesets(context.Background(), testAccountID) + accountActual, err := client.ListRulesets(context.Background(), AccountIdentifier(testAccountID), ListRulesetsParams{}) if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -101,12 +101,12 @@ func TestGetRuleset_MagicTransit(t *testing.T) { Phase: string(RulesetPhaseMagicTransit), } - zoneActual, err := client.GetZoneRuleset(context.Background(), testZoneID, "2c0fc9fa937b11eaa1b71c4d701ab86e") + zoneActual, err := client.GetRuleset(context.Background(), ZoneIdentifier(testZoneID), "2c0fc9fa937b11eaa1b71c4d701ab86e") if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.GetAccountRuleset(context.Background(), testAccountID, "2c0fc9fa937b11eaa1b71c4d701ab86e") + accountActual, err := client.GetRuleset(context.Background(), AccountIdentifier(testAccountID), "2c0fc9fa937b11eaa1b71c4d701ab86e") if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -188,12 +188,12 @@ func TestGetRuleset_WAF(t *testing.T) { Rules: rules, } - zoneActual, err := client.GetZoneRuleset(context.Background(), testZoneID, "b232b534beea4e00a21dcbb7a8a545e9") + zoneActual, err := client.GetRuleset(context.Background(), ZoneIdentifier(testZoneID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.GetAccountRuleset(context.Background(), testAccountID, "b232b534beea4e00a21dcbb7a8a545e9") + accountActual, err := client.GetRuleset(context.Background(), AccountIdentifier(testAccountID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -343,12 +343,12 @@ func TestGetRuleset_SetCacheSettings(t *testing.T) { Rules: rules, } - zoneActual, err := client.GetZoneRuleset(context.Background(), testZoneID, "b232b534beea4e00a21dcbb7a8a545e9") + zoneActual, err := client.GetRuleset(context.Background(), ZoneIdentifier(testZoneID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.GetAccountRuleset(context.Background(), testAccountID, "b232b534beea4e00a21dcbb7a8a545e9") + accountActual, err := client.GetRuleset(context.Background(), AccountIdentifier(testAccountID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -454,12 +454,12 @@ func TestGetRuleset_SetConfig(t *testing.T) { Rules: rules, } - zoneActual, err := client.GetZoneRuleset(context.Background(), testZoneID, "b232b534beea4e00a21dcbb7a8a545e9") + zoneActual, err := client.GetRuleset(context.Background(), ZoneIdentifier(testZoneID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.GetAccountRuleset(context.Background(), testAccountID, "b232b534beea4e00a21dcbb7a8a545e9") + accountActual, err := client.GetRuleset(context.Background(), AccountIdentifier(testAccountID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -543,12 +543,12 @@ func TestGetRuleset_RedirectFromValue(t *testing.T) { Rules: rules, } - zoneActual, err := client.GetZoneRuleset(context.Background(), testZoneID, "b232b534beea4e00a21dcbb7a8a545e9") + zoneActual, err := client.GetRuleset(context.Background(), ZoneIdentifier(testZoneID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.GetAccountRuleset(context.Background(), testAccountID, "b232b534beea4e00a21dcbb7a8a545e9") + accountActual, err := client.GetRuleset(context.Background(), AccountIdentifier(testAccountID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -623,12 +623,12 @@ func TestGetRuleset_CompressResponse(t *testing.T) { Rules: rules, } - zoneActual, err := client.GetZoneRuleset(context.Background(), testZoneID, "b232b534beea4e00a21dcbb7a8a545e9") + zoneActual, err := client.GetRuleset(context.Background(), ZoneIdentifier(testZoneID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.GetAccountRuleset(context.Background(), testAccountID, "b232b534beea4e00a21dcbb7a8a545e9") + accountActual, err := client.GetRuleset(context.Background(), AccountIdentifier(testAccountID), "b232b534beea4e00a21dcbb7a8a545e9") if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -691,7 +691,7 @@ func TestCreateRuleset(t *testing.T) { Enabled: BoolPtr(true), }} - newRuleset := Ruleset{ + newRuleset := CreateRulesetParams{ Name: "my example ruleset", Description: "Test magic transit ruleset", Kind: "root", @@ -710,12 +710,12 @@ func TestCreateRuleset(t *testing.T) { Rules: rules, } - zoneActual, err := client.CreateZoneRuleset(context.Background(), testZoneID, newRuleset) + zoneActual, err := client.CreateRuleset(context.Background(), ZoneIdentifier(testZoneID), newRuleset) if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.CreateAccountRuleset(context.Background(), testAccountID, newRuleset) + accountActual, err := client.CreateRuleset(context.Background(), AccountIdentifier(testAccountID), newRuleset) if assert.NoError(t, err) { assert.Equal(t, want, accountActual) } @@ -734,10 +734,10 @@ func TestDeleteRuleset(t *testing.T) { mux.HandleFunc("/accounts/"+testAccountID+"/rulesets/2c0fc9fa937b11eaa1b71c4d701ab86e", handler) mux.HandleFunc("/zones/"+testZoneID+"/rulesets/2c0fc9fa937b11eaa1b71c4d701ab86e", handler) - zErr := client.DeleteZoneRuleset(context.Background(), testZoneID, "2c0fc9fa937b11eaa1b71c4d701ab86e") + zErr := client.DeleteRuleset(context.Background(), ZoneIdentifier(testZoneID), "2c0fc9fa937b11eaa1b71c4d701ab86e") assert.NoError(t, zErr) - aErr := client.DeleteAccountRuleset(context.Background(), testAccountID, "2c0fc9fa937b11eaa1b71c4d701ab86e") + aErr := client.DeleteRuleset(context.Background(), AccountIdentifier(testAccountID), "2c0fc9fa937b11eaa1b71c4d701ab86e") assert.NoError(t, aErr) } @@ -823,6 +823,12 @@ func TestUpdateRuleset(t *testing.T) { Enabled: BoolPtr(true), }} + updated := UpdateRulesetParams{ + ID: "2c0fc9fa937b11eaa1b71c4d701ab86e", + Description: "Test Firewall Ruleset Update", + Rules: rules, + } + want := Ruleset{ ID: "2c0fc9fa937b11eaa1b71c4d701ab86e", Name: "ruleset1", @@ -834,12 +840,12 @@ func TestUpdateRuleset(t *testing.T) { Rules: rules, } - zoneActual, err := client.UpdateZoneRuleset(context.Background(), testZoneID, "2c0fc9fa937b11eaa1b71c4d701ab86e", "Test Firewall Ruleset Update", rules) + zoneActual, err := client.UpdateRuleset(context.Background(), ZoneIdentifier(testZoneID), updated) if assert.NoError(t, err) { assert.Equal(t, want, zoneActual) } - accountActual, err := client.UpdateAccountRuleset(context.Background(), testAccountID, "2c0fc9fa937b11eaa1b71c4d701ab86e", "Test Firewall Ruleset Update", rules) + accountActual, err := client.UpdateRuleset(context.Background(), AccountIdentifier(testAccountID), updated) if assert.NoError(t, err) { assert.Equal(t, want, accountActual) }