1// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. 2// 3// Example code for Core Services API 4// 5 6package example 7 8import ( 9 "context" 10 "fmt" 11 "log" 12 13 "github.com/oracle/oci-go-sdk/common" 14 "github.com/oracle/oci-go-sdk/core" 15 "github.com/oracle/oci-go-sdk/example/helpers" 16) 17 18const ( 19 vcnDisplayName = "OCI-GOSDK-Sample-VCN" 20 subnetDisplayName1 = "OCI-GOSDK-Sample-Subnet1" 21 subnetDisplayName2 = "OCI-GOSDK-Sample-Subnet2" 22 subnetDisplayName3 = "OCI-GOSDK-Sample-Subnet3" 23 24 // replace following variables with your instance info 25 // this is used by ExampleCreateImageDetails_Polymorphic 26 objectStorageURIWtihImage = "[The Object Storage URL for the image which will be used to create an image.]" 27) 28 29// ExampleLaunchInstance does create an instance 30// NOTE: launch instance will create a new instance and VCN. please make sure delete the instance 31// after execute this sample code, otherwise, you will be charged for the running instance 32func ExampleLaunchInstance() { 33 c, err := core.NewComputeClientWithConfigurationProvider(common.DefaultConfigProvider()) 34 helpers.FatalIfError(err) 35 ctx := context.Background() 36 37 // create the launch instance request 38 request := core.LaunchInstanceRequest{} 39 request.CompartmentId = helpers.CompartmentID() 40 request.DisplayName = common.String("OCI-Sample-Instance") 41 request.AvailabilityDomain = helpers.AvailabilityDomain() 42 43 // create a subnet or get the one already created 44 subnet := CreateOrGetSubnet() 45 fmt.Println("subnet created") 46 request.SubnetId = subnet.Id 47 48 // get a image 49 image := listImages(ctx, c)[30] 50 fmt.Println("list images") 51 request.ImageId = image.Id 52 53 // get all the shapes and filter the list by compatibility with the image 54 shapes := listShapes(ctx, c, request.ImageId) 55 fmt.Println("list shapes") 56 request.Shape = shapes[1].Shape 57 58 // default retry policy will retry on non-200 response 59 request.RequestMetadata = helpers.GetRequestMetadataWithDefaultRetryPolicy() 60 61 createResp, err := c.LaunchInstance(ctx, request) 62 helpers.FatalIfError(err) 63 64 fmt.Println("launching instance") 65 66 // should retry condition check which returns a bool value indicating whether to do retry or not 67 // it checks the lifecycle status equals to Running or not for this case 68 shouldRetryFunc := func(r common.OCIOperationResponse) bool { 69 if converted, ok := r.Response.(core.GetInstanceResponse); ok { 70 return converted.LifecycleState != core.InstanceLifecycleStateRunning 71 } 72 return true 73 } 74 75 // create get instance request with a retry policy which takes a function 76 // to determine shouldRetry or not 77 pollingGetRequest := core.GetInstanceRequest{ 78 InstanceId: createResp.Instance.Id, 79 RequestMetadata: helpers.GetRequestMetadataWithCustomizedRetryPolicy(shouldRetryFunc), 80 } 81 82 instance, pollError := c.GetInstance(ctx, pollingGetRequest) 83 helpers.FatalIfError(pollError) 84 85 fmt.Println("instance launched") 86 87 attachVnicResponse, err := c.AttachVnic(context.Background(), core.AttachVnicRequest{ 88 AttachVnicDetails: core.AttachVnicDetails{ 89 CreateVnicDetails: &core.CreateVnicDetails{ 90 SubnetId: subnet.Id, 91 AssignPublicIp: common.Bool(true), 92 }, 93 InstanceId: instance.Id, 94 }, 95 }) 96 97 helpers.FatalIfError(err) 98 fmt.Println("vnic attached") 99 100 _, err = c.DetachVnic(context.Background(), core.DetachVnicRequest{ 101 VnicAttachmentId: attachVnicResponse.Id, 102 }) 103 104 helpers.FatalIfError(err) 105 fmt.Println("vnic dettached") 106 107 defer func() { 108 terminateInstance(ctx, c, createResp.Id) 109 110 client, clerr := core.NewVirtualNetworkClientWithConfigurationProvider(common.DefaultConfigProvider()) 111 helpers.FatalIfError(clerr) 112 113 vcnID := subnet.VcnId 114 deleteSubnet(ctx, client, subnet.Id) 115 deleteVcn(ctx, client, vcnID) 116 }() 117 118 // Output: 119 // subnet created 120 // list images 121 // list shapes 122 // launching instance 123 // instance launched 124 // vnic attached 125 // vnic dettached 126 // terminating instance 127 // instance terminated 128 // deleteing subnet 129 // subnet deleted 130 // deleteing VCN 131 // VCN deleted 132} 133 134// ExampleCreateImageDetails_Polymorphic creates a boot disk image for the specified instance or 135// imports an exported image from the Oracle Cloud Infrastructure Object Storage service. 136func ExampleCreateImageDetails_Polymorphic() { 137 request := core.CreateImageRequest{} 138 request.CompartmentId = helpers.CompartmentID() 139 140 // you can import an image based on the Object Storage URL 'core.ImageSourceViaObjectStorageUriDetails' 141 // or based on the namespace, bucket name and object name 'core.ImageSourceViaObjectStorageTupleDetails' 142 // following example shows how to import image from object storage uri, you can use another one: 143 // request.ImageSourceDetails = core.ImageSourceViaObjectStorageTupleDetails 144 sourceDetails := core.ImageSourceViaObjectStorageUriDetails{} 145 sourceDetails.SourceUri = common.String(objectStorageURIWtihImage) 146 147 request.ImageSourceDetails = sourceDetails 148 149 c, err := core.NewComputeClientWithConfigurationProvider(common.DefaultConfigProvider()) 150 helpers.FatalIfError(err) 151 152 _, err = c.CreateImage(context.Background(), request) 153 helpers.FatalIfError(err) 154 fmt.Println("image created") 155} 156 157// CreateOrGetVcn either creates a new Virtual Cloud Network (VCN) or get the one already exist 158func CreateOrGetVcn() core.Vcn { 159 c, clerr := core.NewVirtualNetworkClientWithConfigurationProvider(common.DefaultConfigProvider()) 160 helpers.FatalIfError(clerr) 161 ctx := context.Background() 162 163 vcnItems := listVcns(ctx, c) 164 165 for _, element := range vcnItems { 166 if *element.DisplayName == vcnDisplayName { 167 // VCN already created, return it 168 return element 169 } 170 } 171 172 // create a new VCN 173 request := core.CreateVcnRequest{} 174 request.CidrBlock = common.String("10.0.0.0/16") 175 request.CompartmentId = helpers.CompartmentID() 176 request.DisplayName = common.String(vcnDisplayName) 177 request.DnsLabel = common.String("vcndns") 178 179 r, err := c.CreateVcn(ctx, request) 180 helpers.FatalIfError(err) 181 return r.Vcn 182} 183 184// CreateSubnet creates a new subnet or get the one already exist 185func CreateOrGetSubnet() core.Subnet { 186 return CreateOrGetSubnetWithDetails( 187 common.String(subnetDisplayName1), 188 common.String("10.0.0.0/24"), 189 common.String("subnetdns1"), 190 helpers.AvailabilityDomain()) 191} 192 193// CreateOrGetSubnetWithDetails either creates a new Virtual Cloud Network (VCN) or get the one already exist 194// with detail info 195func CreateOrGetSubnetWithDetails(displayName *string, cidrBlock *string, dnsLabel *string, availableDomain *string) core.Subnet { 196 c, clerr := core.NewVirtualNetworkClientWithConfigurationProvider(common.DefaultConfigProvider()) 197 helpers.FatalIfError(clerr) 198 ctx := context.Background() 199 200 subnets := listSubnets(ctx, c) 201 202 if displayName == nil { 203 displayName = common.String(subnetDisplayName1) 204 } 205 206 // check if the subnet has already been created 207 for _, element := range subnets { 208 if *element.DisplayName == *displayName { 209 // find the subnet, return it 210 return element 211 } 212 } 213 214 // create a new subnet 215 request := core.CreateSubnetRequest{} 216 request.AvailabilityDomain = availableDomain 217 request.CompartmentId = helpers.CompartmentID() 218 request.CidrBlock = cidrBlock 219 request.DisplayName = displayName 220 request.DnsLabel = dnsLabel 221 request.RequestMetadata = helpers.GetRequestMetadataWithDefaultRetryPolicy() 222 223 vcn := CreateOrGetVcn() 224 request.VcnId = vcn.Id 225 226 r, err := c.CreateSubnet(ctx, request) 227 helpers.FatalIfError(err) 228 229 // retry condition check, stop unitl return true 230 pollUntilAvailable := func(r common.OCIOperationResponse) bool { 231 if converted, ok := r.Response.(core.GetSubnetResponse); ok { 232 return converted.LifecycleState != core.SubnetLifecycleStateAvailable 233 } 234 return true 235 } 236 237 pollGetRequest := core.GetSubnetRequest{ 238 SubnetId: r.Id, 239 RequestMetadata: helpers.GetRequestMetadataWithCustomizedRetryPolicy(pollUntilAvailable), 240 } 241 242 // wait for lifecyle become running 243 _, pollErr := c.GetSubnet(ctx, pollGetRequest) 244 helpers.FatalIfError(pollErr) 245 246 // update the security rules 247 getReq := core.GetSecurityListRequest{ 248 SecurityListId: common.String(r.SecurityListIds[0]), 249 } 250 251 getResp, err := c.GetSecurityList(ctx, getReq) 252 helpers.FatalIfError(err) 253 254 // this security rule allows remote control the instance 255 portRange := core.PortRange{ 256 Max: common.Int(1521), 257 Min: common.Int(1521), 258 } 259 260 newRules := append(getResp.IngressSecurityRules, core.IngressSecurityRule{ 261 Protocol: common.String("6"), // TCP 262 Source: common.String("0.0.0.0/0"), 263 TcpOptions: &core.TcpOptions{ 264 DestinationPortRange: &portRange, 265 }, 266 }) 267 268 updateReq := core.UpdateSecurityListRequest{ 269 SecurityListId: common.String(r.SecurityListIds[0]), 270 } 271 272 updateReq.IngressSecurityRules = newRules 273 274 _, err = c.UpdateSecurityList(ctx, updateReq) 275 helpers.FatalIfError(err) 276 277 return r.Subnet 278} 279 280func listVcns(ctx context.Context, c core.VirtualNetworkClient) []core.Vcn { 281 request := core.ListVcnsRequest{ 282 CompartmentId: helpers.CompartmentID(), 283 } 284 285 r, err := c.ListVcns(ctx, request) 286 helpers.FatalIfError(err) 287 return r.Items 288} 289 290func listSubnets(ctx context.Context, c core.VirtualNetworkClient) []core.Subnet { 291 vcn := CreateOrGetVcn() 292 293 request := core.ListSubnetsRequest{ 294 CompartmentId: helpers.CompartmentID(), 295 VcnId: vcn.Id, 296 } 297 298 r, err := c.ListSubnets(ctx, request) 299 helpers.FatalIfError(err) 300 return r.Items 301} 302 303// ListImages lists the available images in the specified compartment. 304func listImages(ctx context.Context, c core.ComputeClient) []core.Image { 305 request := core.ListImagesRequest{ 306 CompartmentId: helpers.CompartmentID(), 307 } 308 309 r, err := c.ListImages(ctx, request) 310 helpers.FatalIfError(err) 311 312 return r.Items 313} 314 315// ListShapes Lists the shapes that can be used to launch an instance within the specified compartment. 316func listShapes(ctx context.Context, c core.ComputeClient, imageID *string) []core.Shape { 317 request := core.ListShapesRequest{ 318 CompartmentId: helpers.CompartmentID(), 319 ImageId: imageID, 320 } 321 322 r, err := c.ListShapes(ctx, request) 323 helpers.FatalIfError(err) 324 325 if r.Items == nil || len(r.Items) == 0 { 326 log.Fatalln("Invalid response from ListShapes") 327 } 328 329 return r.Items 330} 331 332func terminateInstance(ctx context.Context, c core.ComputeClient, id *string) { 333 request := core.TerminateInstanceRequest{ 334 InstanceId: id, 335 RequestMetadata: helpers.GetRequestMetadataWithDefaultRetryPolicy(), 336 } 337 338 _, err := c.TerminateInstance(ctx, request) 339 helpers.FatalIfError(err) 340 341 fmt.Println("terminating instance") 342 343 // should retry condition check which returns a bool value indicating whether to do retry or not 344 // it checks the lifecycle status equals to Terminated or not for this case 345 shouldRetryFunc := func(r common.OCIOperationResponse) bool { 346 if converted, ok := r.Response.(core.GetInstanceResponse); ok { 347 return converted.LifecycleState != core.InstanceLifecycleStateTerminated 348 } 349 return true 350 } 351 352 pollGetRequest := core.GetInstanceRequest{ 353 InstanceId: id, 354 RequestMetadata: helpers.GetRequestMetadataWithCustomizedRetryPolicy(shouldRetryFunc), 355 } 356 357 _, pollErr := c.GetInstance(ctx, pollGetRequest) 358 helpers.FatalIfError(pollErr) 359 fmt.Println("instance terminated") 360} 361 362func deleteVcn(ctx context.Context, c core.VirtualNetworkClient, id *string) { 363 request := core.DeleteVcnRequest{ 364 VcnId: id, 365 RequestMetadata: helpers.GetRequestMetadataWithDefaultRetryPolicy(), 366 } 367 368 fmt.Println("deleteing VCN") 369 _, err := c.DeleteVcn(ctx, request) 370 helpers.FatalIfError(err) 371 372 // should retry condition check which returns a bool value indicating whether to do retry or not 373 // it checks the lifecycle status equals to Terminated or not for this case 374 shouldRetryFunc := func(r common.OCIOperationResponse) bool { 375 if serviceError, ok := common.IsServiceError(r.Error); ok && serviceError.GetHTTPStatusCode() == 404 { 376 // resource been deleted, stop retry 377 return false 378 } 379 380 if converted, ok := r.Response.(core.GetVcnResponse); ok { 381 return converted.LifecycleState != core.VcnLifecycleStateTerminated 382 } 383 return true 384 } 385 386 pollGetRequest := core.GetVcnRequest{ 387 VcnId: id, 388 RequestMetadata: helpers.GetRequestMetadataWithCustomizedRetryPolicy(shouldRetryFunc), 389 } 390 391 _, pollErr := c.GetVcn(ctx, pollGetRequest) 392 if serviceError, ok := common.IsServiceError(pollErr); !ok || 393 (ok && serviceError.GetHTTPStatusCode() != 404) { 394 // fail if the error is not service error or 395 // if the error is service error and status code not equals to 404 396 helpers.FatalIfError(pollErr) 397 } 398 fmt.Println("VCN deleted") 399} 400 401func deleteSubnet(ctx context.Context, c core.VirtualNetworkClient, id *string) { 402 request := core.DeleteSubnetRequest{ 403 SubnetId: id, 404 RequestMetadata: helpers.GetRequestMetadataWithDefaultRetryPolicy(), 405 } 406 407 _, err := c.DeleteSubnet(context.Background(), request) 408 helpers.FatalIfError(err) 409 410 fmt.Println("deleteing subnet") 411 412 // should retry condition check which returns a bool value indicating whether to do retry or not 413 // it checks the lifecycle status equals to Terminated or not for this case 414 shouldRetryFunc := func(r common.OCIOperationResponse) bool { 415 if serviceError, ok := common.IsServiceError(r.Error); ok && serviceError.GetHTTPStatusCode() == 404 { 416 // resource been deleted 417 return false 418 } 419 420 if converted, ok := r.Response.(core.GetSubnetResponse); ok { 421 return converted.LifecycleState != core.SubnetLifecycleStateTerminated 422 } 423 return true 424 } 425 426 pollGetRequest := core.GetSubnetRequest{ 427 SubnetId: id, 428 RequestMetadata: helpers.GetRequestMetadataWithCustomizedRetryPolicy(shouldRetryFunc), 429 } 430 431 _, pollErr := c.GetSubnet(ctx, pollGetRequest) 432 if serviceError, ok := common.IsServiceError(pollErr); !ok || 433 (ok && serviceError.GetHTTPStatusCode() != 404) { 434 // fail if the error is not service error or 435 // if the error is service error and status code not equals to 404 436 helpers.FatalIfError(pollErr) 437 } 438 439 fmt.Println("subnet deleted") 440} 441