One place for hosting & domains

      How To Use Struct Tags in Go


      Introduction

      Structures, or structs, are used to collect multiple pieces of information together in one unit. These collections of information are used to describe higher-level concepts, such as an Address composed of a Street, City, State, and PostalCode. When you read this information from systems such as databases, or APIs, you can use struct tags to control how this information is assigned to the fields of a struct. Struct tags are small pieces of metadata attached to fields of a struct that provide instructions to other Go code that works with the struct.

      What Does a Struct Tag Look Like?

      Go struct tags are annotations that appear after the type in a Go struct declaration. Each tag is composed of short strings associated with some corresponding value.

      A struct tag looks like this, with the tag offset with backtick ` characters:

      type User struct {
          Name string `example:"name"`
      }
      

      Other Go code is then capable of examining these structs and extracting the values assigned to specific keys it requests. Struct tags have no effect on the operation of your code without some other code that examines them.

      Try this example to see what struct tags look like, and that without code from another package, they will have no effect.

      package main
      
      import "fmt"
      
      type User struct {
          Name string `example:"name"`
      }
      
      func (u *User) String() string {
          return fmt.Sprintf("Hi! My name is %s", u.Name)
      }
      
      func main() {
          u := &User{
              Name: "Sammy",
          }
      
          fmt.Println(u)
      }
      

      This will output:

      Output

      Hi! My name is Sammy

      This example defines a User type with a Name field. The Name field has been given a struct tag of example:"name". We would refer to this specific tag in conversation as the “example struct tag” because it uses the word “example” as its key. The example struct tag has the value "name" for the Name field. On the User type, we also define the String() method required by the fmt.Stringer interface. This will be called automatically when we pass the type to fmt.Println and gives us a chance to produce a nicely formatted version of our struct.

      Within the body of main, we create a new instance of our User type and pass it to fmt.Println. Even though the struct had a struct tag present, we see that it has no effect on the operation of this Go code. It will behave exactly the same if the struct tag were not present.

      To use struct tags to accomplish something, other Go code must be written to examine structs at runtime. The standard library has packages that use struct tags as part of their operation. The most popular of these is the encoding/json package.

      Encoding JSON

      JavaScript Object Notation (JSON) is a textual format for encoding collections of data organized under different string keys. It’s commonly used to communicate data between different programs as the format is simple enough that libraries exist to decode it in many different languages. The following is an example of JSON:

      {
        "language": "Go",
        "mascot": "Gopher"
      }
      

      This JSON object contains two keys, language and mascot. Following these keys are the associated values. Here the language key has a value of Go and mascot is assigned the value Gopher.

      The JSON encoder in the standard library makes use of struct tags as annotations indicating to the encoder how you would like to name your fields in the JSON output. These JSON encoding and decoding mechanisms can be found in the encoding/json package.

      Try this example to see how JSON is encoded without struct tags:

      package main
      
      import (
          "encoding/json"
          "fmt"
          "log"
          "os"
          "time"
      )
      
      type User struct {
          Name          string
          Password      string
          PreferredFish []string
          CreatedAt     time.Time
      }
      
      func main() {
          u := &User{
              Name:      "Sammy the Shark",
              Password:  "fisharegreat",
              CreatedAt: time.Now(),
          }
      
          out, err := json.MarshalIndent(u, "", "  ")
          if err != nil {
              log.Println(err)
              os.Exit(1)
          }
      
          fmt.Println(string(out))
      }
      

      This will print the following output:

      Output

      { "Name": "Sammy the Shark", "Password": "fisharegreat", "CreatedAt": "2019-09-23T15:50:01.203059-04:00" }

      We defined a struct describing a user with fields including their name, password, and the time the user was created. Within the main function, we create an instance of this user by supplying values for all fields except PreferredFish (Sammy likes all fish). We then passed the instance of User to the json.MarshalIndent function. This is used so we can more easily see the JSON output without using an external formatting tool. This call could be replaced with json.Marshal(u) to receive JSON without any additional whitespace. The two additional arguments to json.MarshalIndent control the prefix to the output (which we have omitted with the empty string), and the characters to use for indenting, which here are two space characters. Any errors produced from json.MarshalIndent are logged and the program terminates using os.Exit(1). Finally, we cast the []byte returned from json.MarshalIndent to a string and hand the resulting string to fmt.Println for printing on the terminal.

      The fields of the struct appear exactly as we named them. This is not the typical JSON style that you may expect, which uses camel casing for names of fields. You’ll change the names of the field to follow camel case style in this next example. As you’ll see when you run this example, this won’t work because the desired field names conflict with Go’s rules about exported field names.

      package main
      
      import (
          "encoding/json"
          "fmt"
          "log"
          "os"
          "time"
      )
      
      type User struct {
          name          string
          password      string
          preferredFish []string
          createdAt     time.Time
      }
      
      func main() {
          u := &User{
              name:      "Sammy the Shark",
              password:  "fisharegreat",
              createdAt: time.Now(),
          }
      
          out, err := json.MarshalIndent(u, "", "  ")
          if err != nil {
              log.Println(err)
              os.Exit(1)
          }
      
          fmt.Println(string(out))
      }
      

      This will present the following output:

      Output

      {}

      In this version, we’ve altered the names of the fields to be camel cased. Now Name is name, Password is password, and finally CreatedAt is createdAt. Within the body of main we’ve changed the instantiation of our struct to use these new names. We then pass the struct to the json.MarshalIndent function as before. The output, this time is an empty JSON object, {}.

      Camel casing fields properly requires that the first character be lower-cased. While JSON doesn’t care how you name your fields, Go does, as it indicates the visibility of the field outside of the package. Since the encoding/json package is a separate package from the main package we’re using, we must uppercase the first character in order to make it visible to encoding/json. It would seem that we’re at an impasse, and we need some way to convey to the JSON encoder what we would like this field to be named.

      Using Struct Tags to Control Encoding

      You can modify the previous example to have exported fields that are properly encoded with camel-cased field names by annotating each field with a struct tag. The struct tag that encoding/json recognizes has a key of json and a value that controls the output. By placing the camel-cased version of the field names as the value to the json key, the encoder will use that name instead. This example fixes the previous two attempts:

      package main
      
      import (
          "encoding/json"
          "fmt"
          "log"
          "os"
          "time"
      )
      
      type User struct {
          Name          string    `json:"name"`
          Password      string    `json:"password"`
          PreferredFish []string  `json:"preferredFish"`
          CreatedAt     time.Time `json:"createdAt"`
      }
      
      func main() {
          u := &User{
              Name:      "Sammy the Shark",
              Password:  "fisharegreat",
              CreatedAt: time.Now(),
          }
      
          out, err := json.MarshalIndent(u, "", "  ")
          if err != nil {
              log.Println(err)
              os.Exit(1)
          }
      
          fmt.Println(string(out))
      }
      

      This will output:

      Output

      { "name": "Sammy the Shark", "password": "fisharegreat", "preferredFish": null, "createdAt": "2019-09-23T18:16:17.57739-04:00" }

      We’ve changed the field names back to be visible to other packages by capitalizing the first letters of their names. However, this time we’ve added struct tags in the form of json:"name", where "name" was the name we wanted json.MarshalIndent to use when printing our struct as JSON.

      We’ve now successfully formatted our JSON correctly. Notice, however, that the fields for some values were printed even though we did not set those values. The JSON encoder can eliminate these fields as well, if you like.

      Removing Empty JSON Fields

      Most commonly, we want to suppress outputting fields that are unset in JSON. Since all types in Go have a “zero value,” some default value that they are set to, the encoding/json package needs additional information to be able to tell that some field should be considered unset when it assumes this zero value. Within the value part of any json struct tag, you can suffix the desired name of your field with ,omitempty to tell the JSON encoder to suppress the output of this field when the field is set to the zero value. The following example fixes the previous examples to no longer output empty fields:

      package main
      
      import (
          "encoding/json"
          "fmt"
          "log"
          "os"
          "time"
      )
      
      type User struct {
          Name          string    `json:"name"`
          Password      string    `json:"password"`
          PreferredFish []string  `json:"preferredFish,omitempty"`
          CreatedAt     time.Time `json:"createdAt"`
      }
      
      func main() {
          u := &User{
              Name:      "Sammy the Shark",
              Password:  "fisharegreat",
              CreatedAt: time.Now(),
          }
      
          out, err := json.MarshalIndent(u, "", "  ")
          if err != nil {
              log.Println(err)
              os.Exit(1)
          }
      
          fmt.Println(string(out))
      }
      

      This example will output:

      Output

      { "name": "Sammy the Shark", "password": "fisharegreat", "createdAt": "2019-09-23T18:21:53.863846-04:00" }

      We’ve modified the previous examples so that the PreferredFish field now has the struct tag json:"preferredFish,omitempty". The presence of the ,omitempty augmentation causes the JSON encoder to skip that field, since we decided to leave it unset. This had the value null in our previous examples’ outputs.

      This output is looking much better, but we’re still printing out the user’s password. The encoding/json package provides another way for us to ignore private fields entirely.

      Ignoring Private Fields

      Some fields must be exported from structs so that other packages can correctly interact with the type. However, the nature of these fields may be sensitive, so in these circumstances, we would like the JSON encoder to ignore the field entirely—even when it is set. This is done using the special value - as the value argument to a json: struct tag.

      This example fixes the issue of exposing the user’s password.

      package main
      
      import (
          "encoding/json"
          "fmt"
          "log"
          "os"
          "time"
      )
      
      type User struct {
          Name      string    `json:"name"`
          Password  string    `json:"-"`
          CreatedAt time.Time `json:"createdAt"`
      }
      
      func main() {
          u := &User{
              Name:      "Sammy the Shark",
              Password:  "fisharegreat",
              CreatedAt: time.Now(),
          }
      
          out, err := json.MarshalIndent(u, "", "  ")
          if err != nil {
              log.Println(err)
              os.Exit(1)
          }
      
          fmt.Println(string(out))
      }
      

      When you run this example, you’ll see this output:

      Output

      { "name": "Sammy the Shark", "createdAt": "2019-09-23T16:08:21.124481-04:00" }

      The only thing we’ve changed in this example from previous ones is that the password field now uses the special "-" value for its json: struct tag. We see that in the output from this example that the password field is no longer present.

      These features of the encoding/json package, ,omitempty and "-", are not standards. What a package decides to do with values of a struct tag depends on its implementation. Because the encoding/json package is part of the standard library, other packages have also implemented these features in the same way as a matter of convention. However, it’s important to read the documentation for any third-party package that uses struct tags to learn what is supported and what is not.

      Conclusion

      Struct tags offer a powerful means to augment the functionality of code that works with your structs. Many standard library and third-party packages offer ways to customize their operation through the use of struct tags. Using them effectively in your code provides both this customization behavior and succinctly documents how these fields are used to future developers.



      Source link

      Customizing Go Binaries with Build Tags


      Introduction

      In Go, a build tag, or a build constraint, is an identifier added to a piece of code that determines when the file should be included in a package during the build process. This allows you to build different versions of your Go application from the same source code and to toggle between them in a fast and organized manner. Many developers use build tags to improve the workflow of building cross-platform compatible applications, such as programs that require code changes to account for variances between different operating systems. Build tags are also used for integration testing, allowing you to quickly switch between the integrated code and the code with a mock service or stub, and for differing levels of feature sets within an application.

      Let’s take the problem of differing customer feature sets as an example. When writing some applications, you may want to control which features to include in the binary, such as an application that offers Free, Pro, and Enterprise levels. As the customer increases their subscription level in these applications, more features become unlocked and available. To solve this problem, you could maintain separate projects and try to keep them in sync with each other through the use of import statements. While this approach would work, over time it would become tedious and error prone. An alternative approach would be to use build tags.

      In this article, you will use build tags in Go to generate different executable binaries that offer Free, Pro, and Enterprise feature sets of a sample application. Each will have a different set of features available, with the Free version being the default.

      Prerequisites

      To follow the example in this article, you will need:

      Building the Free Version

      Let’s start by building the Free version of the application, as it will be the default when running go build without any build tags. Later on, we will use build tags to selectively add other parts to our program.

      In the src directory, create a folder with the name of your application. This tutorial will use app:

      Move into this folder:

      Next, make a new text file in your text editor of choice named main.go:

      Now, we’ll define the Free version of the application. Add in the following contents to main.go:

      main.go

      package main
      
      import "fmt"
      
      var features = []string{
        "Free Feature #1",
        "Free Feature #2",
      }
      
      func main() {
        for _, f := range features {
          fmt.Println(">", f)
        }
      }
      

      In this file, we created a program that declares a slice named features, which holds two strings that represent the features of our Free application. The main() function in the application uses a for loop to range through the features slice and print all of the features available to the screen.

      Save and exit the file. Now that this file is saved, we will no longer have to edit it for the rest of the article. Instead we will use build tags to change the features of the binaries we will build from it.

      Build and run the program:

      You’ll receive the following output:

      Output

      > Free Feature #1 > Free Feature #2

      The program has printed out our two free features, completing the Free version of our app.

      So far, you created an application that has a very basic feature set. Next, you will build a way to add more features into the application at build time.

      Adding the Pro Features With go build

      We have so far avoided making changes to main.go, simulating a common production environment in which code needs to be added without changing and possibly breaking the main code. Since we can’t edit the main.go file, we’ll need to use another mechanism for injecting more features into the features slice using build tags.

      Let’s create a new file called pro.go that will use an init() function to append more features to the features slice:

      Once the editor has opened the file, add the following lines:

      pro.go

      package main
      
      func init() {
        features = append(features,
          "Pro Feature #1",
          "Pro Feature #2",
        )
      }
      

      In this code, we used init() to run code before the main() function of our application, followed by append() to add the Pro features to the features slice. Save and exit the file.

      Compile and run the application using go build:

      Since there are now two files in our current directory (pro.go and main.go), go build will create a binary from both of them. Execute this binary:

      This will give you the following feature set:

      Output

      > Free Feature #1 > Free Feature #2 > Pro Feature #1 > Pro Feature #2

      The application now includes both the Pro and the Free features. However, this is not desirable: since there is no distinction between versions, the Free version now includes the features that are supposed to be only available in the Pro version. To fix this, you could include more code to manage the different tiers of the application, or you could use build tags to tell the Go tool chain which .go files to build and which to ignore. Let’s add build tags in the next step.

      You can now use build tags to distinguish the Pro version of your application from the Free version.

      Let’s start by examining what a build tag looks like:

      // +build tag_name
      

      By putting this line of code as the first line of your package and replacing tag_name with the name of your build tag, you will tag this package as code that can be selectively included in the final binary. Let’s see this in action by adding a build tag to the pro.go file to tell the go build command to ignore it unless the tag is specified. Open up the file in your text editor:

      Then add the following highlighted line:

      pro.go

      // +build pro
      
      package main
      
      func init() {
        features = append(features,
          "Pro Feature #1",
          "Pro Feature #2",
        )
      }
      

      At the top of the pro.go file, we added // +build pro followed by a blank newline. This trailing newline is required, otherwise Go interprets this as a comment. Build tag declarations must also be at the very top of a .go file. Nothing, not even comments, can be above build tags.

      The +build declaration tells the go build command that this isn’t a comment, but instead is a build tag. The second part is the pro tag. By adding this tag at the top of the pro.go file, the go build command will now only include the pro.go file with the pro tag is present.

      Compile and run the application again:

      You’ll receive the following output:

      Output

      > Free Feature #1 > Free Feature #2

      Since the pro.go file requires a pro tag to be present, the file is ignored and the application compiles without it.

      When running the go build command, we can use the -tags flag to conditionally include code in the compiled source by adding the tag itself as an argument. Let’s do this for the pro tag:

      This will output the following:

      Output

      > Free Feature #1 > Free Feature #2 > Pro Feature #1 > Pro Feature #2

      Now we only get the extra features when we build the application using the pro build tag.

      This is fine if there are only two versions, but things get complicated when you add in more tags. To add in the Enterprise version of our app in the next step, we will use multiple build tags joined together with Boolean logic.

      Build Tag Boolean Logic

      When there are multiple build tags in a Go package, the tags interact with each other using Boolean logic. To demonstrate this, we will add the Enterprise level of our application using both the pro tag and the enterprise tag.

      In order to build an Enterprise binary, we will need to include both the default features, the Pro level features, and a new set of features for Enterprise. First, open an editor and create a new file, enterprise.go, that will add the new Enterprise features:

      The contents of enterprise.go will look almost identical to pro.go but will contain new features. Add the following lines to the file:

      enterprise.go

      package main
      
      func init() {
        features = append(features,
          "Enterprise Feature #1",
          "Enterprise Feature #2",
        )
      }
      

      Save and exit the file.

      Currently the enterprise.go file does not have any build tags, and as you learned when you added pro.go, this means that these features will be added to the Free version when executing go.build. For pro.go, you added // +build pro and a newline to the top of the file to tell go build that it should only be included when -tags pro is used. In this situation, you only needed one build tag to accomplish the goal. When adding the new Enterprise features, however, you first must also have the Pro features.

      Let’s add support for the pro build tag to enterprise.go first. Open the file with your text editor:

      Next add the build tag before the package main declaration and make sure to include a newline after the build tag:

      enterprise.go

      // +build pro
      
      package main
      
      func init() {
        features = append(features,
          "Enterprise Feature #1",
          "Enterprise Feature #2",
        )
      }
      

      Save and exit the file.

      Compile and run the application without any tags:

      You’ll receive the following output:

      Output

      > Free Feature #1 > Free Feature #2

      The Enterprise features no longer show up in the Free version. Now let’s add the pro build tag and build and run the application again:

      You’ll receive the following output:

      Output

      > Free Feature #1 > Free Feature #2 > Enterprise Feature #1 > Enterprise Feature #2 > Pro Feature #1 > Pro Feature #2

      This is still not exactly what we need: The Enterprise features now show up when we try to build the Pro version. To solve this, we need to use another build tag. Unlike the pro tag, however, we need to now make sure both the pro and enterprise features are available.

      The Go build system accounts for this situation by allowing the use of some basic Boolean logic in the build tags system.

      Let’s open enterprise.go again:

      Add another build tag, enterprise, on the same line as the pro tag:

      enterprise.go

      // +build pro enterprise
      
      package main
      
      func init() {
        features = append(features,
          "Enterprise Feature #1",
          "Enterprise Feature #2",
        )
      }
      

      Save and close the file.

      Now let’s compile and run the application with the new enterprise build tag.

      • go build -tags enterprise
      • ./app

      This will give the following:

      Output

      > Free Feature #1 > Free Feature #2 > Enterprise Feature #1 > Enterprise Feature #2

      Now we have lost the Pro features. This is because when we put multiple build tags on the same line in a .go file, go build interprets them as using OR logic. With the addition of the line // +build pro enterprise, the enterprise.go file will be built if either the pro build tag or the enterprise build tag is present. We need to set up the build tags correctly to require both and use AND logic instead.

      Instead of putting both tags on the same line, if we put them on separate lines, then go build will interpret those tags using AND logic.

      Open enterprise.go once again and let’s separate the build tags onto multiple lines.

      enterprise.go

      // +build pro
      // +build enterprise
      
      package main
      
      func init() {
        features = append(features,
          "Enterprise Feature #1",
          "Enterprise Feature #2",
        )
      }
      

      Now compile and run the application with the new enterprise build tag.

      • go build -tags enterprise
      • ./app

      You’ll receive the following output:

      Output

      > Free Feature #1 > Free Feature #2

      Still not quite there: Because an AND statement requires both elements to be considered true, we need to use both pro and enterprise build tags.

      Let’s try again:

      • go build -tags "enterprise pro"
      • ./app

      You’ll receive the following output:

      Output

      > Free Feature #1 > Free Feature #2 > Enterprise Feature #1 > Enterprise Feature #2 > Pro Feature #1 > Pro Feature #2

      Now our application can be built from the same source tree in multiple ways unlocking the features of the application accordingly.

      In this example, we used a new // +build tag to signify AND logic, but there are alternative ways to represent Boolean logic with build tags. The following table holds some examples of other syntactic formatting for build tags, along with their Boolean equivalent:

      Build Tag Syntax Build Tag Sample Boolean Statement
      Space-separated elements // +build pro enterprise pro OR enterprise
      Comma-separated elements // +build pro,enterprise pro AND enterprise
      Exclamation point elements // +build !pro NOT pro

      Conclusion

      In this tutorial, you used build tags to allow you to control which of your code got compiled into the binary. First, you declared build tags and used them with go build, then you combined multiple tags with Boolean logic. You then built a program that represented the different feature sets of a Free, Pro, and Enterprise version, showing the powerful level of control that build tags can give you over your project.

      If you’d like to learn more about build tags, take a look at the Golang documentation on the subject, or continue to explore our How To Code in Go series.



      Source link

      Tags and Groups


      Updated by Linode

      Contributed by

      Linode

      Linode’s Cloud Manager and API allow you to create tags to help organize and group your Linode resources. Tags can be applied to Linodes, Block Storage Volumes, NodeBalancers, and Domains.

      This guide will show you how to perform the following actions with the Cloud Manager:

      • Create and apply tags to your Linode resources
      • Search and group your Linode resources by tag
      • Import tags from the Classic Manager

      Tagging a Linode

      Tag a Linode at Creation

      To tag a Linode at the time of its creation:

      1. In the Create New Linode form, click the dropdown menu labeled Add Tags located below the Linode Label field.

      2. Select one or more tags from the menu. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears:

        Add Tags field in the Linode creation form

      3. Your tag will be applied when you finish creating the Linode.

      Tag an Existing Linode

      To tag an existing Linode:

      1. Navigate to the Linode’s detail page.

      2. Click on the Summary tab.

      3. Locate the Tags pane and click on the Add New Tag option.

      4. Select one or more tags from the dropdown menu that appears. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears:

        Location of Tags box for a Linode

      Remove a Tag from a Linode

      To remove a tag from a Linode:

      1. Navigate to the Linode’s detail page.

      2. Click on the Summary tab.

      3. Locate the Tags box. A list of your tags for the Linode will be displayed.

      4. Click on the X icon attached to the tag you would like to remove from your Linode.

      Tagging a Volume

      Tag a Volume at Creation

      To tag a Volume at the time of its creation:

      1. In the Create a Volume form, select the dropdown menu labeled Tags.

      2. Select one or more tags from the menu. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears.

        Tags field in the Volume creation form

      3. Once you are done configuring the Volume, click Submit.

      Tag an Existing Volume

      To tag an existing Volume:

      1. Navigate to the Volumes page of the Cloud Manager.

      2. Select the more options ellipsis (…) corresponding to the Volume you would like to tag.

      3. Select Edit Volume from the menu that appears.

      4. The Edit volume form will appear. Click on the dropdown menu labeled Tags.

      5. Select one or more tags from the form. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears.

      6. When you are done, click Submit:

        Tags field in the Edit volume form

      Remove a Tag from a Volume

      To remove a tag from a Volume:

      1. Navigate to the Volumes page of the Cloud Manager.

      2. Select the more options ellipsis (…) corresponding to the Volume whose tags you would like to edit.

      3. Select Edit Volume from the menu that appears.

      4. The Edit volume form will appear. A list of your tags for the Volume will be displayed in the Tags field.

      5. Click on the x icon attached to the tag you would like to remove from your Volume.

      Tagging a NodeBalancer

      Tag a NodeBalancer at Creation

      To tag a NodeBalancer at the time of its creation:

      1. In the Create a NodeBalancer form, click the dropdown menu labeled Add Tags under the NodeBalancer Label field.

      2. Select one or more tags from the menu. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears.

        Add Tags field in the NodeBalancer creation form

      3. Once you are done configuring the NodeBalancer, click Create.

      Tag an Existing NodeBalancer

      To tag an existing NodeBalancer:

      1. Navigate to the NodeBalancer’s detail page.

      2. Click on the Summary tab.

      3. Locate the Tags pane and click on the Add New Tag option.

      4. Select one or more tags from the dropdown menu that appears. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears:

        Location of Tags box for a NodeBalancer

      Remove a Tag from a NodeBalancer

      To remove a tag from a NodeBalancer:

      1. Navigate to the NodeBalancer’s detail page.

      2. Click on the Summary tab.

      3. Locate the Tags pane. A list of your tags for the NodeBalancer will be displayed.

      4. Click on the x icon attached to the tag you would like to remove from your NodeBalancer.

      Tagging a Domain

      Tag a Domain at Creation

      To tag a domain at the time of its creation:

      1. In the Add a new Domain form, click the dropdown menu labeled Add Tags.

      2. Select one or more tags from the menu. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears:

        Tags field in the domain creation form

      Tag an Existing Domain

      To tag an existing domain:

      1. Navigate to the domain’s detail page.

      2. Click on the DNS Records tab.

      3. Locate the pane labeled Tags and click on the Add New Tag option.

      4. Select one or more tags from the dropdown menu that appears. To create a new tag, type in the desired tag name and click the Create “new-tag” option that appears:

        Location of Tags box for a domain

      Remove a Tag from a Domain

      To remove a tag from a domain:

      1. Navigate to the domain’s detail page.

      2. Click on the DNS Records tab.

      3. Locate the Tags pane. A list of your tags for the Domain will be displayed.

      4. Click on the x icon attached to the tag you would like to remove from your domain.

      Grouping by Tag

      You can group the following resources by tag: Linodes, Volumes, NodeBalancers, and Domains.

      1. To group by tag, navigate to the resource’s page and toggle the Group by Tag switch at the top of the page:

        Cloud Manager Group by Tag switch

      2. You will now be able to view your resources grouped by tag:

        Group your Linodes by tag

      Searching by Tag

      You can search your Linode resources by a tag’s name:

      1. Type the tag name into the search bar at the top of the Cloud Manager and the results will be populated in a dropdown list that appears:

        Cloud Manager tag search

      2. To see a more organized view of your tagged resources, click on the blue View search results page banner inside the dropdown list, or hit the Enter key on your keyboard. You will be taken to the search results page:

        Cloud Manager search results page

      3. A second way to search by tag is to click on a tag wherever it appears in the Cloud Manager. For example, if you previously applied a tag named tag-example to one of your Linodes, clicking on that tag where it is displayed in the Linode’s detail page will take you to the search results page for tag-example.

      If you have used the Display Groups feature in the Classic Manager, you can import your Display Groups to the Cloud Manager as tags:

      1. Navigate to the Account page in the sidebar links menu, then click on the Settings tab.

      2. Expand the panel labeled Import Display Groups as Tags and then click Import Display Groups:

        Cloud Manager import display groups as tags

      3. A form will appear that lists your Display Groups and asks you to confirm the import action. To proceed, click the Import Display Groups Now button in this form.

        Note

        Importing your Display Groups is a one-time operation. If you don’t have any Display Groups configured in the Classic Manager this feature will not appear in the Cloud Manager.

      Find answers, ask questions, and help others.

      This guide is published under a CC BY-ND 4.0 license.



      Source link