github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/modelstatus_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/loggo"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/apiserver/common"
    13  	"github.com/juju/juju/apiserver/facade/facadetest"
    14  	"github.com/juju/juju/apiserver/facades/client/controller"
    15  	"github.com/juju/juju/apiserver/params"
    16  	apiservertesting "github.com/juju/juju/apiserver/testing"
    17  	"github.com/juju/juju/core/constraints"
    18  	"github.com/juju/juju/core/instance"
    19  	"github.com/juju/juju/environs"
    20  	"github.com/juju/juju/environs/config"
    21  	"github.com/juju/juju/environs/context"
    22  	"github.com/juju/juju/provider/dummy"
    23  	"github.com/juju/juju/state"
    24  	statetesting "github.com/juju/juju/state/testing"
    25  	"github.com/juju/juju/storage"
    26  	"github.com/juju/juju/storage/provider"
    27  	"github.com/juju/juju/testing"
    28  	"github.com/juju/juju/testing/factory"
    29  )
    30  
    31  type modelStatusSuite struct {
    32  	statetesting.StateSuite
    33  
    34  	controller *controller.ControllerAPI
    35  	resources  *common.Resources
    36  	authorizer apiservertesting.FakeAuthorizer
    37  }
    38  
    39  var _ = gc.Suite(&modelStatusSuite{})
    40  
    41  func (s *modelStatusSuite) SetUpTest(c *gc.C) {
    42  	// Initial config needs to be set before the StateSuite SetUpTest.
    43  	s.InitialConfig = testing.CustomModelConfig(c, testing.Attrs{
    44  		"name": "controller",
    45  	})
    46  	s.NewPolicy = func(*state.State) state.Policy {
    47  		return statePolicy{}
    48  	}
    49  
    50  	s.StateSuite.SetUpTest(c)
    51  	s.resources = common.NewResources()
    52  	s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() })
    53  
    54  	s.authorizer = apiservertesting.FakeAuthorizer{
    55  		Tag:      s.Owner,
    56  		AdminTag: s.Owner,
    57  	}
    58  
    59  	controller, err := controller.NewControllerAPIv7(
    60  		facadetest.Context{
    61  			State_:     s.State,
    62  			Resources_: s.resources,
    63  			Auth_:      s.authorizer,
    64  			StatePool_: s.StatePool,
    65  		})
    66  	c.Assert(err, jc.ErrorIsNil)
    67  	s.controller = controller
    68  
    69  	loggo.GetLogger("juju.apiserver.controller").SetLogLevel(loggo.TRACE)
    70  }
    71  
    72  func (s *modelStatusSuite) TestModelStatusNonAuth(c *gc.C) {
    73  	// Set up the user making the call.
    74  	user := s.Factory.MakeUser(c, &factory.UserParams{NoModelUser: true})
    75  	anAuthoriser := apiservertesting.FakeAuthorizer{
    76  		Tag: user.Tag(),
    77  	}
    78  	endpoint, err := controller.NewControllerAPIv6(
    79  		facadetest.Context{
    80  			State_:     s.State,
    81  			Resources_: s.resources,
    82  			Auth_:      anAuthoriser,
    83  		})
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	controllerModelTag := s.Model.ModelTag().String()
    86  
    87  	req := params.Entities{
    88  		Entities: []params.Entity{{Tag: controllerModelTag}},
    89  	}
    90  	result, err := endpoint.ModelStatus(req)
    91  	c.Assert(err, jc.ErrorIsNil)
    92  	c.Assert(result.Results[0].Error, gc.ErrorMatches, "permission denied")
    93  }
    94  
    95  func (s *modelStatusSuite) TestModelStatusOwnerAllowed(c *gc.C) {
    96  	// Set up the user making the call.
    97  	owner := s.Factory.MakeUser(c, nil)
    98  	anAuthoriser := apiservertesting.FakeAuthorizer{
    99  		Tag: owner.Tag(),
   100  	}
   101  	st := s.Factory.MakeModel(c, &factory.ModelParams{Owner: owner.Tag()})
   102  	defer st.Close()
   103  	endpoint, err := controller.NewControllerAPIv6(
   104  		facadetest.Context{
   105  			State_:     s.State,
   106  			Resources_: s.resources,
   107  			Auth_:      anAuthoriser,
   108  			StatePool_: s.StatePool,
   109  		})
   110  	c.Assert(err, jc.ErrorIsNil)
   111  
   112  	model, err := st.Model()
   113  	c.Assert(err, jc.ErrorIsNil)
   114  	req := params.Entities{
   115  		Entities: []params.Entity{{Tag: model.ModelTag().String()}},
   116  	}
   117  	_, err = endpoint.ModelStatus(req)
   118  	c.Assert(err, jc.ErrorIsNil)
   119  }
   120  
   121  func (s *modelStatusSuite) TestModelStatus(c *gc.C) {
   122  	otherModelOwner := s.Factory.MakeModelUser(c, nil)
   123  	otherSt := s.Factory.MakeModel(c, &factory.ModelParams{
   124  		Name:  "dummytoo",
   125  		Owner: otherModelOwner.UserTag,
   126  		ConfigAttrs: testing.Attrs{
   127  			"controller": false,
   128  		},
   129  	})
   130  	defer otherSt.Close()
   131  
   132  	eight := uint64(8)
   133  	s.Factory.MakeMachine(c, &factory.MachineParams{
   134  		Jobs:            []state.MachineJob{state.JobManageModel},
   135  		Characteristics: &instance.HardwareCharacteristics{CpuCores: &eight},
   136  		InstanceId:      "id-4",
   137  		DisplayName:     "snowflake",
   138  		Volumes: []state.HostVolumeParams{{
   139  			Volume: state.VolumeParams{
   140  				Pool: "modelscoped",
   141  				Size: 123,
   142  			},
   143  		}},
   144  	})
   145  	s.Factory.MakeMachine(c, &factory.MachineParams{
   146  		Jobs:       []state.MachineJob{state.JobHostUnits},
   147  		InstanceId: "id-5",
   148  		Filesystems: []state.HostFilesystemParams{{
   149  			Filesystem: state.FilesystemParams{
   150  				Pool: "modelscoped",
   151  				Size: 123,
   152  			},
   153  		}, {
   154  			Filesystem: state.FilesystemParams{
   155  				Pool: "machinescoped",
   156  				Size: 123,
   157  			},
   158  		}},
   159  	})
   160  	s.Factory.MakeApplication(c, &factory.ApplicationParams{
   161  		Charm: s.Factory.MakeCharm(c, nil),
   162  	})
   163  
   164  	otherFactory := factory.NewFactory(otherSt, s.StatePool)
   165  	otherFactory.MakeMachine(c, &factory.MachineParams{InstanceId: "id-8"})
   166  	otherFactory.MakeMachine(c, &factory.MachineParams{InstanceId: "id-9"})
   167  	otherFactory.MakeApplication(c, &factory.ApplicationParams{
   168  		Charm: otherFactory.MakeCharm(c, nil),
   169  	})
   170  
   171  	otherModel, err := otherSt.Model()
   172  	c.Assert(err, jc.ErrorIsNil)
   173  
   174  	controllerModelTag := s.Model.ModelTag().String()
   175  	hostedModelTag := otherModel.ModelTag().String()
   176  
   177  	req := params.Entities{
   178  		Entities: []params.Entity{{Tag: controllerModelTag}, {Tag: hostedModelTag}},
   179  	}
   180  	results, err := s.controller.ModelStatus(req)
   181  	c.Assert(err, jc.ErrorIsNil)
   182  
   183  	arch := "amd64"
   184  	mem := uint64(64 * 1024 * 1024 * 1024)
   185  	stdHw := &params.MachineHardware{
   186  		Arch: &arch,
   187  		Mem:  &mem,
   188  	}
   189  	c.Assert(results.Results, jc.DeepEquals, []params.ModelStatus{
   190  		{
   191  			ModelTag:           controllerModelTag,
   192  			HostedMachineCount: 1,
   193  			ApplicationCount:   1,
   194  			OwnerTag:           s.Owner.String(),
   195  			Life:               params.Alive,
   196  			Machines: []params.ModelMachineInfo{
   197  				{Id: "0", Hardware: &params.MachineHardware{Cores: &eight}, InstanceId: "id-4", DisplayName: "snowflake", Status: "pending", WantsVote: true},
   198  				{Id: "1", Hardware: stdHw, InstanceId: "id-5", Status: "pending"},
   199  			},
   200  			Volumes: []params.ModelVolumeInfo{{
   201  				Id: "0", Status: "pending", Detachable: true,
   202  			}},
   203  			Filesystems: []params.ModelFilesystemInfo{{
   204  				Id: "0", Status: "pending", Detachable: true,
   205  			}, {
   206  				Id: "1/1", Status: "pending", Detachable: false,
   207  			}},
   208  		},
   209  		{
   210  			ModelTag:           hostedModelTag,
   211  			HostedMachineCount: 2,
   212  			ApplicationCount:   1,
   213  			OwnerTag:           otherModelOwner.UserTag.String(),
   214  			Life:               params.Alive,
   215  			Machines: []params.ModelMachineInfo{
   216  				{Id: "0", Hardware: stdHw, InstanceId: "id-8", Status: "pending"},
   217  				{Id: "1", Hardware: stdHw, InstanceId: "id-9", Status: "pending"},
   218  			},
   219  		},
   220  	})
   221  }
   222  
   223  func (s *modelStatusSuite) TestModelStatusCAAS(c *gc.C) {
   224  	otherModelOwner := s.Factory.MakeModelUser(c, nil)
   225  	otherSt := s.Factory.MakeCAASModel(c, &factory.ModelParams{
   226  		Owner: otherModelOwner.UserTag,
   227  		ConfigAttrs: testing.Attrs{
   228  			"controller": false,
   229  		},
   230  	})
   231  	defer otherSt.Close()
   232  
   233  	otherFactory := factory.NewFactory(otherSt, s.StatePool)
   234  	otherFactory.MakeApplication(c, &factory.ApplicationParams{
   235  		Charm: otherFactory.MakeCharm(c, &factory.CharmParams{Name: "gitlab", Series: "kubernetes"}),
   236  	})
   237  
   238  	otherModel, err := otherSt.Model()
   239  	c.Assert(err, jc.ErrorIsNil)
   240  
   241  	controllerModelTag := s.Model.ModelTag().String()
   242  	hostedModelTag := otherModel.ModelTag().String()
   243  
   244  	req := params.Entities{
   245  		Entities: []params.Entity{{Tag: controllerModelTag}, {Tag: hostedModelTag}},
   246  	}
   247  	results, err := s.controller.ModelStatus(req)
   248  	c.Assert(err, jc.ErrorIsNil)
   249  
   250  	c.Assert(results.Results, jc.DeepEquals, []params.ModelStatus{
   251  		{
   252  			ModelTag:           controllerModelTag,
   253  			HostedMachineCount: 0,
   254  			ApplicationCount:   0,
   255  			OwnerTag:           s.Owner.String(),
   256  			Life:               params.Alive,
   257  		},
   258  		{
   259  			ModelTag:           hostedModelTag,
   260  			HostedMachineCount: 0,
   261  			ApplicationCount:   1,
   262  			OwnerTag:           otherModelOwner.UserTag.String(),
   263  			Life:               params.Alive,
   264  		},
   265  	})
   266  }
   267  
   268  func (s *modelStatusSuite) TestModelStatusRunsForAllModels(c *gc.C) {
   269  	req := params.Entities{
   270  		Entities: []params.Entity{
   271  			{Tag: "fail.me"},
   272  			{Tag: s.Model.ModelTag().String()},
   273  		},
   274  	}
   275  	expected := params.ModelStatusResults{
   276  		Results: []params.ModelStatus{
   277  			{
   278  				Error: common.ServerError(errors.New(`"fail.me" is not a valid tag`))},
   279  			{
   280  				ModelTag: s.Model.ModelTag().String(),
   281  				Life:     params.Life(s.Model.Life().String()),
   282  				OwnerTag: s.Model.Owner().String(),
   283  			},
   284  		},
   285  	}
   286  	result, err := s.controller.ModelStatus(req)
   287  	c.Assert(err, jc.ErrorIsNil)
   288  	c.Assert(result, jc.DeepEquals, expected)
   289  }
   290  
   291  type statePolicy struct{}
   292  
   293  func (statePolicy) Prechecker() (environs.InstancePrechecker, error) {
   294  	return nil, errors.NotImplementedf("Prechecker")
   295  }
   296  
   297  func (statePolicy) ConfigValidator() (config.Validator, error) {
   298  	return nil, errors.NotImplementedf("ConfigValidator")
   299  }
   300  
   301  func (statePolicy) ConstraintsValidator(context.ProviderCallContext) (constraints.Validator, error) {
   302  	return nil, errors.NotImplementedf("ConstraintsValidator")
   303  }
   304  
   305  func (statePolicy) InstanceDistributor() (context.Distributor, error) {
   306  	return nil, errors.NotImplementedf("InstanceDistributor")
   307  }
   308  
   309  func (statePolicy) StorageProviderRegistry() (storage.ProviderRegistry, error) {
   310  	return storage.ChainedProviderRegistry{
   311  		dummy.StorageProviders(),
   312  		provider.CommonStorageProviders(),
   313  	}, nil
   314  }
   315  
   316  func (statePolicy) ProviderConfigSchemaSource() (config.ConfigSchemaSource, error) {
   317  	return nil, errors.NotImplementedf("ConfigSchemaSource")
   318  }