diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 000000000..7a07cb556 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,15 @@ +# Development + +1. Clone the project to your preferred directory, using your preferred method. +2. Download the module and accompanying developer tooling. + + ```bash + $ go mod download + ``` + +3. Make changes. +4. Verify those changes. + + ```bash + $ make all + ``` diff --git a/EXAMPLES.md b/EXAMPLES.md new file mode 100644 index 000000000..81f694dbb --- /dev/null +++ b/EXAMPLES.md @@ -0,0 +1,118 @@ +# Examples + +Fastly's API is designed to work in the following manner: + +1. Create (or clone) a new configuration version for the service +2. Make any changes to the version +3. Validate the version +4. Activate the version + +This flow using the Golang client looks like this: + +```go +package main + +import ( + "fmt" + "log" + "os" + "github.com/fastly/go-fastly/v8/fastly" +) + +func main() { + // Create a client object. The client has no state, so it can be persisted + // and re-used. It is also safe to use concurrently due to its lack of state. + // There is also a DefaultClient() method that reads an environment variable. + // Please see the documentation for more information and details. + client, err := fastly.NewClient(os.Getenv("FASTLY_API_KEY")) + if err != nil { + log.Fatal(err) + } + + // You can find the service ID in the Fastly web console. + var serviceID = "SERVICE_ID" + + // We'll get the latest 'active' version by inspecting the service metadata and + // then finding which available version is the 'active' version. + service, err := client.GetService(&fastly.GetServiceInput{ + ID: serviceID, + }) + if err != nil { + log.Fatal(err) + } + + // Let's acquire a service version to clone from. We'll start by searching for + // the latest 'active' version available, and if there are no active versions, + // then we'll clone from whatever is the latest version. + latest := service.Versions[len(service.Versions)-1] + for _, version := range service.Versions { + if version.Active { + latest = version + break + } + } + + // Clone the latest version so we can make changes without affecting the + // active configuration. + version, err := client.CloneVersion(&fastly.CloneVersionInput{ + ServiceID: serviceID, + ServiceVersion: latest.Number, + }) + if err != nil { + log.Fatal(err) + } + + // Now you can make any changes to the new version. In this example, we will add + // a new domain. + domain, err := client.CreateDomain(&fastly.CreateDomainInput{ + ServiceID: serviceID, + ServiceVersion: version.Number, + Name: String("example.com"), + }) + if err != nil { + log.Fatal(err) + } + + // Output: "example.com" + fmt.Println("domain.Name:", domain.Name) + + // And we will also add a new backend. + backend, err := client.CreateBackend(&fastly.CreateBackendInput{ + ServiceID: serviceID, + ServiceVersion: version.Number, + Name: String("example-backend"), + Address: String("127.0.0.1"), + Port: Int(80), + }) + if err != nil { + log.Fatal(err) + } + + // Output: "example-backend" + fmt.Println("backend.Name:", backend.Name) + + // Now we can validate that our version is valid. + valid, _, err := client.ValidateVersion(&fastly.ValidateVersionInput{ + ServiceID: serviceID, + ServiceVersion: version.Number, + }) + if err != nil { + log.Fatal(err) + } + if !valid { + log.Fatal("not valid version") + } + + // Finally, activate this new version. + activeVersion, err := client.ActivateVersion(&fastly.ActivateVersionInput{ + ServiceID: serviceID, + ServiceVersion: version.Number, + }) + if err != nil { + log.Fatal(err) + } + + // Output: true + fmt.Println("activeVersion.Locked:", activeVersion.Locked) +} +``` diff --git a/README.md b/README.md index fe438fc33..0aa3d333e 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,7 @@ [latest]: https://pkg.go.dev/github.com/fastly/go-fastly/v8/fastly -Go Fastly is a Golang API client for interacting with most facets of the -[Fastly API](https://docs.fastly.com/api). - -## Installation - -This is a client library, so there is nothing to install. But, it uses Go modules, -so you must be running Go 1.11 or higher. +A Go client library for interacting with most facets of the [Fastly API](https://docs.fastly.com/api). ## Usage @@ -18,211 +12,9 @@ so you must be running Go 1.11 or higher. import "github.com/fastly/go-fastly/v8/fastly" ``` -## Examples - -Fastly's API is designed to work in the following manner: - -1. Create (or clone) a new configuration version for the service -2. Make any changes to the version -3. Validate the version -4. Activate the version - -This flow using the Golang client looks like this: - -```go -package main - -import ( - "fmt" - "log" - "os" - "github.com/fastly/go-fastly/v8/fastly" -) - -func main() { - // Create a client object. The client has no state, so it can be persisted - // and re-used. It is also safe to use concurrently due to its lack of state. - // There is also a DefaultClient() method that reads an environment variable. - // Please see the documentation for more information and details. - client, err := fastly.NewClient(os.Getenv("FASTLY_API_KEY")) - if err != nil { - log.Fatal(err) - } - - // You can find the service ID in the Fastly web console. - var serviceID = "SERVICE_ID" - - // We'll get the latest 'active' version by inspecting the service metadata and - // then finding which available version is the 'active' version. - service, err := client.GetService(&fastly.GetServiceInput{ - ID: serviceID, - }) - if err != nil { - log.Fatal(err) - } - - // Let's acquire a service version to clone from. We'll start by searching for - // the latest 'active' version available, and if there are no active versions, - // then we'll clone from whatever is the latest version. - latest := service.Versions[len(service.Versions)-1] - for _, version := range service.Versions { - if version.Active { - latest = version - break - } - } - - // Clone the latest version so we can make changes without affecting the - // active configuration. - version, err := client.CloneVersion(&fastly.CloneVersionInput{ - ServiceID: serviceID, - ServiceVersion: latest.Number, - }) - if err != nil { - log.Fatal(err) - } - - // Now you can make any changes to the new version. In this example, we will add - // a new domain. - domain, err := client.CreateDomain(&fastly.CreateDomainInput{ - ServiceID: serviceID, - ServiceVersion: version.Number, - Name: String("example.com"), - }) - if err != nil { - log.Fatal(err) - } - - // Output: "example.com" - fmt.Println("domain.Name:", domain.Name) - - // And we will also add a new backend. - backend, err := client.CreateBackend(&fastly.CreateBackendInput{ - ServiceID: serviceID, - ServiceVersion: version.Number, - Name: String("example-backend"), - Address: String("127.0.0.1"), - Port: Int(80), - }) - if err != nil { - log.Fatal(err) - } - - // Output: "example-backend" - fmt.Println("backend.Name:", backend.Name) - - // Now we can validate that our version is valid. - valid, _, err := client.ValidateVersion(&fastly.ValidateVersionInput{ - ServiceID: serviceID, - ServiceVersion: version.Number, - }) - if err != nil { - log.Fatal(err) - } - if !valid { - log.Fatal("not valid version") - } - - // Finally, activate this new version. - activeVersion, err := client.ActivateVersion(&fastly.ActivateVersionInput{ - ServiceID: serviceID, - ServiceVersion: version.Number, - }) - if err != nil { - log.Fatal(err) - } - - // Output: true - fmt.Println("activeVersion.Locked:", activeVersion.Locked) -} -``` - -More information can be found in the -[Fastly Godoc][latest]. - -## Developing - -1. Clone the project to your preferred directory, using your preferred method. -2. Download the module and accompanying developer tooling. - - ```bash - $ go mod download - ``` - -3. Make changes. -4. Verify those changes. - - ```bash - $ make all - ``` +## Reference -## Testing - -Go Fastly uses [go-vcr](https://github.com/dnaeon/go-vcr) to "record" and "replay" API request fixtures to improve the speed and portability of integration tests. The test suite uses a single test service ID for all test fixtures. - -Contributors without access to the test service can still update the fixtures but with some additional steps required. Below is an example workflow for updating a set of fixture files (where `...` should be replaced with an appropriate value): - -```sh -# Remove all yaml fixture files from the specified directory. -# -rm -r fastly/fixtures/.../* - -# Run a subsection of the tests. -# This will cause the deleted fixtures to be recreated. -# -# FASTLY_TEST_SERVICE_ID: should correspond to a real service you control. -# FASTLY_API_KEY: should be a real token associated with the Service you control. -# TESTARGS: allows you to use the -run flag of the 'go test' command. -# -make test FASTLY_TEST_SERVICE_ID="..." FASTLY_API_KEY="..." TESTARGS="-run=..." -``` - -> **NOTE**: to run the tests with go-vcr disabled, set `VCR_DISABLE=1` (`make test-full` does this). - -When adding or updating client code and integration tests, contributors should record a new set of fixtures. Before submitting a pull request with new or updated fixtures, we ask that contributors update them to use the default service ID by running `make fix-fixtures` with `FASTLY_TEST_SERVICE_ID` set to the same value used to run your tests. - -```sh -make fix-fixtures FASTLY_TEST_SERVICE_ID="..." -``` - -### Important Test Tips! - -There are two important things external contributors need to do when running the tests: - -1. Use a 'temporary' token for running the tests (only if regenerating the token fixtures). -2. Redact sensitive information in your fixtures. - -You only need to use a temporary token when regenerating the 'token' fixtures. This is because there is a test to validate the _revoking_ of a token using the [`/tokens/self`](https://developer.fastly.com/reference/api/auth/#revoke-token-current) API endpoint, for which running this test (if there are no existing fixtures) will cause the token you provided at your command-line shell to be revoked/expired. So please don't use a token that's also used by a real/running application! Otherwise you'll discover those application may stop working as you've inadvertently caused your token to be revoked. - -In general, any time you regenerate fixtures you should be sure to redact any sensitive information served back from the API, but specifically there is a test which _creates_ tokens that needs special attention: when regenerating the token fixtures this will require you to enter your actual account credentials (i.e. username/password) into the `token_test.go` file. You'll want to ensure that once the fixtures are created that you redact those values from both the generated fixture as well as the go test file itself. For example... - -```go -input := &CreateTokenInput{ - Name: "my-test-token", - Scope: "global", - Username: "XXXXXXXXXXXXXXXXXXXXXX", - Password: "XXXXXXXXXXXXXXXXXXXXXX", -} -``` - -## Contributing - -Refer to [CONTRIBUTING.md](./CONTRIBUTING.md) - -## License - -``` -Copyright 2015 Seth Vargo - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` +- [CONTRIBUTING.md](./CONTRIBUTING.md) +- [DEVELOPMENT.md](./DEVELOPMENT.md) +- [EXAMPLES.md](./EXAMPLES.md) +- [TESTING.md](./TESTING.md) diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 000000000..f50ca5385 --- /dev/null +++ b/TESTING.md @@ -0,0 +1,48 @@ +# Testing + +Go Fastly uses [go-vcr](https://github.com/dnaeon/go-vcr) to "record" and "replay" API request fixtures to improve the speed and portability of integration tests. The test suite uses a single test service ID for all test fixtures. + +Contributors without access to the test service can still update the fixtures but with some additional steps required. Below is an example workflow for updating a set of fixture files (where `...` should be replaced with an appropriate value): + +```sh +# Remove all yaml fixture files from the specified directory. +# +rm -r fastly/fixtures/.../* + +# Run a subsection of the tests. +# This will cause the deleted fixtures to be recreated. +# +# FASTLY_TEST_SERVICE_ID: should correspond to a real service you control. +# FASTLY_API_KEY: should be a real token associated with the Service you control. +# TESTARGS: allows you to use the -run flag of the 'go test' command. +# +make test FASTLY_TEST_SERVICE_ID="..." FASTLY_API_KEY="..." TESTARGS="-run=..." +``` + +> **NOTE**: to run the tests with go-vcr disabled, set `VCR_DISABLE=1` (`make test-full` does this). + +When adding or updating client code and integration tests, contributors should record a new set of fixtures. Before submitting a pull request with new or updated fixtures, we ask that contributors update them to use the default service ID by running `make fix-fixtures` with `FASTLY_TEST_SERVICE_ID` set to the same value used to run your tests. + +```sh +make fix-fixtures FASTLY_TEST_SERVICE_ID="..." +``` + +### Important Test Tips! + +There are two important things external contributors need to do when running the tests: + +1. Use a 'temporary' token for running the tests (only if regenerating the token fixtures). +2. Redact sensitive information in your fixtures. + +You only need to use a temporary token when regenerating the 'token' fixtures. This is because there is a test to validate the _revoking_ of a token using the [`/tokens/self`](https://developer.fastly.com/reference/api/auth/#revoke-token-current) API endpoint, for which running this test (if there are no existing fixtures) will cause the token you provided at your command-line shell to be revoked/expired. So please don't use a token that's also used by a real/running application! Otherwise you'll discover those application may stop working as you've inadvertently caused your token to be revoked. + +In general, any time you regenerate fixtures you should be sure to redact any sensitive information served back from the API, but specifically there is a test which _creates_ tokens that needs special attention: when regenerating the token fixtures this will require you to enter your actual account credentials (i.e. username/password) into the `token_test.go` file. You'll want to ensure that once the fixtures are created that you redact those values from both the generated fixture as well as the go test file itself. For example... + +```go +input := &CreateTokenInput{ + Name: "my-test-token", + Scope: "global", + Username: "XXXXXXXXXXXXXXXXXXXXXX", + Password: "XXXXXXXXXXXXXXXXXXXXXX", +} +```