github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/gce/google/testing_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package google
     5  
     6  import (
     7  	jujuhttp "github.com/juju/http/v2"
     8  	"google.golang.org/api/compute/v1"
     9  	gc "gopkg.in/check.v1"
    10  
    11  	"github.com/juju/juju/core/network"
    12  	"github.com/juju/juju/testing"
    13  )
    14  
    15  type BaseSuite struct {
    16  	testing.BaseSuite
    17  
    18  	Credentials *Credentials
    19  	ConnCfg     ConnectionConfig
    20  	Conn        *Connection
    21  	FakeConn    *fakeConn
    22  
    23  	DiskSpec         DiskSpec
    24  	AttachedDisk     compute.AttachedDisk
    25  	NetworkSpec      NetworkSpec
    26  	NetworkInterface compute.NetworkInterface
    27  	Addresses        network.ProviderAddresses
    28  	RawMetadata      compute.Metadata
    29  	Metadata         map[string]string
    30  	RawInstance      compute.Instance
    31  	RawInstanceFull  compute.Instance
    32  	InstanceSpec     InstanceSpec
    33  	Instance         Instance
    34  }
    35  
    36  var _ = gc.Suite(&BaseSuite{})
    37  
    38  func (s *BaseSuite) SetUpTest(c *gc.C) {
    39  	s.BaseSuite.SetUpTest(c)
    40  
    41  	s.Credentials = &Credentials{
    42  		ClientID:    "spam",
    43  		ClientEmail: "user@mail.com",
    44  		PrivateKey:  []byte("<some-key>"),
    45  		JSONKey: []byte(`
    46  {
    47      "private_key_id": "mnopq",
    48      "private_key": "<some-key>",
    49      "client_email": "user@mail.com",
    50      "client_id": "spam",
    51      "type": "service_account"
    52  }`[1:]),
    53  	}
    54  	s.ConnCfg = ConnectionConfig{
    55  		Region:     "a",
    56  		ProjectID:  "spam",
    57  		HTTPClient: jujuhttp.NewClient(),
    58  	}
    59  	fake := &fakeConn{}
    60  	s.Conn = &Connection{
    61  		service:   fake,
    62  		region:    "a",
    63  		projectID: "spam",
    64  	}
    65  	s.FakeConn = fake
    66  
    67  	s.DiskSpec = DiskSpec{
    68  		OS:         "ubuntu",
    69  		SizeHintGB: 15,
    70  		ImageURL:   "some/image/path",
    71  		Boot:       true,
    72  		Scratch:    false,
    73  		Readonly:   false,
    74  		AutoDelete: true,
    75  	}
    76  	s.AttachedDisk = compute.AttachedDisk{
    77  		Type:       "PERSISTENT",
    78  		Boot:       true,
    79  		Mode:       "READ_WRITE",
    80  		AutoDelete: true,
    81  		InitializeParams: &compute.AttachedDiskInitializeParams{
    82  			DiskSizeGb:  10,
    83  			SourceImage: "some/image/path",
    84  		},
    85  	}
    86  	s.NetworkSpec = NetworkSpec{
    87  		Name: "somenetwork",
    88  	}
    89  	s.NetworkInterface = compute.NetworkInterface{
    90  		Network:   "global/networks/somenetwork",
    91  		NetworkIP: "10.0.0.1",
    92  		AccessConfigs: []*compute.AccessConfig{{
    93  			Name: "somenetif",
    94  			Type: NetworkAccessOneToOneNAT,
    95  		}},
    96  	}
    97  	s.Addresses = []network.ProviderAddress{
    98  		network.NewMachineAddress("10.0.0.1", network.WithScope(network.ScopeCloudLocal)).AsProviderAddress(),
    99  	}
   100  	s.RawMetadata = compute.Metadata{
   101  		Items: []*compute.MetadataItems{{
   102  			Key:   "eggs",
   103  			Value: StringPtr("steak"),
   104  		}},
   105  		Fingerprint: "heymumwatchthis",
   106  	}
   107  	s.Metadata = map[string]string{
   108  		"eggs": "steak",
   109  	}
   110  	s.RawInstance = compute.Instance{
   111  		Name:              "spam",
   112  		Status:            StatusRunning,
   113  		NetworkInterfaces: []*compute.NetworkInterface{&s.NetworkInterface},
   114  		Metadata:          &s.RawMetadata,
   115  		Disks:             []*compute.AttachedDisk{&s.AttachedDisk},
   116  		Tags:              &compute.Tags{Items: []string{"spam"}},
   117  	}
   118  	s.RawInstanceFull = s.RawInstance
   119  	s.RawInstanceFull.Zone = "a-zone"
   120  	s.RawInstanceFull.Status = StatusRunning
   121  	s.RawInstanceFull.MachineType = "zones/a-zone/machineTypes/mtype"
   122  	s.InstanceSpec = InstanceSpec{
   123  		ID:                "spam",
   124  		Type:              "mtype",
   125  		Disks:             []DiskSpec{s.DiskSpec},
   126  		Network:           s.NetworkSpec,
   127  		NetworkInterfaces: []string{"somenetif"},
   128  		Metadata:          s.Metadata,
   129  		Tags:              []string{"spam"},
   130  		AvailabilityZone:  "a-zone",
   131  		AllocatePublicIP:  true,
   132  	}
   133  	s.Instance = Instance{
   134  		InstanceSummary: InstanceSummary{
   135  			ID:                "spam",
   136  			ZoneName:          "a-zone",
   137  			Status:            StatusRunning,
   138  			Metadata:          s.Metadata,
   139  			Addresses:         s.Addresses,
   140  			NetworkInterfaces: s.RawInstance.NetworkInterfaces,
   141  		},
   142  		spec: &s.InstanceSpec,
   143  	}
   144  }
   145  
   146  func (s *BaseSuite) NewWaitError(op *compute.Operation, cause error) error {
   147  	return waitError{op, cause}
   148  }
   149  
   150  func StringPtr(val string) *string {
   151  	return &val
   152  }
   153  
   154  type fakeCall struct {
   155  	FuncName string
   156  
   157  	ProjectID        string
   158  	Region           string
   159  	ZoneName         string
   160  	Name             string
   161  	ID               string
   162  	Prefix           string
   163  	Statuses         []string
   164  	Instance         *compute.Instance
   165  	InstValue        compute.Instance
   166  	Firewall         *compute.Firewall
   167  	InstanceId       string
   168  	AttachedDisk     *compute.AttachedDisk
   169  	DeviceName       string
   170  	ComputeDisk      *compute.Disk
   171  	Metadata         *compute.Metadata
   172  	LabelFingerprint string
   173  	Labels           map[string]string
   174  }
   175  
   176  type fakeConn struct {
   177  	Calls []fakeCall
   178  
   179  	Project       *compute.Project
   180  	Instance      *compute.Instance
   181  	Instances     []*compute.Instance
   182  	Firewalls     []*compute.Firewall
   183  	Zones         []*compute.Zone
   184  	Err           error
   185  	FailOnCall    int
   186  	Disks         []*compute.Disk
   187  	Disk          *compute.Disk
   188  	AttachedDisks []*compute.AttachedDisk
   189  	Networks      []*compute.Network
   190  	Subnetworks   []*compute.Subnetwork
   191  }
   192  
   193  func (rc *fakeConn) GetProject(projectID string) (*compute.Project, error) {
   194  	call := fakeCall{
   195  		FuncName:  "GetProject",
   196  		ProjectID: projectID,
   197  	}
   198  	rc.Calls = append(rc.Calls, call)
   199  
   200  	err := rc.Err
   201  	if len(rc.Calls) != rc.FailOnCall+1 {
   202  		err = nil
   203  	}
   204  	return rc.Project, err
   205  }
   206  
   207  func (rc *fakeConn) GetInstance(projectID, zone, id string) (*compute.Instance, error) {
   208  	call := fakeCall{
   209  		FuncName:  "GetInstance",
   210  		ProjectID: projectID,
   211  		ZoneName:  zone,
   212  		ID:        id,
   213  	}
   214  	rc.Calls = append(rc.Calls, call)
   215  
   216  	err := rc.Err
   217  	if len(rc.Calls) != rc.FailOnCall+1 {
   218  		err = nil
   219  	}
   220  	return rc.Instance, err
   221  }
   222  
   223  func (rc *fakeConn) ListInstances(projectID, prefix string, statuses ...string) ([]*compute.Instance, error) {
   224  	call := fakeCall{
   225  		FuncName:  "ListInstances",
   226  		ProjectID: projectID,
   227  		Prefix:    prefix,
   228  		Statuses:  statuses,
   229  	}
   230  	rc.Calls = append(rc.Calls, call)
   231  
   232  	err := rc.Err
   233  	if len(rc.Calls) != rc.FailOnCall+1 {
   234  		err = nil
   235  	}
   236  	return rc.Instances, err
   237  }
   238  
   239  func (rc *fakeConn) AddInstance(projectID, zoneName string, spec *compute.Instance) error {
   240  	call := fakeCall{
   241  		FuncName:  "AddInstance",
   242  		ProjectID: projectID,
   243  		ZoneName:  zoneName,
   244  		Instance:  spec,
   245  		InstValue: *spec,
   246  	}
   247  	rc.Calls = append(rc.Calls, call)
   248  
   249  	err := rc.Err
   250  	if len(rc.Calls) != rc.FailOnCall+1 {
   251  		err = nil
   252  	}
   253  	return err
   254  }
   255  
   256  func (rc *fakeConn) RemoveInstance(projectID, zone, id string) error {
   257  	call := fakeCall{
   258  		FuncName:  "RemoveInstance",
   259  		ProjectID: projectID,
   260  		ID:        id,
   261  		ZoneName:  zone,
   262  	}
   263  	rc.Calls = append(rc.Calls, call)
   264  
   265  	err := rc.Err
   266  	if len(rc.Calls) != rc.FailOnCall+1 {
   267  		err = nil
   268  	}
   269  	return err
   270  }
   271  
   272  func (rc *fakeConn) GetFirewalls(projectID, name string) ([]*compute.Firewall, error) {
   273  	call := fakeCall{
   274  		FuncName:  "GetFirewalls",
   275  		ProjectID: projectID,
   276  		Name:      name,
   277  	}
   278  	rc.Calls = append(rc.Calls, call)
   279  
   280  	err := rc.Err
   281  	if len(rc.Calls) != rc.FailOnCall+1 {
   282  		err = nil
   283  	}
   284  	return rc.Firewalls, err
   285  }
   286  
   287  func (rc *fakeConn) AddFirewall(projectID string, firewall *compute.Firewall) error {
   288  	call := fakeCall{
   289  		FuncName:  "AddFirewall",
   290  		ProjectID: projectID,
   291  		Firewall:  firewall,
   292  	}
   293  	rc.Calls = append(rc.Calls, call)
   294  
   295  	err := rc.Err
   296  	if len(rc.Calls) != rc.FailOnCall+1 {
   297  		err = nil
   298  	}
   299  	return err
   300  }
   301  
   302  func (rc *fakeConn) UpdateFirewall(projectID, name string, firewall *compute.Firewall) error {
   303  	call := fakeCall{
   304  		FuncName:  "UpdateFirewall",
   305  		ProjectID: projectID,
   306  		Name:      name,
   307  		Firewall:  firewall,
   308  	}
   309  	rc.Calls = append(rc.Calls, call)
   310  
   311  	err := rc.Err
   312  	if len(rc.Calls) != rc.FailOnCall+1 {
   313  		err = nil
   314  	}
   315  	return err
   316  }
   317  
   318  func (rc *fakeConn) RemoveFirewall(projectID, name string) error {
   319  	call := fakeCall{
   320  		FuncName:  "RemoveFirewall",
   321  		ProjectID: projectID,
   322  		Name:      name,
   323  	}
   324  	rc.Calls = append(rc.Calls, call)
   325  
   326  	err := rc.Err
   327  	if len(rc.Calls) != rc.FailOnCall+1 {
   328  		err = nil
   329  	}
   330  	return err
   331  }
   332  
   333  func (rc *fakeConn) ListAvailabilityZones(projectID, region string) ([]*compute.Zone, error) {
   334  	call := fakeCall{
   335  		FuncName:  "ListAvailabilityZones",
   336  		ProjectID: projectID,
   337  		Region:    region,
   338  	}
   339  	rc.Calls = append(rc.Calls, call)
   340  
   341  	err := rc.Err
   342  	if len(rc.Calls) != rc.FailOnCall+1 {
   343  		err = nil
   344  	}
   345  	return rc.Zones, err
   346  }
   347  
   348  func (rc *fakeConn) CreateDisk(project, zone string, spec *compute.Disk) error {
   349  	call := fakeCall{
   350  		FuncName:    "CreateDisk",
   351  		ProjectID:   project,
   352  		ZoneName:    zone,
   353  		ComputeDisk: spec,
   354  	}
   355  	rc.Calls = append(rc.Calls, call)
   356  
   357  	err := rc.Err
   358  	if len(rc.Calls) != rc.FailOnCall+1 {
   359  		err = nil
   360  	}
   361  	return err
   362  }
   363  
   364  func (rc *fakeConn) ListDisks(project string) ([]*compute.Disk, error) {
   365  	call := fakeCall{
   366  		FuncName:  "ListDisks",
   367  		ProjectID: project,
   368  	}
   369  	rc.Calls = append(rc.Calls, call)
   370  
   371  	err := rc.Err
   372  	if len(rc.Calls) != rc.FailOnCall+1 {
   373  		err = nil
   374  	}
   375  	return rc.Disks, err
   376  }
   377  
   378  func (rc *fakeConn) RemoveDisk(project, zone, id string) error {
   379  	call := fakeCall{
   380  		FuncName:  "RemoveDisk",
   381  		ProjectID: project,
   382  		ZoneName:  zone,
   383  		ID:        id,
   384  	}
   385  	rc.Calls = append(rc.Calls, call)
   386  
   387  	err := rc.Err
   388  	if len(rc.Calls) != rc.FailOnCall+1 {
   389  		err = nil
   390  	}
   391  	return err
   392  }
   393  
   394  func (rc *fakeConn) GetDisk(project, zone, id string) (*compute.Disk, error) {
   395  	call := fakeCall{
   396  		FuncName:  "GetDisk",
   397  		ProjectID: project,
   398  		ZoneName:  zone,
   399  		ID:        id,
   400  	}
   401  	rc.Calls = append(rc.Calls, call)
   402  
   403  	err := rc.Err
   404  	if len(rc.Calls) != rc.FailOnCall+1 {
   405  		err = nil
   406  	}
   407  	return rc.Disk, err
   408  }
   409  
   410  func (rc *fakeConn) SetDiskLabels(project, zone, id, labelFingerprint string, labels map[string]string) error {
   411  	call := fakeCall{
   412  		FuncName:         "SetDiskLabels",
   413  		ProjectID:        project,
   414  		ZoneName:         zone,
   415  		ID:               id,
   416  		LabelFingerprint: labelFingerprint,
   417  		Labels:           labels,
   418  	}
   419  	rc.Calls = append(rc.Calls, call)
   420  
   421  	err := rc.Err
   422  	if len(rc.Calls) != rc.FailOnCall+1 {
   423  		err = nil
   424  	}
   425  	return err
   426  }
   427  
   428  func (rc *fakeConn) AttachDisk(project, zone, instanceId string, attachedDisk *compute.AttachedDisk) error {
   429  	call := fakeCall{
   430  		FuncName:     "AttachDisk",
   431  		ProjectID:    project,
   432  		ZoneName:     zone,
   433  		InstanceId:   instanceId,
   434  		AttachedDisk: attachedDisk,
   435  	}
   436  	rc.Calls = append(rc.Calls, call)
   437  
   438  	err := rc.Err
   439  	if len(rc.Calls) != rc.FailOnCall+1 {
   440  		err = nil
   441  	}
   442  	return err
   443  }
   444  
   445  func (rc *fakeConn) DetachDisk(project, zone, instanceId, diskDeviceName string) error {
   446  	call := fakeCall{
   447  		FuncName:   "DetachDisk",
   448  		ProjectID:  project,
   449  		ZoneName:   zone,
   450  		InstanceId: instanceId,
   451  		DeviceName: diskDeviceName,
   452  	}
   453  	rc.Calls = append(rc.Calls, call)
   454  
   455  	err := rc.Err
   456  	if len(rc.Calls) != rc.FailOnCall+1 {
   457  		err = nil
   458  	}
   459  	return err
   460  }
   461  
   462  func (rc *fakeConn) InstanceDisks(project, zone, instanceId string) ([]*compute.AttachedDisk, error) {
   463  	call := fakeCall{
   464  		FuncName:   "InstanceDisks",
   465  		ProjectID:  project,
   466  		ZoneName:   zone,
   467  		InstanceId: instanceId,
   468  	}
   469  	rc.Calls = append(rc.Calls, call)
   470  
   471  	err := rc.Err
   472  	if len(rc.Calls) != rc.FailOnCall+1 {
   473  		err = nil
   474  	}
   475  	return rc.AttachedDisks, err
   476  }
   477  
   478  func (rc *fakeConn) ListMachineTypes(projectID, zone string) (*compute.MachineTypeList, error) {
   479  	call := fakeCall{
   480  		FuncName:  "ListMachineTypes",
   481  		ProjectID: projectID,
   482  		ZoneName:  zone,
   483  	}
   484  	rc.Calls = append(rc.Calls, call)
   485  	machineType := compute.MachineTypeList{
   486  		Items: []*compute.MachineType{
   487  			{Name: "type-1", MemoryMb: 1024},
   488  			{Name: "type-2", MemoryMb: 2048},
   489  		},
   490  	}
   491  	return &machineType, nil
   492  
   493  }
   494  
   495  func (rc *fakeConn) SetMetadata(projectID, zone, instanceID string, metadata *compute.Metadata) error {
   496  	call := fakeCall{
   497  		FuncName:   "SetMetadata",
   498  		ProjectID:  projectID,
   499  		ZoneName:   zone,
   500  		InstanceId: instanceID,
   501  		Metadata:   metadata,
   502  	}
   503  	rc.Calls = append(rc.Calls, call)
   504  
   505  	err := rc.Err
   506  	if len(rc.Calls) != rc.FailOnCall+1 {
   507  		err = nil
   508  	}
   509  	return err
   510  }
   511  
   512  func (rc *fakeConn) ListNetworks(projectID string) ([]*compute.Network, error) {
   513  	call := fakeCall{
   514  		FuncName:  "ListNetworks",
   515  		ProjectID: projectID,
   516  	}
   517  	rc.Calls = append(rc.Calls, call)
   518  
   519  	err := rc.Err
   520  	if len(rc.Calls) != rc.FailOnCall+1 {
   521  		err = nil
   522  	}
   523  	if err != nil {
   524  		return nil, err
   525  	}
   526  	return rc.Networks, nil
   527  }
   528  
   529  func (rc *fakeConn) ListSubnetworks(projectID, region string) ([]*compute.Subnetwork, error) {
   530  	call := fakeCall{
   531  		FuncName:  "ListSubnetworks",
   532  		ProjectID: projectID,
   533  		Region:    region,
   534  	}
   535  	rc.Calls = append(rc.Calls, call)
   536  
   537  	err := rc.Err
   538  	if len(rc.Calls) != rc.FailOnCall+1 {
   539  		err = nil
   540  	}
   541  	if err != nil {
   542  		return nil, err
   543  	}
   544  	return rc.Subnetworks, nil
   545  }