Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding in customized user-agent #69

Merged
merged 2 commits into from
Sep 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pkg/buildinfo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ limitations under the License.
// worrying about introducing circular dependencies.
package buildinfo

import "fmt"

var (
// Version is the current version of Ark, set by the go linker's -X flag at build time.
Version string
Expand All @@ -34,3 +36,11 @@ var (
// time.
GitTreeState string
)

// FormattedGitSHA renders the Git SHA with an indicator of the tree state.
func FormattedGitSHA() string {
if GitTreeState != "clean" {
return fmt.Sprintf("%s-%s", GitSHA, GitTreeState)
}
return GitSHA
}
38 changes: 38 additions & 0 deletions pkg/buildinfo/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package buildinfo

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestFormattedGitSHA(t *testing.T) {
tests := []struct {
name string
sha string
state string
expected string
}{
{
"Clean git state has no suffix",
"abc123",
"clean",
"abc123",
},
{
"Dirty git status includes suffix",
"abc123",
"dirty",
"abc123-dirty",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
GitSHA = test.sha
GitTreeState = test.state
assert.Equal(t, FormattedGitSHA(), test.expected)
})
}

}
22 changes: 21 additions & 1 deletion pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,38 @@ limitations under the License.
package client

import (
"fmt"
"runtime"

"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"

"github.com/heptio/ark/pkg/buildinfo"
)

// Config returns a *rest.Config, using either the kubeconfig (if specified) or an in-cluster
// configuration.
func Config(kubeconfig string) (*rest.Config, error) {
func Config(kubeconfig, baseName string) (*rest.Config, error) {
loader := clientcmd.NewDefaultClientConfigLoadingRules()
loader.ExplicitPath = kubeconfig
clientConfig, err := clientcmd.BuildConfigFromKubeconfigGetter("", loader.Load)
if err != nil {
return nil, err
}

clientConfig.UserAgent = buildUserAgent(
baseName,
buildinfo.Version,
buildinfo.FormattedGitSHA(),
runtime.GOOS,
runtime.GOARCH,
)

return clientConfig, nil
}

// buildUserAgent builds a User-Agent string from given args.
func buildUserAgent(command, version, formattedSha, os, arch string) string {
return fmt.Sprintf(
"%s/%s (%s/%s) %s", command, version, os, arch, formattedSha)
}
36 changes: 36 additions & 0 deletions pkg/client/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package client

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestBuildUserAgent(t *testing.T) {
tests := []struct {
name string
command string
os string
arch string
gitSha string
version string
expected string
}{
{
name: "Test general interpolation in correct order",
command: "ark",
os: "darwin",
arch: "amd64",
gitSha: "abc123",
version: "v0.1.1",
expected: "ark/v0.1.1 (darwin/amd64) abc123",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := buildUserAgent(test.command, test.version, test.gitSha, test.os, test.arch)
assert.Equal(t, resp, test.expected)
})
}
}
8 changes: 5 additions & 3 deletions pkg/client/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ type Factory interface {
type factory struct {
flags *pflag.FlagSet
kubeconfig string
baseName string
}

// NewFactory returns a Factory.
func NewFactory() Factory {
func NewFactory(baseName string) Factory {
f := &factory{
flags: pflag.NewFlagSet("", pflag.ContinueOnError),
flags: pflag.NewFlagSet("", pflag.ContinueOnError),
baseName: baseName,
}
f.flags.StringVar(&f.kubeconfig, "kubeconfig", "", "Path to the kubeconfig file to use to talk to the Kubernetes apiserver. If unset, try the environment variable KUBECONFIG, as well as in-cluster configuration")

Expand All @@ -51,7 +53,7 @@ func (f *factory) BindFlags(flags *pflag.FlagSet) {
}

func (f *factory) Client() (clientset.Interface, error) {
clientConfig, err := Config(f.kubeconfig)
clientConfig, err := Config(f.kubeconfig, f.baseName)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/ark/ark.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ and operationally robust way to back up your application state and
associated data.`,
}

f := client.NewFactory()
f := client.NewFactory(name)
f.BindFlags(c.PersistentFlags())

c.AddCommand(
Expand Down
6 changes: 3 additions & 3 deletions pkg/cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func NewCommand() *cobra.Command {
Short: "Run the ark server",
Long: "Run the ark server",
Run: func(c *cobra.Command, args []string) {
s, err := newServer(kubeconfig)
s, err := newServer(kubeconfig, fmt.Sprintf("%s-%s", c.Parent().Name(), c.Name()))
cmd.CheckError(err)

cmd.CheckError(s.run())
Expand All @@ -89,8 +89,8 @@ type server struct {
cancelFunc context.CancelFunc
}

func newServer(kubeconfig string) (*server, error) {
clientConfig, err := client.Config(kubeconfig)
func newServer(kubeconfig, baseName string) (*server, error) {
clientConfig, err := client.Config(kubeconfig, baseName)
if err != nil {
return nil, err
}
Expand Down