package client import ( "errors" "fmt" command "github.com/docker/cli/cli/command" dConfig "github.com/docker/cli/cli/config" context "github.com/docker/cli/cli/context" "github.com/docker/cli/cli/context/docker" contextStore "github.com/docker/cli/cli/context/store" "github.com/moby/term" ) type Context = contextStore.Metadata func CreateContext(contextName string, user string, port string) error { host := contextName if user != "" { host = fmt.Sprintf("%s@%s", user, host) } if port != "" { host = fmt.Sprintf("%s:%s", host, port) } host = fmt.Sprintf("ssh://%s", host) if err := createContext(contextName, host); err != nil { return err } return nil } // createContext interacts with Docker Context to create a Docker context config func createContext(name string, host string) error { s := NewDefaultDockerContextStore() contextMetadata := contextStore.Metadata{ Endpoints: make(map[string]interface{}), Name: name, } contextTLSData := contextStore.ContextTLSData{ Endpoints: make(map[string]contextStore.EndpointTLSData), } dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(host) if err != nil { return err } contextMetadata.Endpoints[docker.DockerEndpoint] = dockerEP if dockerTLS != nil { contextTLSData.Endpoints[docker.DockerEndpoint] = *dockerTLS } if err := s.CreateOrUpdate(contextMetadata); err != nil { return err } if err := s.ResetTLSMaterial(name, &contextTLSData); err != nil { return err } return nil } func GetContext(contextName string) (contextStore.Metadata, error) { ctx, err := NewDefaultDockerContextStore().GetMetadata(contextName) if err != nil { return contextStore.Metadata{}, err } return ctx, nil } func GetContextEndpoint(ctx contextStore.Metadata) (string, error) { // safe to use docker key hardcoded since abra doesn't use k8s... yet... endpointmeta, ok := ctx.Endpoints["docker"].(context.EndpointMetaBase) if !ok { err := errors.New("context lacks Docker endpoint") return "", err } return endpointmeta.Host, nil } func newContextStore(dir string, config contextStore.Config) contextStore.Store { return contextStore.New(dir, config) } func NewDefaultDockerContextStore() *command.ContextStoreWithDefault { // Grabbing the stderr from Docker commands // Much easier to fit this into the code we are using to replicate docker cli commands _, _, stderr := term.StdStreams() // TODO: Look into custom docker configs in case users want that dockerConfig := dConfig.LoadDefaultConfigFile(stderr) contextDir := dConfig.ContextStoreDir() storeConfig := command.DefaultContextStoreConfig() store := newContextStore(contextDir, storeConfig) dockerContextStore := &command.ContextStoreWithDefault{ Store: store, Resolver: func() (*command.DefaultContext, error) { // nil for the Opts because it works without it and its a cli thing return command.ResolveDefaultContext(nil, dockerConfig, storeConfig, stderr) }, } return dockerContextStore }