diff --git a/builder/googlecompute/builder.go b/builder/googlecompute/builder.go index f083066c4..60b5ac551 100644 --- a/builder/googlecompute/builder.go +++ b/builder/googlecompute/builder.go @@ -56,6 +56,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("gce_%s.pem", b.config.PackerBuildName), }, + &StepImportOSLoginSSHKey{ + Debug: b.config.PackerDebug, + }, &StepCreateInstance{ Debug: b.config.PackerDebug, }, diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index 8d8ccfb04..c7fd17aeb 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -220,6 +220,50 @@ type Config struct { // If true, use the instance's internal IP instead of its external IP // during building. UseInternalIP bool `mapstructure:"use_internal_ip" required:"false"` + // If true, OSLogin will be used to manage SSH access to the compute instance by + // dynamically importing a temporary SSH key to the Google account's login profile, + // and setting the `enable-oslogin` to `TRUE` in the instance metadata. + // Optionally, `use_os_login` can be used with an existing `ssh_username` and `ssh_private_key_file` + // if a SSH key has already been added to the Google account's login profile - See [Adding SSH Keys](https://cloud.google.com/compute/docs/instances/managing-instance-access#add_oslogin_keys). + // + // SSH keys can be added to an individual user account + // + //```shell-session + // $ gcloud compute os-login ssh-keys add --key-file=/home/user/.ssh/my-key.pub + // + // $ gcloud compute os-login describe-profile + //PosixAccounts: + //- accountId: + // gid: '34567890754' + // homeDirectory: /home/user_example_com + // ... + // primary: true + // uid: '2504818925' + // username: /home/user_example_com + //sshPublicKeys: + // 000000000000000000000000000000000000000000000000000000000000000a: + // fingerprint: 000000000000000000000000000000000000000000000000000000000000000a + //``` + // + // Or SSH keys can be added to an associated service account + //```shell-session + // $ gcloud auth activate-service-account --key-file= + // $ gcloud compute os-login ssh-keys add --key-file=/home/user/.ssh/my-key.pub + // + // $ gcloud compute os-login describe-profile + //PosixAccounts: + //- accountId: + // gid: '34567890754' + // homeDirectory: /home/sa_000000000000000000000 + // ... + // primary: true + // uid: '2504818925' + // username: sa_000000000000000000000 + //sshPublicKeys: + // 000000000000000000000000000000000000000000000000000000000000000a: + // fingerprint: 000000000000000000000000000000000000000000000000000000000000000a + //``` + UseOSLogin bool `mapstructure:"use_os_login" required:"false"` // Can be set instead of account_file. If set, this builder will use // HashiCorp Vault to generate an Oauth token for authenticating against // Google's cloud. The value should be the path of the token generator diff --git a/builder/googlecompute/config.hcl2spec.go b/builder/googlecompute/config.hcl2spec.go index bf1defda0..7e2fcdae0 100644 --- a/builder/googlecompute/config.hcl2spec.go +++ b/builder/googlecompute/config.hcl2spec.go @@ -106,6 +106,7 @@ type FlatConfig struct { Subnetwork *string `mapstructure:"subnetwork" required:"false" cty:"subnetwork" hcl:"subnetwork"` Tags []string `mapstructure:"tags" required:"false" cty:"tags" hcl:"tags"` UseInternalIP *bool `mapstructure:"use_internal_ip" required:"false" cty:"use_internal_ip" hcl:"use_internal_ip"` + UseOSLogin *bool `mapstructure:"use_os_login" required:"false" cty:"use_os_login" hcl:"use_os_login"` VaultGCPOauthEngine *string `mapstructure:"vault_gcp_oauth_engine" cty:"vault_gcp_oauth_engine" hcl:"vault_gcp_oauth_engine"` Zone *string `mapstructure:"zone" required:"true" cty:"zone" hcl:"zone"` } @@ -219,6 +220,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "subnetwork": &hcldec.AttrSpec{Name: "subnetwork", Type: cty.String, Required: false}, "tags": &hcldec.AttrSpec{Name: "tags", Type: cty.List(cty.String), Required: false}, "use_internal_ip": &hcldec.AttrSpec{Name: "use_internal_ip", Type: cty.Bool, Required: false}, + "use_os_login": &hcldec.AttrSpec{Name: "use_os_login", Type: cty.Bool, Required: false}, "vault_gcp_oauth_engine": &hcldec.AttrSpec{Name: "vault_gcp_oauth_engine", Type: cty.String, Required: false}, "zone": &hcldec.AttrSpec{Name: "zone", Type: cty.String, Required: false}, } diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index 2e0224230..65243250b 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -5,6 +5,7 @@ import ( "time" compute "google.golang.org/api/compute/v1" + oslogin "google.golang.org/api/oslogin/v1" ) // Driver is the interface that has to be implemented to communicate @@ -62,6 +63,12 @@ type Driver interface { // CreateOrResetWindowsPassword creates or resets the password for a user on an Windows instance. CreateOrResetWindowsPassword(zone, name string, config *WindowsPasswordConfig) (<-chan error, error) + + // ImportOSLoginSSHKey imports SSH public key for OSLogin. + ImportOSLoginSSHKey(user, sshPublicKey string) (*oslogin.LoginProfile, error) + + // DeleteOSLoginSSHKey deletes the SSH public key for OSLogin with the given key. + DeleteOSLoginSSHKey(user, fingerprint string) error } type InstanceConfig struct { diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 3110081c5..3fca1f6b1 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -15,6 +15,7 @@ import ( "time" compute "google.golang.org/api/compute/v1" + oslogin "google.golang.org/api/oslogin/v1" "github.com/hashicorp/packer/common/retry" "github.com/hashicorp/packer/helper/useragent" @@ -29,9 +30,10 @@ import ( // driverGCE is a Driver implementation that actually talks to GCE. // Create an instance using NewDriverGCE. type driverGCE struct { - projectId string - service *compute.Service - ui packer.Ui + projectId string + service *compute.Service + osLoginService *oslogin.Service + ui packer.Ui } var DriverScopes = []string{"https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/devstorage.full_control"} @@ -127,13 +129,19 @@ func NewDriverGCE(ui packer.Ui, p string, conf *jwt.Config, vaultOauth string) ( return nil, err } + osLoginService, err := oslogin.New(client) + if err != nil { + return nil, err + } + // Set UserAgent service.UserAgent = useragent.String() return &driverGCE{ - projectId: p, - service: service, - ui: ui, + projectId: p, + service: service, + osLoginService: osLoginService, + ui: ui, }, nil } @@ -605,6 +613,28 @@ func (d *driverGCE) getPasswordResponses(zone, instance string) ([]windowsPasswo return passwordResponses, nil } +func (d *driverGCE) ImportOSLoginSSHKey(user, sshPublicKey string) (*oslogin.LoginProfile, error) { + parent := fmt.Sprintf("users/%s", user) + resp, err := d.osLoginService.Users.ImportSshPublicKey(parent, &oslogin.SshPublicKey{ + Key: sshPublicKey, + }).Do() + if err != nil { + return nil, err + } + + return resp.LoginProfile, nil +} + +func (d *driverGCE) DeleteOSLoginSSHKey(user, fingerprint string) error { + name := fmt.Sprintf("users/%s/sshPublicKeys/%s", user, fingerprint) + _, err := d.osLoginService.Users.SshPublicKeys.Delete(name).Do() + if err != nil { + return err + } + + return nil +} + func (d *driverGCE) WaitForInstance(state, zone, name string) <-chan error { errCh := make(chan error, 1) go waitForState(errCh, state, d.refreshInstanceState(zone, name)) diff --git a/builder/googlecompute/driver_mock.go b/builder/googlecompute/driver_mock.go index e01ffe058..da5599bc9 100644 --- a/builder/googlecompute/driver_mock.go +++ b/builder/googlecompute/driver_mock.go @@ -4,6 +4,7 @@ import ( "fmt" compute "google.golang.org/api/compute/v1" + oslogin "google.golang.org/api/oslogin/v1" ) // DriverMock is a Driver implementation that is a mocked out so that @@ -275,3 +276,15 @@ func (d *DriverMock) CreateOrResetWindowsPassword(instance, zone string, c *Wind return resultCh, d.CreateOrResetWindowsPasswordErr } + +func (d *DriverMock) ImportOSLoginSSHKey(user, key string) (*oslogin.LoginProfile, error) { + account := oslogin.PosixAccount{Primary: true, Username: "testing_packer_io"} + profile := oslogin.LoginProfile{ + PosixAccounts: []*oslogin.PosixAccount{&account}, + } + return &profile, nil +} + +func (d *DriverMock) DeleteOSLoginSSHKey(user, fingerprint string) error { + return nil +} diff --git a/builder/googlecompute/startup.go b/builder/googlecompute/startup.go index 18d6961ef..743778a2c 100644 --- a/builder/googlecompute/startup.go +++ b/builder/googlecompute/startup.go @@ -7,6 +7,7 @@ import ( const StartupScriptKey string = "startup-script" const StartupScriptStatusKey string = "startup-script-status" const StartupWrappedScriptKey string = "packer-wrapped-startup-script" +const EnableOSLoginKey string = "enable-oslogin" const StartupScriptStatusDone string = "done" const StartupScriptStatusError string = "error" diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index 4eb86ad08..6c892da60 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -64,6 +64,12 @@ func (c *Config) createInstanceMetadata(sourceImage *Image, sshPublicKey string) instanceMetadata[StartupScriptStatusKey] = StartupScriptStatusDone } + // If UseOSLogin is true, force `enable-oslogin` in metadata + // In the event that `enable-oslogin` is not enabled at project level + if c.UseOSLogin { + instanceMetadata[EnableOSLoginKey] = "TRUE" + } + for key, value := range c.MetadataFiles { var content []byte content, err = ioutil.ReadFile(value) diff --git a/builder/googlecompute/step_import_os_login_ssh_key.go b/builder/googlecompute/step_import_os_login_ssh_key.go new file mode 100644 index 000000000..0d064bfb0 --- /dev/null +++ b/builder/googlecompute/step_import_os_login_ssh_key.go @@ -0,0 +1,132 @@ +package googlecompute + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "google.golang.org/api/oauth2/v2" +) + +// StepImportOSLoginSSHKey imports a temporary SSH key pair into a GCE login profile. +type StepImportOSLoginSSHKey struct { + Debug bool + TokeninfoFunc func(context.Context) (*oauth2.Tokeninfo, error) + accountEmail string +} + +// Run executes the Packer build step that generates SSH key pairs. +// The key pairs are added to the ssh config +func (s *StepImportOSLoginSSHKey) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + driver := state.Get("driver").(Driver) + ui := state.Get("ui").(packer.Ui) + + if !config.UseOSLogin { + return multistep.ActionContinue + } + + // If no public key information is available chances are that a private key was provided + // or that the user is using a SSH agent for authentication. + if config.Comm.SSHPublicKey == nil { + ui.Say("No public SSH key found; skipping SSH public key import for OSLogin...") + return multistep.ActionContinue + } + + if s.TokeninfoFunc == nil { + s.TokeninfoFunc = tokeninfo + } + + ui.Say("Importing SSH public key for OSLogin...") + // Generate SHA256 fingerprint of SSH public key + // Put it into state to clean up later + sha256sum := sha256.Sum256(config.Comm.SSHPublicKey) + state.Put("ssh_key_public_sha256", hex.EncodeToString(sha256sum[:])) + + if config.account != nil { + s.accountEmail = config.account.Email + } + + if s.accountEmail == "" { + info, err := s.TokeninfoFunc(ctx) + if err != nil { + err := fmt.Errorf("Error obtaining token information needed for OSLogin: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.accountEmail = info.Email + } + + loginProfile, err := driver.ImportOSLoginSSHKey(s.accountEmail, string(config.Comm.SSHPublicKey)) + if err != nil { + err := fmt.Errorf("Error importing SSH public key for OSLogin: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Replacing `SSHUsername` as the username have to be from OSLogin + if len(loginProfile.PosixAccounts) == 0 { + err := fmt.Errorf("Error importing SSH public key for OSLogin: no PosixAccounts available") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Let's obtain the `Primary` account username + ui.Say("Obtaining SSH Username for OSLogin...") + var username string + for _, account := range loginProfile.PosixAccounts { + if account.Primary { + username = account.Username + break + } + } + + if s.Debug { + ui.Message(fmt.Sprintf("ssh_username: %s", username)) + } + config.Comm.SSHUsername = username + + return multistep.ActionContinue +} + +// Cleanup the SSH Key that we added to the POSIX account +func (s *StepImportOSLoginSSHKey) Cleanup(state multistep.StateBag) { + config := state.Get("config").(*Config) + driver := state.Get("driver").(Driver) + ui := state.Get("ui").(packer.Ui) + + if !config.UseOSLogin { + return + } + + fingerprint, ok := state.Get("ssh_key_public_sha256").(string) + if !ok || fingerprint == "" { + return + } + + ui.Say("Deleting SSH public key for OSLogin...") + err := driver.DeleteOSLoginSSHKey(s.accountEmail, fingerprint) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting SSH public key for OSLogin. Please delete it manually.\n\nError: %s", err)) + return + } + + ui.Message("SSH public key for OSLogin has been deleted!") +} + +func tokeninfo(ctx context.Context) (*oauth2.Tokeninfo, error) { + svc, err := oauth2.NewService(ctx) + if err != nil { + err := fmt.Errorf("Error initializing oauth service needed for OSLogin: %s", err) + return nil, err + } + + return svc.Tokeninfo().Context(ctx).Do() +} diff --git a/builder/googlecompute/step_import_os_login_ssh_key_test.go b/builder/googlecompute/step_import_os_login_ssh_key_test.go new file mode 100644 index 000000000..f31df1b0d --- /dev/null +++ b/builder/googlecompute/step_import_os_login_ssh_key_test.go @@ -0,0 +1,152 @@ +package googlecompute + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "testing" + + "github.com/hashicorp/packer/helper/multistep" + "google.golang.org/api/oauth2/v2" +) + +func TestStepImportOSLoginSSHKey_impl(t *testing.T) { + var _ multistep.Step = new(StepImportOSLoginSSHKey) +} + +func TestStepImportOSLoginSSHKey(t *testing.T) { + tt := []struct { + Name string + UseOSLogin bool + ExpectedEmail string + ExpectedAction multistep.StepAction + PubKeyExpected bool + }{ + { + Name: "UseOSLoginDisabled", + ExpectedAction: multistep.ActionContinue, + }, + { + Name: "UseOSLoginWithAccountFile", + UseOSLogin: true, + ExpectedAction: multistep.ActionContinue, + ExpectedEmail: "raffi-compute@developer.gserviceaccount.com", + PubKeyExpected: true, + }, + } + + for _, tc := range tt { + tc := tc + state := testState(t) + step := new(StepImportOSLoginSSHKey) + defer step.Cleanup(state) + + config := state.Get("config").(*Config) + config.UseOSLogin = tc.UseOSLogin + + if tc.PubKeyExpected { + config.Comm.SSHPublicKey = []byte{'k', 'e', 'y'} + } + + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + + if step.accountEmail != tc.ExpectedEmail { + t.Fatalf("expected accountEmail to be %q but got %q", tc.ExpectedEmail, step.accountEmail) + } + + if _, ok := state.GetOk("ssh_key_public_sha256"); !ok && tc.PubKeyExpected { + t.Fatal("expected to see a public key") + } + } +} + +func TestStepImportOSLoginSSHKey_withAccountFile(t *testing.T) { + // default teststate contains an account file + state := testState(t) + step := new(StepImportOSLoginSSHKey) + defer step.Cleanup(state) + + config := state.Get("config").(*Config) + config.UseOSLogin = true + config.Comm.SSHPublicKey = []byte{'k', 'e', 'y'} + + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + + fakeAccountEmail := "raffi-compute@developer.gserviceaccount.com" + if step.accountEmail != fakeAccountEmail { + t.Fatalf("expected accountEmail to be %q but got %q", fakeAccountEmail, step.accountEmail) + } + + pubKey, ok := state.GetOk("ssh_key_public_sha256") + if !ok { + t.Fatal("expected to see a public key") + } + + sha256sum := sha256.Sum256(config.Comm.SSHPublicKey) + if pubKey != hex.EncodeToString(sha256sum[:]) { + t.Errorf("expected to see a matching public key, but got %q", pubKey) + } +} + +func TestStepImportOSLoginSSHKey_withNoAccountFile(t *testing.T) { + state := testState(t) + fakeAccountEmail := "testing@packer.io" + step := &StepImportOSLoginSSHKey{ + TokeninfoFunc: func(ctx context.Context) (*oauth2.Tokeninfo, error) { + return &oauth2.Tokeninfo{Email: fakeAccountEmail}, nil + }, + } + defer step.Cleanup(state) + + config := state.Get("config").(*Config) + config.account = nil + config.UseOSLogin = true + config.Comm.SSHPublicKey = []byte{'k', 'e', 'y'} + + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + + if step.accountEmail != fakeAccountEmail { + t.Fatalf("expected accountEmail to be %q but got %q", fakeAccountEmail, step.accountEmail) + } + + pubKey, ok := state.GetOk("ssh_key_public_sha256") + if !ok { + t.Fatal("expected to see a public key") + } + + sha256sum := sha256.Sum256(config.Comm.SSHPublicKey) + if pubKey != hex.EncodeToString(sha256sum[:]) { + t.Errorf("expected to see a matching public key, but got %q", pubKey) + } +} + +func TestStepImportOSLoginSSHKey_withPrivateSSHKey(t *testing.T) { + // default teststate contains an account file + state := testState(t) + step := new(StepImportOSLoginSSHKey) + defer step.Cleanup(state) + + config := state.Get("config").(*Config) + config.UseOSLogin = true + config.Comm.SSHPrivateKey = []byte{'k', 'e', 'y'} + config.Comm.SSHPublicKey = nil + + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + + if step.accountEmail != "" { + t.Fatalf("expected accountEmail to be unset but got %q", step.accountEmail) + } + + pubKey, ok := state.GetOk("ssh_key_public_sha256") + if ok { + t.Errorf("expected to not see a public key when using a dedicated private key, but got %q", pubKey) + } +} diff --git a/go.sum b/go.sum index 9bd7b11ed..dbfde231c 100644 --- a/go.sum +++ b/go.sum @@ -727,21 +727,15 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 h1:pE8b58s1HRDMi8RDc79m0HISf9D4TzseP40cEA6IGfs= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= @@ -749,11 +743,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5 h1:x6r4Jo0KNzOOzYd8lbcRsqjuqEASK6ob3auvWYM4/8U= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -764,7 +756,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -781,23 +772,17 @@ golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -807,14 +792,12 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138 h1:H3uGjxCR/6Ds0Mjgyp7LMK81+LvmbvWWEnJhzk1Pi9E= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -832,24 +815,19 @@ golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa h1:5E4dL8+NgFOgjwbTKz+OOEGGhP+ectTmF842l6KjupQ= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2 h1:L/G4KZvrQn7FWLN/LlulBtBzrLUhqjiGfTWWDmrh+IQ= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0 h1:KKgc1aqhV8wDPbDzlDtpvyjZFY3vjz85FP7p4wcQUyI= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= @@ -857,22 +835,18 @@ google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.21.0 h1:zS+Q/CJJnVlXpXQVIz+lH0ZT2lBuT2ac7XD8Y/3w6hY= google.golang.org/api v0.21.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -890,18 +864,14 @@ google.golang.org/genproto v0.0.0-20200617032506-f1bdc9086088 h1:XXo4PvhJkaWYIkw google.golang.org/genproto v0.0.0-20200617032506-f1bdc9086088/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= @@ -916,9 +886,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -932,9 +900,7 @@ gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181117152235-275e9df93516/go.mod h1:d3R+Nl gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -942,7 +908,6 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= diff --git a/vendor/google.golang.org/api/oauth2/v2/oauth2-api.json b/vendor/google.golang.org/api/oauth2/v2/oauth2-api.json new file mode 100644 index 000000000..1e7653fde --- /dev/null +++ b/vendor/google.golang.org/api/oauth2/v2/oauth2-api.json @@ -0,0 +1,246 @@ +{ + "auth": { + "oauth2": { + "scopes": { + "https://www.googleapis.com/auth/plus.me": { + "description": "Associate you with your personal info on Google" + }, + "https://www.googleapis.com/auth/userinfo.email": { + "description": "View your email address" + }, + "https://www.googleapis.com/auth/userinfo.profile": { + "description": "See your personal info, including any personal info you've made publicly available" + } + } + } + }, + "basePath": "/", + "baseUrl": "https://www.googleapis.com/", + "batchPath": "batch/oauth2/v2", + "description": "Obtains end-user authorization grants for use with other Google APIs.", + "discoveryVersion": "v1", + "documentationLink": "https://developers.google.com/accounts/docs/OAuth2", + "etag": "\"u9GIe6H63LSGq-9_t39K2Zx_EAc/zG8qVEU9Oex8Y_g8HrcHwAALOOo\"", + "icons": { + "x16": "https://www.gstatic.com/images/branding/product/1x/googleg_16dp.png", + "x32": "https://www.gstatic.com/images/branding/product/1x/googleg_32dp.png" + }, + "id": "oauth2:v2", + "kind": "discovery#restDescription", + "methods": { + "tokeninfo": { + "httpMethod": "POST", + "id": "oauth2.tokeninfo", + "parameters": { + "access_token": { + "location": "query", + "type": "string" + }, + "id_token": { + "location": "query", + "type": "string" + }, + "token_handle": { + "location": "query", + "type": "string" + } + }, + "path": "oauth2/v2/tokeninfo", + "response": { + "$ref": "Tokeninfo" + } + } + }, + "name": "oauth2", + "ownerDomain": "google.com", + "ownerName": "Google", + "parameters": { + "alt": { + "default": "json", + "description": "Data format for the response.", + "enum": [ + "json" + ], + "enumDescriptions": [ + "Responses with Content-Type of application/json" + ], + "location": "query", + "type": "string" + }, + "fields": { + "description": "Selector specifying which fields to include in a partial response.", + "location": "query", + "type": "string" + }, + "key": { + "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", + "location": "query", + "type": "string" + }, + "oauth_token": { + "description": "OAuth 2.0 token for the current user.", + "location": "query", + "type": "string" + }, + "prettyPrint": { + "default": "true", + "description": "Returns response with indentations and line breaks.", + "location": "query", + "type": "boolean" + }, + "quotaUser": { + "description": "An opaque string that represents a user for quota purposes. Must not exceed 40 characters.", + "location": "query", + "type": "string" + }, + "userIp": { + "description": "Deprecated. Please use quotaUser instead.", + "location": "query", + "type": "string" + } + }, + "protocol": "rest", + "resources": { + "userinfo": { + "methods": { + "get": { + "httpMethod": "GET", + "id": "oauth2.userinfo.get", + "path": "oauth2/v2/userinfo", + "response": { + "$ref": "Userinfoplus" + }, + "scopes": [ + "https://www.googleapis.com/auth/plus.me", + "https://www.googleapis.com/auth/userinfo.email", + "https://www.googleapis.com/auth/userinfo.profile" + ] + } + }, + "resources": { + "v2": { + "resources": { + "me": { + "methods": { + "get": { + "httpMethod": "GET", + "id": "oauth2.userinfo.v2.me.get", + "path": "userinfo/v2/me", + "response": { + "$ref": "Userinfoplus" + }, + "scopes": [ + "https://www.googleapis.com/auth/plus.me", + "https://www.googleapis.com/auth/userinfo.email", + "https://www.googleapis.com/auth/userinfo.profile" + ] + } + } + } + } + } + } + } + }, + "revision": "20200213", + "rootUrl": "https://www.googleapis.com/", + "schemas": { + "Tokeninfo": { + "id": "Tokeninfo", + "properties": { + "access_type": { + "description": "The access type granted with this token. It can be offline or online.", + "type": "string" + }, + "audience": { + "description": "Who is the intended audience for this token. In general the same as issued_to.", + "type": "string" + }, + "email": { + "description": "The email address of the user. Present only if the email scope is present in the request.", + "type": "string" + }, + "expires_in": { + "description": "The expiry time of the token, as number of seconds left until expiry.", + "format": "int32", + "type": "integer" + }, + "issued_to": { + "description": "To whom was the token issued to. In general the same as audience.", + "type": "string" + }, + "scope": { + "description": "The space separated list of scopes granted to this token.", + "type": "string" + }, + "token_handle": { + "description": "The token handle associated with this token.", + "type": "string" + }, + "user_id": { + "description": "The obfuscated user id.", + "type": "string" + }, + "verified_email": { + "description": "Boolean flag which is true if the email address is verified. Present only if the email scope is present in the request.", + "type": "boolean" + } + }, + "type": "object" + }, + "Userinfoplus": { + "id": "Userinfoplus", + "properties": { + "email": { + "description": "The user's email address.", + "type": "string" + }, + "family_name": { + "description": "The user's last name.", + "type": "string" + }, + "gender": { + "description": "The user's gender.", + "type": "string" + }, + "given_name": { + "description": "The user's first name.", + "type": "string" + }, + "hd": { + "description": "The hosted domain e.g. example.com if the user is Google apps user.", + "type": "string" + }, + "id": { + "description": "The obfuscated ID of the user.", + "type": "string" + }, + "link": { + "description": "URL of the profile page.", + "type": "string" + }, + "locale": { + "description": "The user's preferred locale.", + "type": "string" + }, + "name": { + "description": "The user's full name.", + "type": "string" + }, + "picture": { + "description": "URL of the user's picture image.", + "type": "string" + }, + "verified_email": { + "default": "true", + "description": "Boolean flag which is true if the email address is verified. Always verified because we only return the user's primary email address.", + "type": "boolean" + } + }, + "type": "object" + } + }, + "servicePath": "", + "title": "Google OAuth2 API", + "version": "v2" +} \ No newline at end of file diff --git a/vendor/google.golang.org/api/oauth2/v2/oauth2-gen.go b/vendor/google.golang.org/api/oauth2/v2/oauth2-gen.go new file mode 100644 index 000000000..c3ace0bb5 --- /dev/null +++ b/vendor/google.golang.org/api/oauth2/v2/oauth2-gen.go @@ -0,0 +1,701 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated file. DO NOT EDIT. + +// Package oauth2 provides access to the Google OAuth2 API. +// +// For product documentation, see: https://developers.google.com/accounts/docs/OAuth2 +// +// Creating a client +// +// Usage example: +// +// import "google.golang.org/api/oauth2/v2" +// ... +// ctx := context.Background() +// oauth2Service, err := oauth2.NewService(ctx) +// +// In this example, Google Application Default Credentials are used for authentication. +// +// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials. +// +// Other authentication options +// +// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes: +// +// oauth2Service, err := oauth2.NewService(ctx, option.WithScopes(oauth2.UserinfoProfileScope)) +// +// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey: +// +// oauth2Service, err := oauth2.NewService(ctx, option.WithAPIKey("AIza...")) +// +// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource: +// +// config := &oauth2.Config{...} +// // ... +// token, err := config.Exchange(ctx, ...) +// oauth2Service, err := oauth2.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token))) +// +// See https://godoc.org/google.golang.org/api/option/ for details on options. +package oauth2 // import "google.golang.org/api/oauth2/v2" + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + + googleapi "google.golang.org/api/googleapi" + gensupport "google.golang.org/api/internal/gensupport" + option "google.golang.org/api/option" + internaloption "google.golang.org/api/option/internaloption" + htransport "google.golang.org/api/transport/http" +) + +// Always reference these packages, just in case the auto-generated code +// below doesn't. +var _ = bytes.NewBuffer +var _ = strconv.Itoa +var _ = fmt.Sprintf +var _ = json.NewDecoder +var _ = io.Copy +var _ = url.Parse +var _ = gensupport.MarshalJSON +var _ = googleapi.Version +var _ = errors.New +var _ = strings.Replace +var _ = context.Canceled +var _ = internaloption.WithDefaultEndpoint + +const apiId = "oauth2:v2" +const apiName = "oauth2" +const apiVersion = "v2" +const basePath = "https://www.googleapis.com/" + +// OAuth2 scopes used by this API. +const ( + // Associate you with your personal info on Google + PlusMeScope = "https://www.googleapis.com/auth/plus.me" + + // View your email address + UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email" + + // See your personal info, including any personal info you've made + // publicly available + UserinfoProfileScope = "https://www.googleapis.com/auth/userinfo.profile" +) + +// NewService creates a new Service. +func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) { + scopesOption := option.WithScopes( + "https://www.googleapis.com/auth/plus.me", + "https://www.googleapis.com/auth/userinfo.email", + "https://www.googleapis.com/auth/userinfo.profile", + ) + // NOTE: prepend, so we don't override user-specified scopes. + opts = append([]option.ClientOption{scopesOption}, opts...) + opts = append(opts, internaloption.WithDefaultEndpoint(basePath)) + client, endpoint, err := htransport.NewClient(ctx, opts...) + if err != nil { + return nil, err + } + s, err := New(client) + if err != nil { + return nil, err + } + if endpoint != "" { + s.BasePath = endpoint + } + return s, nil +} + +// New creates a new Service. It uses the provided http.Client for requests. +// +// Deprecated: please use NewService instead. +// To provide a custom HTTP client, use option.WithHTTPClient. +// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead. +func New(client *http.Client) (*Service, error) { + if client == nil { + return nil, errors.New("client is nil") + } + s := &Service{client: client, BasePath: basePath} + s.Userinfo = NewUserinfoService(s) + return s, nil +} + +type Service struct { + client *http.Client + BasePath string // API endpoint base URL + UserAgent string // optional additional User-Agent fragment + + Userinfo *UserinfoService +} + +func (s *Service) userAgent() string { + if s.UserAgent == "" { + return googleapi.UserAgent + } + return googleapi.UserAgent + " " + s.UserAgent +} + +func NewUserinfoService(s *Service) *UserinfoService { + rs := &UserinfoService{s: s} + rs.V2 = NewUserinfoV2Service(s) + return rs +} + +type UserinfoService struct { + s *Service + + V2 *UserinfoV2Service +} + +func NewUserinfoV2Service(s *Service) *UserinfoV2Service { + rs := &UserinfoV2Service{s: s} + rs.Me = NewUserinfoV2MeService(s) + return rs +} + +type UserinfoV2Service struct { + s *Service + + Me *UserinfoV2MeService +} + +func NewUserinfoV2MeService(s *Service) *UserinfoV2MeService { + rs := &UserinfoV2MeService{s: s} + return rs +} + +type UserinfoV2MeService struct { + s *Service +} + +type Tokeninfo struct { + // AccessType: The access type granted with this token. It can be + // offline or online. + AccessType string `json:"access_type,omitempty"` + + // Audience: Who is the intended audience for this token. In general the + // same as issued_to. + Audience string `json:"audience,omitempty"` + + // Email: The email address of the user. Present only if the email scope + // is present in the request. + Email string `json:"email,omitempty"` + + // ExpiresIn: The expiry time of the token, as number of seconds left + // until expiry. + ExpiresIn int64 `json:"expires_in,omitempty"` + + // IssuedTo: To whom was the token issued to. In general the same as + // audience. + IssuedTo string `json:"issued_to,omitempty"` + + // Scope: The space separated list of scopes granted to this token. + Scope string `json:"scope,omitempty"` + + // TokenHandle: The token handle associated with this token. + TokenHandle string `json:"token_handle,omitempty"` + + // UserId: The obfuscated user id. + UserId string `json:"user_id,omitempty"` + + // VerifiedEmail: Boolean flag which is true if the email address is + // verified. Present only if the email scope is present in the request. + VerifiedEmail bool `json:"verified_email,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccessType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "AccessType") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Tokeninfo) MarshalJSON() ([]byte, error) { + type NoMethod Tokeninfo + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type Userinfoplus struct { + // Email: The user's email address. + Email string `json:"email,omitempty"` + + // FamilyName: The user's last name. + FamilyName string `json:"family_name,omitempty"` + + // Gender: The user's gender. + Gender string `json:"gender,omitempty"` + + // GivenName: The user's first name. + GivenName string `json:"given_name,omitempty"` + + // Hd: The hosted domain e.g. example.com if the user is Google apps + // user. + Hd string `json:"hd,omitempty"` + + // Id: The obfuscated ID of the user. + Id string `json:"id,omitempty"` + + // Link: URL of the profile page. + Link string `json:"link,omitempty"` + + // Locale: The user's preferred locale. + Locale string `json:"locale,omitempty"` + + // Name: The user's full name. + Name string `json:"name,omitempty"` + + // Picture: URL of the user's picture image. + Picture string `json:"picture,omitempty"` + + // VerifiedEmail: Boolean flag which is true if the email address is + // verified. Always verified because we only return the user's primary + // email address. + // + // Default: true + VerifiedEmail *bool `json:"verified_email,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Email") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Email") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Userinfoplus) MarshalJSON() ([]byte, error) { + type NoMethod Userinfoplus + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// method id "oauth2.tokeninfo": + +type TokeninfoCall struct { + s *Service + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Tokeninfo: +func (s *Service) Tokeninfo() *TokeninfoCall { + c := &TokeninfoCall{s: s, urlParams_: make(gensupport.URLParams)} + return c +} + +// AccessToken sets the optional parameter "access_token": +func (c *TokeninfoCall) AccessToken(accessToken string) *TokeninfoCall { + c.urlParams_.Set("access_token", accessToken) + return c +} + +// IdToken sets the optional parameter "id_token": +func (c *TokeninfoCall) IdToken(idToken string) *TokeninfoCall { + c.urlParams_.Set("id_token", idToken) + return c +} + +// TokenHandle sets the optional parameter "token_handle": +func (c *TokeninfoCall) TokenHandle(tokenHandle string) *TokeninfoCall { + c.urlParams_.Set("token_handle", tokenHandle) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *TokeninfoCall) Fields(s ...googleapi.Field) *TokeninfoCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *TokeninfoCall) Context(ctx context.Context) *TokeninfoCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *TokeninfoCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *TokeninfoCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "oauth2/v2/tokeninfo") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oauth2.tokeninfo" call. +// Exactly one of *Tokeninfo or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Tokeninfo.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *TokeninfoCall) Do(opts ...googleapi.CallOption) (*Tokeninfo, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Tokeninfo{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "httpMethod": "POST", + // "id": "oauth2.tokeninfo", + // "parameters": { + // "access_token": { + // "location": "query", + // "type": "string" + // }, + // "id_token": { + // "location": "query", + // "type": "string" + // }, + // "token_handle": { + // "location": "query", + // "type": "string" + // } + // }, + // "path": "oauth2/v2/tokeninfo", + // "response": { + // "$ref": "Tokeninfo" + // } + // } + +} + +// method id "oauth2.userinfo.get": + +type UserinfoGetCall struct { + s *Service + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: +func (r *UserinfoService) Get() *UserinfoGetCall { + c := &UserinfoGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UserinfoGetCall) Fields(s ...googleapi.Field) *UserinfoGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *UserinfoGetCall) IfNoneMatch(entityTag string) *UserinfoGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UserinfoGetCall) Context(ctx context.Context) *UserinfoGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UserinfoGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UserinfoGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "oauth2/v2/userinfo") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oauth2.userinfo.get" call. +// Exactly one of *Userinfoplus or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Userinfoplus.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *UserinfoGetCall) Do(opts ...googleapi.CallOption) (*Userinfoplus, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Userinfoplus{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "httpMethod": "GET", + // "id": "oauth2.userinfo.get", + // "path": "oauth2/v2/userinfo", + // "response": { + // "$ref": "Userinfoplus" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/plus.me", + // "https://www.googleapis.com/auth/userinfo.email", + // "https://www.googleapis.com/auth/userinfo.profile" + // ] + // } + +} + +// method id "oauth2.userinfo.v2.me.get": + +type UserinfoV2MeGetCall struct { + s *Service + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: +func (r *UserinfoV2MeService) Get() *UserinfoV2MeGetCall { + c := &UserinfoV2MeGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UserinfoV2MeGetCall) Fields(s ...googleapi.Field) *UserinfoV2MeGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *UserinfoV2MeGetCall) IfNoneMatch(entityTag string) *UserinfoV2MeGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UserinfoV2MeGetCall) Context(ctx context.Context) *UserinfoV2MeGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UserinfoV2MeGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UserinfoV2MeGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "userinfo/v2/me") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oauth2.userinfo.v2.me.get" call. +// Exactly one of *Userinfoplus or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Userinfoplus.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *UserinfoV2MeGetCall) Do(opts ...googleapi.CallOption) (*Userinfoplus, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Userinfoplus{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "httpMethod": "GET", + // "id": "oauth2.userinfo.v2.me.get", + // "path": "userinfo/v2/me", + // "response": { + // "$ref": "Userinfoplus" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/plus.me", + // "https://www.googleapis.com/auth/userinfo.email", + // "https://www.googleapis.com/auth/userinfo.profile" + // ] + // } + +} diff --git a/vendor/google.golang.org/api/oslogin/v1/oslogin-api.json b/vendor/google.golang.org/api/oslogin/v1/oslogin-api.json new file mode 100644 index 000000000..1c6ef44e9 --- /dev/null +++ b/vendor/google.golang.org/api/oslogin/v1/oslogin-api.json @@ -0,0 +1,446 @@ +{ + "auth": { + "oauth2": { + "scopes": { + "https://www.googleapis.com/auth/cloud-platform": { + "description": "View and manage your data across Google Cloud Platform services" + }, + "https://www.googleapis.com/auth/compute": { + "description": "View and manage your Google Compute Engine resources" + } + } + } + }, + "basePath": "", + "baseUrl": "https://oslogin.googleapis.com/", + "batchPath": "batch", + "canonicalName": "Cloud OS Login", + "description": "You can use OS Login to manage access to your VM instances using IAM roles.", + "discoveryVersion": "v1", + "documentationLink": "https://cloud.google.com/compute/docs/oslogin/", + "fullyEncodeReservedExpansion": true, + "icons": { + "x16": "http://www.google.com/images/icons/product/search-16.gif", + "x32": "http://www.google.com/images/icons/product/search-32.gif" + }, + "id": "oslogin:v1", + "kind": "discovery#restDescription", + "mtlsRootUrl": "https://oslogin.mtls.googleapis.com/", + "name": "oslogin", + "ownerDomain": "google.com", + "ownerName": "Google", + "parameters": { + "$.xgafv": { + "description": "V1 error format.", + "enum": [ + "1", + "2" + ], + "enumDescriptions": [ + "v1 error format", + "v2 error format" + ], + "location": "query", + "type": "string" + }, + "access_token": { + "description": "OAuth access token.", + "location": "query", + "type": "string" + }, + "alt": { + "default": "json", + "description": "Data format for response.", + "enum": [ + "json", + "media", + "proto" + ], + "enumDescriptions": [ + "Responses with Content-Type of application/json", + "Media download with context-dependent Content-Type", + "Responses with Content-Type of application/x-protobuf" + ], + "location": "query", + "type": "string" + }, + "callback": { + "description": "JSONP", + "location": "query", + "type": "string" + }, + "fields": { + "description": "Selector specifying which fields to include in a partial response.", + "location": "query", + "type": "string" + }, + "key": { + "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", + "location": "query", + "type": "string" + }, + "oauth_token": { + "description": "OAuth 2.0 token for the current user.", + "location": "query", + "type": "string" + }, + "prettyPrint": { + "default": "true", + "description": "Returns response with indentations and line breaks.", + "location": "query", + "type": "boolean" + }, + "quotaUser": { + "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.", + "location": "query", + "type": "string" + }, + "uploadType": { + "description": "Legacy upload protocol for media (e.g. \"media\", \"multipart\").", + "location": "query", + "type": "string" + }, + "upload_protocol": { + "description": "Upload protocol for media (e.g. \"raw\", \"multipart\").", + "location": "query", + "type": "string" + } + }, + "protocol": "rest", + "resources": { + "users": { + "methods": { + "getLoginProfile": { + "description": "Retrieves the profile information used for logging in to a virtual machine\non Google Compute Engine.", + "flatPath": "v1/users/{usersId}/loginProfile", + "httpMethod": "GET", + "id": "oslogin.users.getLoginProfile", + "parameterOrder": [ + "name" + ], + "parameters": { + "name": { + "description": "Required. The unique ID for the user in format `users/{user}`.", + "location": "path", + "pattern": "^users/[^/]+$", + "required": true, + "type": "string" + }, + "projectId": { + "description": "The project ID of the Google Cloud Platform project.", + "location": "query", + "type": "string" + }, + "systemId": { + "description": "A system ID for filtering the results of the request.", + "location": "query", + "type": "string" + } + }, + "path": "v1/{+name}/loginProfile", + "response": { + "$ref": "LoginProfile" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/compute" + ] + }, + "importSshPublicKey": { + "description": "Adds an SSH public key and returns the profile information. Default POSIX\naccount information is set when no username and UID exist as part of the\nlogin profile.", + "flatPath": "v1/users/{usersId}:importSshPublicKey", + "httpMethod": "POST", + "id": "oslogin.users.importSshPublicKey", + "parameterOrder": [ + "parent" + ], + "parameters": { + "parent": { + "description": "Required. The unique ID for the user in format `users/{user}`.", + "location": "path", + "pattern": "^users/[^/]+$", + "required": true, + "type": "string" + }, + "projectId": { + "description": "The project ID of the Google Cloud Platform project.", + "location": "query", + "type": "string" + } + }, + "path": "v1/{+parent}:importSshPublicKey", + "request": { + "$ref": "SshPublicKey" + }, + "response": { + "$ref": "ImportSshPublicKeyResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/compute" + ] + } + }, + "resources": { + "projects": { + "methods": { + "delete": { + "description": "Deletes a POSIX account.", + "flatPath": "v1/users/{usersId}/projects/{projectsId}", + "httpMethod": "DELETE", + "id": "oslogin.users.projects.delete", + "parameterOrder": [ + "name" + ], + "parameters": { + "name": { + "description": "Required. A reference to the POSIX account to update. POSIX accounts are identified\nby the project ID they are associated with. A reference to the POSIX\naccount is in format `users/{user}/projects/{project}`.", + "location": "path", + "pattern": "^users/[^/]+/projects/[^/]+$", + "required": true, + "type": "string" + } + }, + "path": "v1/{+name}", + "response": { + "$ref": "Empty" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/compute" + ] + } + } + }, + "sshPublicKeys": { + "methods": { + "delete": { + "description": "Deletes an SSH public key.", + "flatPath": "v1/users/{usersId}/sshPublicKeys/{sshPublicKeysId}", + "httpMethod": "DELETE", + "id": "oslogin.users.sshPublicKeys.delete", + "parameterOrder": [ + "name" + ], + "parameters": { + "name": { + "description": "Required. The fingerprint of the public key to update. Public keys are identified by\ntheir SHA-256 fingerprint. The fingerprint of the public key is in format\n`users/{user}/sshPublicKeys/{fingerprint}`.", + "location": "path", + "pattern": "^users/[^/]+/sshPublicKeys/[^/]+$", + "required": true, + "type": "string" + } + }, + "path": "v1/{+name}", + "response": { + "$ref": "Empty" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/compute" + ] + }, + "get": { + "description": "Retrieves an SSH public key.", + "flatPath": "v1/users/{usersId}/sshPublicKeys/{sshPublicKeysId}", + "httpMethod": "GET", + "id": "oslogin.users.sshPublicKeys.get", + "parameterOrder": [ + "name" + ], + "parameters": { + "name": { + "description": "Required. The fingerprint of the public key to retrieve. Public keys are identified\nby their SHA-256 fingerprint. The fingerprint of the public key is in\nformat `users/{user}/sshPublicKeys/{fingerprint}`.", + "location": "path", + "pattern": "^users/[^/]+/sshPublicKeys/[^/]+$", + "required": true, + "type": "string" + } + }, + "path": "v1/{+name}", + "response": { + "$ref": "SshPublicKey" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/compute" + ] + }, + "patch": { + "description": "Updates an SSH public key and returns the profile information. This method\nsupports patch semantics.", + "flatPath": "v1/users/{usersId}/sshPublicKeys/{sshPublicKeysId}", + "httpMethod": "PATCH", + "id": "oslogin.users.sshPublicKeys.patch", + "parameterOrder": [ + "name" + ], + "parameters": { + "name": { + "description": "Required. The fingerprint of the public key to update. Public keys are identified by\ntheir SHA-256 fingerprint. The fingerprint of the public key is in format\n`users/{user}/sshPublicKeys/{fingerprint}`.", + "location": "path", + "pattern": "^users/[^/]+/sshPublicKeys/[^/]+$", + "required": true, + "type": "string" + }, + "updateMask": { + "description": "Mask to control which fields get updated. Updates all if not present.", + "format": "google-fieldmask", + "location": "query", + "type": "string" + } + }, + "path": "v1/{+name}", + "request": { + "$ref": "SshPublicKey" + }, + "response": { + "$ref": "SshPublicKey" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/compute" + ] + } + } + } + } + } + }, + "revision": "20200215", + "rootUrl": "https://oslogin.googleapis.com/", + "schemas": { + "Empty": { + "description": "A generic empty message that you can re-use to avoid defining duplicated\nempty messages in your APIs. A typical example is to use it as the request\nor the response type of an API method. For instance:\n\n service Foo {\n rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);\n }\n\nThe JSON representation for `Empty` is empty JSON object `{}`.", + "id": "Empty", + "properties": {}, + "type": "object" + }, + "ImportSshPublicKeyResponse": { + "description": "A response message for importing an SSH public key.", + "id": "ImportSshPublicKeyResponse", + "properties": { + "loginProfile": { + "$ref": "LoginProfile", + "description": "The login profile information for the user." + } + }, + "type": "object" + }, + "LoginProfile": { + "description": "The user profile information used for logging in to a virtual machine on\nGoogle Compute Engine.", + "id": "LoginProfile", + "properties": { + "name": { + "description": "Required. A unique user ID.", + "type": "string" + }, + "posixAccounts": { + "description": "The list of POSIX accounts associated with the user.", + "items": { + "$ref": "PosixAccount" + }, + "type": "array" + }, + "sshPublicKeys": { + "additionalProperties": { + "$ref": "SshPublicKey" + }, + "description": "A map from SSH public key fingerprint to the associated key object.", + "type": "object" + } + }, + "type": "object" + }, + "PosixAccount": { + "description": "The POSIX account information associated with a Google account.", + "id": "PosixAccount", + "properties": { + "accountId": { + "description": "Output only. A POSIX account identifier.", + "type": "string" + }, + "gecos": { + "description": "The GECOS (user information) entry for this account.", + "type": "string" + }, + "gid": { + "description": "The default group ID.", + "format": "int64", + "type": "string" + }, + "homeDirectory": { + "description": "The path to the home directory for this account.", + "type": "string" + }, + "name": { + "description": "Output only. The canonical resource name.", + "type": "string" + }, + "operatingSystemType": { + "description": "The operating system type where this account applies.", + "enum": [ + "OPERATING_SYSTEM_TYPE_UNSPECIFIED", + "LINUX", + "WINDOWS" + ], + "enumDescriptions": [ + "The operating system type associated with the user account information is\nunspecified.", + "Linux user account information.", + "Windows user account information." + ], + "type": "string" + }, + "primary": { + "description": "Only one POSIX account can be marked as primary.", + "type": "boolean" + }, + "shell": { + "description": "The path to the logic shell for this account.", + "type": "string" + }, + "systemId": { + "description": "System identifier for which account the username or uid applies to.\nBy default, the empty value is used.", + "type": "string" + }, + "uid": { + "description": "The user ID.", + "format": "int64", + "type": "string" + }, + "username": { + "description": "The username of the POSIX account.", + "type": "string" + } + }, + "type": "object" + }, + "SshPublicKey": { + "description": "The SSH public key information associated with a Google account.", + "id": "SshPublicKey", + "properties": { + "expirationTimeUsec": { + "description": "An expiration time in microseconds since epoch.", + "format": "int64", + "type": "string" + }, + "fingerprint": { + "description": "Output only. The SHA-256 fingerprint of the SSH public key.", + "type": "string" + }, + "key": { + "description": "Public key text in SSH format, defined by\n\u003ca href=\"https://www.ietf.org/rfc/rfc4253.txt\" target=\"_blank\"\u003eRFC4253\u003c/a\u003e\nsection 6.6.", + "type": "string" + }, + "name": { + "description": "Output only. The canonical resource name.", + "type": "string" + } + }, + "type": "object" + } + }, + "servicePath": "", + "title": "Cloud OS Login API", + "version": "v1", + "version_module": true +} \ No newline at end of file diff --git a/vendor/google.golang.org/api/oslogin/v1/oslogin-gen.go b/vendor/google.golang.org/api/oslogin/v1/oslogin-gen.go new file mode 100644 index 000000000..71dc70843 --- /dev/null +++ b/vendor/google.golang.org/api/oslogin/v1/oslogin-gen.go @@ -0,0 +1,1276 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated file. DO NOT EDIT. + +// Package oslogin provides access to the Cloud OS Login API. +// +// This package is DEPRECATED. Use package cloud.google.com/go/oslogin/apiv1 instead. +// +// For product documentation, see: https://cloud.google.com/compute/docs/oslogin/ +// +// Creating a client +// +// Usage example: +// +// import "google.golang.org/api/oslogin/v1" +// ... +// ctx := context.Background() +// osloginService, err := oslogin.NewService(ctx) +// +// In this example, Google Application Default Credentials are used for authentication. +// +// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials. +// +// Other authentication options +// +// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes: +// +// osloginService, err := oslogin.NewService(ctx, option.WithScopes(oslogin.ComputeScope)) +// +// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey: +// +// osloginService, err := oslogin.NewService(ctx, option.WithAPIKey("AIza...")) +// +// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource: +// +// config := &oauth2.Config{...} +// // ... +// token, err := config.Exchange(ctx, ...) +// osloginService, err := oslogin.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token))) +// +// See https://godoc.org/google.golang.org/api/option/ for details on options. +package oslogin // import "google.golang.org/api/oslogin/v1" + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + + googleapi "google.golang.org/api/googleapi" + gensupport "google.golang.org/api/internal/gensupport" + option "google.golang.org/api/option" + internaloption "google.golang.org/api/option/internaloption" + htransport "google.golang.org/api/transport/http" +) + +// Always reference these packages, just in case the auto-generated code +// below doesn't. +var _ = bytes.NewBuffer +var _ = strconv.Itoa +var _ = fmt.Sprintf +var _ = json.NewDecoder +var _ = io.Copy +var _ = url.Parse +var _ = gensupport.MarshalJSON +var _ = googleapi.Version +var _ = errors.New +var _ = strings.Replace +var _ = context.Canceled +var _ = internaloption.WithDefaultEndpoint + +const apiId = "oslogin:v1" +const apiName = "oslogin" +const apiVersion = "v1" +const basePath = "https://oslogin.googleapis.com/" + +// OAuth2 scopes used by this API. +const ( + // View and manage your data across Google Cloud Platform services + CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform" + + // View and manage your Google Compute Engine resources + ComputeScope = "https://www.googleapis.com/auth/compute" +) + +// NewService creates a new Service. +func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) { + scopesOption := option.WithScopes( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/compute", + ) + // NOTE: prepend, so we don't override user-specified scopes. + opts = append([]option.ClientOption{scopesOption}, opts...) + opts = append(opts, internaloption.WithDefaultEndpoint(basePath)) + client, endpoint, err := htransport.NewClient(ctx, opts...) + if err != nil { + return nil, err + } + s, err := New(client) + if err != nil { + return nil, err + } + if endpoint != "" { + s.BasePath = endpoint + } + return s, nil +} + +// New creates a new Service. It uses the provided http.Client for requests. +// +// Deprecated: please use NewService instead. +// To provide a custom HTTP client, use option.WithHTTPClient. +// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead. +func New(client *http.Client) (*Service, error) { + if client == nil { + return nil, errors.New("client is nil") + } + s := &Service{client: client, BasePath: basePath} + s.Users = NewUsersService(s) + return s, nil +} + +type Service struct { + client *http.Client + BasePath string // API endpoint base URL + UserAgent string // optional additional User-Agent fragment + + Users *UsersService +} + +func (s *Service) userAgent() string { + if s.UserAgent == "" { + return googleapi.UserAgent + } + return googleapi.UserAgent + " " + s.UserAgent +} + +func NewUsersService(s *Service) *UsersService { + rs := &UsersService{s: s} + rs.Projects = NewUsersProjectsService(s) + rs.SshPublicKeys = NewUsersSshPublicKeysService(s) + return rs +} + +type UsersService struct { + s *Service + + Projects *UsersProjectsService + + SshPublicKeys *UsersSshPublicKeysService +} + +func NewUsersProjectsService(s *Service) *UsersProjectsService { + rs := &UsersProjectsService{s: s} + return rs +} + +type UsersProjectsService struct { + s *Service +} + +func NewUsersSshPublicKeysService(s *Service) *UsersSshPublicKeysService { + rs := &UsersSshPublicKeysService{s: s} + return rs +} + +type UsersSshPublicKeysService struct { + s *Service +} + +// Empty: A generic empty message that you can re-use to avoid defining +// duplicated +// empty messages in your APIs. A typical example is to use it as the +// request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns +// (google.protobuf.Empty); +// } +// +// The JSON representation for `Empty` is empty JSON object `{}`. +type Empty struct { + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` +} + +// ImportSshPublicKeyResponse: A response message for importing an SSH +// public key. +type ImportSshPublicKeyResponse struct { + // LoginProfile: The login profile information for the user. + LoginProfile *LoginProfile `json:"loginProfile,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "LoginProfile") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "LoginProfile") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ImportSshPublicKeyResponse) MarshalJSON() ([]byte, error) { + type NoMethod ImportSshPublicKeyResponse + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// LoginProfile: The user profile information used for logging in to a +// virtual machine on +// Google Compute Engine. +type LoginProfile struct { + // Name: Required. A unique user ID. + Name string `json:"name,omitempty"` + + // PosixAccounts: The list of POSIX accounts associated with the user. + PosixAccounts []*PosixAccount `json:"posixAccounts,omitempty"` + + // SshPublicKeys: A map from SSH public key fingerprint to the + // associated key object. + SshPublicKeys map[string]SshPublicKey `json:"sshPublicKeys,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Name") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Name") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *LoginProfile) MarshalJSON() ([]byte, error) { + type NoMethod LoginProfile + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// PosixAccount: The POSIX account information associated with a Google +// account. +type PosixAccount struct { + // AccountId: Output only. A POSIX account identifier. + AccountId string `json:"accountId,omitempty"` + + // Gecos: The GECOS (user information) entry for this account. + Gecos string `json:"gecos,omitempty"` + + // Gid: The default group ID. + Gid int64 `json:"gid,omitempty,string"` + + // HomeDirectory: The path to the home directory for this account. + HomeDirectory string `json:"homeDirectory,omitempty"` + + // Name: Output only. The canonical resource name. + Name string `json:"name,omitempty"` + + // OperatingSystemType: The operating system type where this account + // applies. + // + // Possible values: + // "OPERATING_SYSTEM_TYPE_UNSPECIFIED" - The operating system type + // associated with the user account information is + // unspecified. + // "LINUX" - Linux user account information. + // "WINDOWS" - Windows user account information. + OperatingSystemType string `json:"operatingSystemType,omitempty"` + + // Primary: Only one POSIX account can be marked as primary. + Primary bool `json:"primary,omitempty"` + + // Shell: The path to the logic shell for this account. + Shell string `json:"shell,omitempty"` + + // SystemId: System identifier for which account the username or uid + // applies to. + // By default, the empty value is used. + SystemId string `json:"systemId,omitempty"` + + // Uid: The user ID. + Uid int64 `json:"uid,omitempty,string"` + + // Username: The username of the POSIX account. + Username string `json:"username,omitempty"` + + // ForceSendFields is a list of field names (e.g. "AccountId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "AccountId") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *PosixAccount) MarshalJSON() ([]byte, error) { + type NoMethod PosixAccount + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// SshPublicKey: The SSH public key information associated with a Google +// account. +type SshPublicKey struct { + // ExpirationTimeUsec: An expiration time in microseconds since epoch. + ExpirationTimeUsec int64 `json:"expirationTimeUsec,omitempty,string"` + + // Fingerprint: Output only. The SHA-256 fingerprint of the SSH public + // key. + Fingerprint string `json:"fingerprint,omitempty"` + + // Key: Public key text in SSH format, defined by + // RFC4253 + // section 6.6. + Key string `json:"key,omitempty"` + + // Name: Output only. The canonical resource name. + Name string `json:"name,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "ExpirationTimeUsec") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ExpirationTimeUsec") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *SshPublicKey) MarshalJSON() ([]byte, error) { + type NoMethod SshPublicKey + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// method id "oslogin.users.getLoginProfile": + +type UsersGetLoginProfileCall struct { + s *Service + name string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// GetLoginProfile: Retrieves the profile information used for logging +// in to a virtual machine +// on Google Compute Engine. +func (r *UsersService) GetLoginProfile(name string) *UsersGetLoginProfileCall { + c := &UsersGetLoginProfileCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.name = name + return c +} + +// ProjectId sets the optional parameter "projectId": The project ID of +// the Google Cloud Platform project. +func (c *UsersGetLoginProfileCall) ProjectId(projectId string) *UsersGetLoginProfileCall { + c.urlParams_.Set("projectId", projectId) + return c +} + +// SystemId sets the optional parameter "systemId": A system ID for +// filtering the results of the request. +func (c *UsersGetLoginProfileCall) SystemId(systemId string) *UsersGetLoginProfileCall { + c.urlParams_.Set("systemId", systemId) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UsersGetLoginProfileCall) Fields(s ...googleapi.Field) *UsersGetLoginProfileCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *UsersGetLoginProfileCall) IfNoneMatch(entityTag string) *UsersGetLoginProfileCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UsersGetLoginProfileCall) Context(ctx context.Context) *UsersGetLoginProfileCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UsersGetLoginProfileCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UsersGetLoginProfileCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/loginProfile") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "name": c.name, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oslogin.users.getLoginProfile" call. +// Exactly one of *LoginProfile or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *LoginProfile.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *UsersGetLoginProfileCall) Do(opts ...googleapi.CallOption) (*LoginProfile, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &LoginProfile{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves the profile information used for logging in to a virtual machine\non Google Compute Engine.", + // "flatPath": "v1/users/{usersId}/loginProfile", + // "httpMethod": "GET", + // "id": "oslogin.users.getLoginProfile", + // "parameterOrder": [ + // "name" + // ], + // "parameters": { + // "name": { + // "description": "Required. The unique ID for the user in format `users/{user}`.", + // "location": "path", + // "pattern": "^users/[^/]+$", + // "required": true, + // "type": "string" + // }, + // "projectId": { + // "description": "The project ID of the Google Cloud Platform project.", + // "location": "query", + // "type": "string" + // }, + // "systemId": { + // "description": "A system ID for filtering the results of the request.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "v1/{+name}/loginProfile", + // "response": { + // "$ref": "LoginProfile" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/compute" + // ] + // } + +} + +// method id "oslogin.users.importSshPublicKey": + +type UsersImportSshPublicKeyCall struct { + s *Service + parent string + sshpublickey *SshPublicKey + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// ImportSshPublicKey: Adds an SSH public key and returns the profile +// information. Default POSIX +// account information is set when no username and UID exist as part of +// the +// login profile. +func (r *UsersService) ImportSshPublicKey(parent string, sshpublickey *SshPublicKey) *UsersImportSshPublicKeyCall { + c := &UsersImportSshPublicKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.parent = parent + c.sshpublickey = sshpublickey + return c +} + +// ProjectId sets the optional parameter "projectId": The project ID of +// the Google Cloud Platform project. +func (c *UsersImportSshPublicKeyCall) ProjectId(projectId string) *UsersImportSshPublicKeyCall { + c.urlParams_.Set("projectId", projectId) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UsersImportSshPublicKeyCall) Fields(s ...googleapi.Field) *UsersImportSshPublicKeyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UsersImportSshPublicKeyCall) Context(ctx context.Context) *UsersImportSshPublicKeyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UsersImportSshPublicKeyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UsersImportSshPublicKeyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.sshpublickey) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:importSshPublicKey") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "parent": c.parent, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oslogin.users.importSshPublicKey" call. +// Exactly one of *ImportSshPublicKeyResponse or error will be non-nil. +// Any non-2xx status code is an error. Response headers are in either +// *ImportSshPublicKeyResponse.ServerResponse.Header or (if a response +// was returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *UsersImportSshPublicKeyCall) Do(opts ...googleapi.CallOption) (*ImportSshPublicKeyResponse, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ImportSshPublicKeyResponse{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Adds an SSH public key and returns the profile information. Default POSIX\naccount information is set when no username and UID exist as part of the\nlogin profile.", + // "flatPath": "v1/users/{usersId}:importSshPublicKey", + // "httpMethod": "POST", + // "id": "oslogin.users.importSshPublicKey", + // "parameterOrder": [ + // "parent" + // ], + // "parameters": { + // "parent": { + // "description": "Required. The unique ID for the user in format `users/{user}`.", + // "location": "path", + // "pattern": "^users/[^/]+$", + // "required": true, + // "type": "string" + // }, + // "projectId": { + // "description": "The project ID of the Google Cloud Platform project.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "v1/{+parent}:importSshPublicKey", + // "request": { + // "$ref": "SshPublicKey" + // }, + // "response": { + // "$ref": "ImportSshPublicKeyResponse" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/compute" + // ] + // } + +} + +// method id "oslogin.users.projects.delete": + +type UsersProjectsDeleteCall struct { + s *Service + name string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Deletes a POSIX account. +func (r *UsersProjectsService) Delete(name string) *UsersProjectsDeleteCall { + c := &UsersProjectsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.name = name + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UsersProjectsDeleteCall) Fields(s ...googleapi.Field) *UsersProjectsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UsersProjectsDeleteCall) Context(ctx context.Context) *UsersProjectsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UsersProjectsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UsersProjectsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "name": c.name, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oslogin.users.projects.delete" call. +// Exactly one of *Empty or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Empty.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *UsersProjectsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Empty{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Deletes a POSIX account.", + // "flatPath": "v1/users/{usersId}/projects/{projectsId}", + // "httpMethod": "DELETE", + // "id": "oslogin.users.projects.delete", + // "parameterOrder": [ + // "name" + // ], + // "parameters": { + // "name": { + // "description": "Required. A reference to the POSIX account to update. POSIX accounts are identified\nby the project ID they are associated with. A reference to the POSIX\naccount is in format `users/{user}/projects/{project}`.", + // "location": "path", + // "pattern": "^users/[^/]+/projects/[^/]+$", + // "required": true, + // "type": "string" + // } + // }, + // "path": "v1/{+name}", + // "response": { + // "$ref": "Empty" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/compute" + // ] + // } + +} + +// method id "oslogin.users.sshPublicKeys.delete": + +type UsersSshPublicKeysDeleteCall struct { + s *Service + name string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Deletes an SSH public key. +func (r *UsersSshPublicKeysService) Delete(name string) *UsersSshPublicKeysDeleteCall { + c := &UsersSshPublicKeysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.name = name + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UsersSshPublicKeysDeleteCall) Fields(s ...googleapi.Field) *UsersSshPublicKeysDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UsersSshPublicKeysDeleteCall) Context(ctx context.Context) *UsersSshPublicKeysDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UsersSshPublicKeysDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UsersSshPublicKeysDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "name": c.name, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oslogin.users.sshPublicKeys.delete" call. +// Exactly one of *Empty or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Empty.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *UsersSshPublicKeysDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Empty{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Deletes an SSH public key.", + // "flatPath": "v1/users/{usersId}/sshPublicKeys/{sshPublicKeysId}", + // "httpMethod": "DELETE", + // "id": "oslogin.users.sshPublicKeys.delete", + // "parameterOrder": [ + // "name" + // ], + // "parameters": { + // "name": { + // "description": "Required. The fingerprint of the public key to update. Public keys are identified by\ntheir SHA-256 fingerprint. The fingerprint of the public key is in format\n`users/{user}/sshPublicKeys/{fingerprint}`.", + // "location": "path", + // "pattern": "^users/[^/]+/sshPublicKeys/[^/]+$", + // "required": true, + // "type": "string" + // } + // }, + // "path": "v1/{+name}", + // "response": { + // "$ref": "Empty" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/compute" + // ] + // } + +} + +// method id "oslogin.users.sshPublicKeys.get": + +type UsersSshPublicKeysGetCall struct { + s *Service + name string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Retrieves an SSH public key. +func (r *UsersSshPublicKeysService) Get(name string) *UsersSshPublicKeysGetCall { + c := &UsersSshPublicKeysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.name = name + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UsersSshPublicKeysGetCall) Fields(s ...googleapi.Field) *UsersSshPublicKeysGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *UsersSshPublicKeysGetCall) IfNoneMatch(entityTag string) *UsersSshPublicKeysGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UsersSshPublicKeysGetCall) Context(ctx context.Context) *UsersSshPublicKeysGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UsersSshPublicKeysGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UsersSshPublicKeysGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "name": c.name, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oslogin.users.sshPublicKeys.get" call. +// Exactly one of *SshPublicKey or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *SshPublicKey.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *UsersSshPublicKeysGetCall) Do(opts ...googleapi.CallOption) (*SshPublicKey, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &SshPublicKey{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves an SSH public key.", + // "flatPath": "v1/users/{usersId}/sshPublicKeys/{sshPublicKeysId}", + // "httpMethod": "GET", + // "id": "oslogin.users.sshPublicKeys.get", + // "parameterOrder": [ + // "name" + // ], + // "parameters": { + // "name": { + // "description": "Required. The fingerprint of the public key to retrieve. Public keys are identified\nby their SHA-256 fingerprint. The fingerprint of the public key is in\nformat `users/{user}/sshPublicKeys/{fingerprint}`.", + // "location": "path", + // "pattern": "^users/[^/]+/sshPublicKeys/[^/]+$", + // "required": true, + // "type": "string" + // } + // }, + // "path": "v1/{+name}", + // "response": { + // "$ref": "SshPublicKey" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/compute" + // ] + // } + +} + +// method id "oslogin.users.sshPublicKeys.patch": + +type UsersSshPublicKeysPatchCall struct { + s *Service + name string + sshpublickey *SshPublicKey + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Updates an SSH public key and returns the profile information. +// This method +// supports patch semantics. +func (r *UsersSshPublicKeysService) Patch(name string, sshpublickey *SshPublicKey) *UsersSshPublicKeysPatchCall { + c := &UsersSshPublicKeysPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.name = name + c.sshpublickey = sshpublickey + return c +} + +// UpdateMask sets the optional parameter "updateMask": Mask to control +// which fields get updated. Updates all if not present. +func (c *UsersSshPublicKeysPatchCall) UpdateMask(updateMask string) *UsersSshPublicKeysPatchCall { + c.urlParams_.Set("updateMask", updateMask) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *UsersSshPublicKeysPatchCall) Fields(s ...googleapi.Field) *UsersSshPublicKeysPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *UsersSshPublicKeysPatchCall) Context(ctx context.Context) *UsersSshPublicKeysPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *UsersSshPublicKeysPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *UsersSshPublicKeysPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317") + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.sshpublickey) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PATCH", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "name": c.name, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "oslogin.users.sshPublicKeys.patch" call. +// Exactly one of *SshPublicKey or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *SshPublicKey.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *UsersSshPublicKeysPatchCall) Do(opts ...googleapi.CallOption) (*SshPublicKey, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &SshPublicKey{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an SSH public key and returns the profile information. This method\nsupports patch semantics.", + // "flatPath": "v1/users/{usersId}/sshPublicKeys/{sshPublicKeysId}", + // "httpMethod": "PATCH", + // "id": "oslogin.users.sshPublicKeys.patch", + // "parameterOrder": [ + // "name" + // ], + // "parameters": { + // "name": { + // "description": "Required. The fingerprint of the public key to update. Public keys are identified by\ntheir SHA-256 fingerprint. The fingerprint of the public key is in format\n`users/{user}/sshPublicKeys/{fingerprint}`.", + // "location": "path", + // "pattern": "^users/[^/]+/sshPublicKeys/[^/]+$", + // "required": true, + // "type": "string" + // }, + // "updateMask": { + // "description": "Mask to control which fields get updated. Updates all if not present.", + // "format": "google-fieldmask", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "v1/{+name}", + // "request": { + // "$ref": "SshPublicKey" + // }, + // "response": { + // "$ref": "SshPublicKey" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/compute" + // ] + // } + +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 618910dd0..bc9f7b1b9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -800,8 +800,10 @@ google.golang.org/api/internal google.golang.org/api/internal/gensupport google.golang.org/api/internal/third_party/uritemplates google.golang.org/api/iterator +google.golang.org/api/oauth2/v2 google.golang.org/api/option google.golang.org/api/option/internaloption +google.golang.org/api/oslogin/v1 google.golang.org/api/storage/v1 google.golang.org/api/transport/cert google.golang.org/api/transport/http diff --git a/website/pages/partials/builder/googlecompute/Config-not-required.mdx b/website/pages/partials/builder/googlecompute/Config-not-required.mdx index d33a72d04..a2d267c91 100644 --- a/website/pages/partials/builder/googlecompute/Config-not-required.mdx +++ b/website/pages/partials/builder/googlecompute/Config-not-required.mdx @@ -176,6 +176,50 @@ - `use_internal_ip` (bool) - If true, use the instance's internal IP instead of its external IP during building. +- `use_os_login` (bool) - If true, OSLogin will be used to manage SSH access to the compute instance by + dynamically importing a temporary SSH key to the Google account's login profile, + and setting the `enable-oslogin` to `TRUE` in the instance metadata. + Optionally, `use_os_login` can be used with an existing `ssh_username` and `ssh_private_key_file` + if a SSH key has already been added to the Google account's login profile - See [Adding SSH Keys](https://cloud.google.com/compute/docs/instances/managing-instance-access#add_oslogin_keys). + + SSH keys can be added to an individual user account + + ```shell-session + $ gcloud compute os-login ssh-keys add --key-file=/home/user/.ssh/my-key.pub + + $ gcloud compute os-login describe-profile + PosixAccounts: + - accountId: + gid: '34567890754' + homeDirectory: /home/user_example_com + ... + primary: true + uid: '2504818925' + username: /home/user_example_com + sshPublicKeys: + 000000000000000000000000000000000000000000000000000000000000000a: + fingerprint: 000000000000000000000000000000000000000000000000000000000000000a + ``` + + Or SSH keys can be added to an associated service account + ```shell-session + $ gcloud auth activate-service-account --key-file= + $ gcloud compute os-login ssh-keys add --key-file=/home/user/.ssh/my-key.pub + + $ gcloud compute os-login describe-profile + PosixAccounts: + - accountId: + gid: '34567890754' + homeDirectory: /home/sa_000000000000000000000 + ... + primary: true + uid: '2504818925' + username: sa_000000000000000000000 + sshPublicKeys: + 000000000000000000000000000000000000000000000000000000000000000a: + fingerprint: 000000000000000000000000000000000000000000000000000000000000000a + ``` + - `vault_gcp_oauth_engine` (string) - Can be set instead of account_file. If set, this builder will use HashiCorp Vault to generate an Oauth token for authenticating against Google's cloud. The value should be the path of the token generator