github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/azure/upgrades_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package azure_test 5 6 import ( 7 "net/http" 8 9 "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute" 10 "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" 11 "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources" 12 "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage" 13 "github.com/Azure/go-autorest/autorest/mocks" 14 "github.com/Azure/go-autorest/autorest/to" 15 jc "github.com/juju/testing/checkers" 16 gc "gopkg.in/check.v1" 17 18 "github.com/juju/juju/environs" 19 "github.com/juju/juju/environs/context" 20 "github.com/juju/juju/provider/azure" 21 "github.com/juju/juju/provider/azure/internal/armtemplates" 22 "github.com/juju/juju/provider/azure/internal/azuretesting" 23 "github.com/juju/juju/testing" 24 ) 25 26 type environUpgradeSuite struct { 27 testing.BaseSuite 28 29 requests []*http.Request 30 sender azuretesting.Senders 31 provider environs.EnvironProvider 32 env environs.Environ 33 34 callCtx *context.CloudCallContext 35 invalidCredential bool 36 } 37 38 var _ = gc.Suite(&environUpgradeSuite{}) 39 40 func (s *environUpgradeSuite) SetUpTest(c *gc.C) { 41 s.BaseSuite.SetUpTest(c) 42 s.sender = nil 43 s.requests = nil 44 45 s.provider = newProvider(c, azure.ProviderConfig{ 46 Sender: azuretesting.NewSerialSender(&s.sender), 47 RequestInspector: azuretesting.RequestRecorder(&s.requests), 48 RandomWindowsAdminPassword: func() string { return "sorandom" }, 49 }) 50 s.env = openEnviron(c, s.provider, &s.sender) 51 s.callCtx = &context.CloudCallContext{ 52 InvalidateCredentialFunc: func(string) error { 53 s.invalidCredential = true 54 return nil 55 }, 56 } 57 } 58 59 func (s *environUpgradeSuite) TestEnvironImplementsUpgrader(c *gc.C) { 60 c.Assert(s.env, gc.Implements, new(environs.Upgrader)) 61 } 62 63 func (s *environUpgradeSuite) TestEnvironUpgradeOperations(c *gc.C) { 64 upgrader := s.env.(environs.Upgrader) 65 ops := upgrader.UpgradeOperations(s.callCtx, environs.UpgradeOperationsParams{}) 66 c.Assert(ops, gc.HasLen, 1) 67 c.Assert(ops[0].TargetVersion, gc.Equals, 1) 68 c.Assert(ops[0].Steps, gc.HasLen, 1) 69 c.Assert(ops[0].Steps[0].Description(), gc.Equals, "Create common resource deployment") 70 } 71 72 func (s *environUpgradeSuite) TestEnvironUpgradeOperationCreateCommonDeployment(c *gc.C) { 73 upgrader := s.env.(environs.Upgrader) 74 op0 := upgrader.UpgradeOperations(s.callCtx, environs.UpgradeOperationsParams{})[0] 75 76 // The existing NSG has two rules: one for Juju API traffic, 77 // and an application-specific rule. Only the latter should 78 // be preserved; we will recreate the "builtin" SSH rule, 79 // and the API rule is not needed for non-controller models. 80 customRule := network.SecurityRule{ 81 Name: to.StringPtr("machine-0-tcp-1234"), 82 SecurityRulePropertiesFormat: &network.SecurityRulePropertiesFormat{ 83 Description: to.StringPtr("custom rule"), 84 Protocol: network.SecurityRuleProtocolTCP, 85 SourceAddressPrefix: to.StringPtr("*"), 86 SourcePortRange: to.StringPtr("*"), 87 DestinationAddressPrefix: to.StringPtr("*"), 88 DestinationPortRange: to.StringPtr("1234"), 89 Access: network.SecurityRuleAccessAllow, 90 Priority: to.Int32Ptr(102), 91 Direction: network.SecurityRuleDirectionInbound, 92 }, 93 } 94 securityRules := []network.SecurityRule{{ 95 Name: to.StringPtr("JujuAPIInbound"), 96 SecurityRulePropertiesFormat: &network.SecurityRulePropertiesFormat{ 97 Description: to.StringPtr("Allow API connections to controller machines"), 98 Protocol: network.SecurityRuleProtocolTCP, 99 SourceAddressPrefix: to.StringPtr("*"), 100 SourcePortRange: to.StringPtr("*"), 101 DestinationAddressPrefix: to.StringPtr("192.168.16.0/20"), 102 DestinationPortRange: to.StringPtr("17777"), 103 Access: network.SecurityRuleAccessAllow, 104 Priority: to.Int32Ptr(101), 105 Direction: network.SecurityRuleDirectionInbound, 106 }, 107 }, customRule} 108 nsg := network.SecurityGroup{ 109 SecurityGroupPropertiesFormat: &network.SecurityGroupPropertiesFormat{ 110 SecurityRules: &securityRules, 111 }, 112 } 113 114 vmListSender := azuretesting.NewSenderWithValue(&compute.VirtualMachineListResult{}) 115 vmListSender.PathPattern = ".*/virtualMachines" 116 nsgSender := azuretesting.NewSenderWithValue(&nsg) 117 nsgSender.PathPattern = ".*/networkSecurityGroups/juju-internal-nsg" 118 deploymentSender := azuretesting.NewSenderWithValue(&resources.Deployment{}) 119 deploymentSender.PathPattern = ".*/deployments/common" 120 s.sender = append(s.sender, vmListSender, nsgSender, deploymentSender) 121 c.Assert(op0.Steps[0].Run(s.callCtx), jc.ErrorIsNil) 122 c.Assert(s.requests, gc.HasLen, 3) 123 124 expectedSecurityRules := []network.SecurityRule{{ 125 Name: to.StringPtr("SSHInbound"), 126 SecurityRulePropertiesFormat: &network.SecurityRulePropertiesFormat{ 127 Description: to.StringPtr("Allow SSH access to all machines"), 128 Protocol: network.SecurityRuleProtocolTCP, 129 SourceAddressPrefix: to.StringPtr("*"), 130 SourcePortRange: to.StringPtr("*"), 131 DestinationAddressPrefix: to.StringPtr("*"), 132 DestinationPortRange: to.StringPtr("22"), 133 Access: network.SecurityRuleAccessAllow, 134 Priority: to.Int32Ptr(100), 135 Direction: network.SecurityRuleDirectionInbound, 136 }, 137 }, customRule} 138 nsgId := `[resourceId('Microsoft.Network/networkSecurityGroups', 'juju-internal-nsg')]` 139 subnets := []network.Subnet{{ 140 Name: to.StringPtr("juju-internal-subnet"), 141 SubnetPropertiesFormat: &network.SubnetPropertiesFormat{ 142 AddressPrefix: to.StringPtr("192.168.0.0/20"), 143 NetworkSecurityGroup: &network.SecurityGroup{ 144 ID: to.StringPtr(nsgId), 145 }, 146 }, 147 }, { 148 Name: to.StringPtr("juju-controller-subnet"), 149 SubnetPropertiesFormat: &network.SubnetPropertiesFormat{ 150 AddressPrefix: to.StringPtr("192.168.16.0/20"), 151 NetworkSecurityGroup: &network.SecurityGroup{ 152 ID: to.StringPtr(nsgId), 153 }, 154 }, 155 }} 156 addressPrefixes := []string{"192.168.0.0/20", "192.168.16.0/20"} 157 templateResources := []armtemplates.Resource{{ 158 Type: "Microsoft.Network/networkSecurityGroups", 159 Name: "juju-internal-nsg", 160 Location: "westus", 161 Properties: &network.SecurityGroupPropertiesFormat{ 162 SecurityRules: &expectedSecurityRules, 163 }, 164 }, { 165 Type: "Microsoft.Network/virtualNetworks", 166 Name: "juju-internal-network", 167 Location: "westus", 168 Properties: &network.VirtualNetworkPropertiesFormat{ 169 AddressSpace: &network.AddressSpace{&addressPrefixes}, 170 Subnets: &subnets, 171 }, 172 DependsOn: []string{nsgId}, 173 }, { 174 Type: "Microsoft.Storage/storageAccounts", 175 Name: storageAccountName, 176 Location: "westus", 177 StorageSku: &storage.Sku{ 178 Name: storage.SkuName("Standard_LRS"), 179 }, 180 }} 181 182 var actual resources.Deployment 183 unmarshalRequestBody(c, s.requests[2], &actual) 184 c.Assert(actual.Properties, gc.NotNil) 185 c.Assert(actual.Properties.Template, gc.NotNil) 186 resources, ok := actual.Properties.Template.(map[string]interface{})["resources"].([]interface{}) 187 c.Assert(ok, jc.IsTrue) 188 c.Assert(resources, gc.HasLen, len(templateResources)) 189 } 190 191 func (s *environUpgradeSuite) TestEnvironUpgradeOperationCreateCommonDeploymentControllerModel(c *gc.C) { 192 s.sender = nil 193 s.requests = nil 194 env := openEnviron(c, s.provider, &s.sender, testing.Attrs{"name": "controller"}) 195 upgrader := env.(environs.Upgrader) 196 197 controllerTags := make(map[string]*string) 198 trueString := "true" 199 controllerTags["juju-is-controller"] = &trueString 200 vms := []compute.VirtualMachine{{ 201 Tags: nil, 202 }, { 203 Tags: controllerTags, 204 }} 205 vmListSender := azuretesting.NewSenderWithValue(&compute.VirtualMachineListResult{ 206 Value: &vms, 207 }) 208 vmListSender.PathPattern = ".*/virtualMachines" 209 s.sender = append(s.sender, vmListSender) 210 211 op0 := upgrader.UpgradeOperations(s.callCtx, environs.UpgradeOperationsParams{})[0] 212 c.Assert(op0.Steps[0].Run(s.callCtx), jc.ErrorIsNil) 213 } 214 215 func (s *environUpgradeSuite) TestEnvironUpgradeOperationCreateCommonDeploymentControllerModelWithInvalidCredential(c *gc.C) { 216 s.sender = nil 217 s.requests = nil 218 env := openEnviron(c, s.provider, &s.sender, testing.Attrs{"name": "controller"}) 219 upgrader := env.(environs.Upgrader) 220 221 controllerTags := make(map[string]*string) 222 trueString := "true" 223 controllerTags["juju-is-controller"] = &trueString 224 225 mockSender := mocks.NewSender() 226 mockSender.AppendResponse(mocks.NewResponseWithStatus("401 Unauthorized", http.StatusUnauthorized)) 227 s.sender = append(s.sender, mockSender) 228 229 c.Assert(s.invalidCredential, jc.IsFalse) 230 op0 := upgrader.UpgradeOperations(s.callCtx, environs.UpgradeOperationsParams{})[0] 231 c.Assert(op0.Steps[0].Run(s.callCtx), gc.NotNil) 232 c.Assert(s.invalidCredential, jc.IsTrue) 233 }