package main import ( "fmt" "log" "github.com/pulumi/pulumi-oci/sdk/go/oci/identity" "github.com/pulumi/pulumi-oci/sdk/go/oci/objectstorage" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" ) const HappyListmonkBucketName = "listmonk-files" func setupListmonkStorage(ctx *pulumi.Context, ocicfg *config.Config, compartment *identity.Compartment) (pulumi.StringOutput, *identity.CustomerSecretKey, error) { // Retrieve current namespace ns := compartment.CompartmentId.ApplyT(func(compartmentId string) (string, error) { ns, err := objectstorage.GetNamespace(ctx, &objectstorage.GetNamespaceArgs{ CompartmentId: &compartmentId, }, nil) if err != nil { return "", err } return ns.Namespace, nil }).(pulumi.StringOutput) // Create bucket _, err := objectstorage.NewBucket(ctx, HappyListmonkBucketName, &objectstorage.BucketArgs{ CompartmentId: compartment.ID(), Namespace: ns, Name: pulumi.String(HappyListmonkBucketName), AccessType: pulumi.String("NoPublicAccess"), StorageTier: pulumi.String("Standard"), }) if err != nil { return ns, nil, err } // Create service account listmonkUser, err := identity.NewUser(ctx, "listmonk-user", &identity.UserArgs{ Name: pulumi.String("listmonk"), Description: pulumi.String("User for Listmonk"), Email: pulumi.String("postmaster+listmonk@happydomain.fr"), }) if err != nil { return ns, nil, err } // Set user capabilities _, err = identity.NewUserCapabilitiesManagement(ctx, "listmonk-user-caps", &identity.UserCapabilitiesManagementArgs{ UserId: listmonkUser.ID(), CanUseApiKeys: pulumi.Bool(false), CanUseAuthTokens: pulumi.Bool(false), CanUseConsolePassword: pulumi.Bool(false), CanUseCustomerSecretKeys: pulumi.Bool(true), CanUseSmtpCredentials: pulumi.Bool(false), }) if err != nil { return ns, nil, err } // Create groups readWriteGroup, err := identity.NewGroup(ctx, "S3ListmonkReadWriteGroup", &identity.GroupArgs{ Name: pulumi.String("s3_read_write_listmonk"), Description: pulumi.String("Users with read and write access to Object Storage " + HappyListmonkBucketName), }) if err != nil { return ns, nil, err } // Add users to groups _, err = identity.NewUserGroupMembership(ctx, "listmonkReadWriteGroupMembership", &identity.UserGroupMembershipArgs{ GroupId: readWriteGroup.ID(), UserId: listmonkUser.ID(), }) if err != nil { return ns, nil, err } // Define policies for the groups policies := []struct { name string description string group pulumi.StringOutput policy []string }{ { name: "readWritePolicy-listmonk", description: "readWritePolicy to " + HappyListmonkBucketName + " bucket object storage", group: readWriteGroup.Name, policy: []string{ "Allow group 'Default'/'s3_read_write_listmonk' to read buckets in compartment %s", fmt.Sprintf("Allow group 'Default'/'s3_read_write_listmonk' to manage objects in compartment %%s where all {target.bucket.name= '%s', any {request.permission= 'OBJECT_CREATE', request.permission='OBJECT_INSPECT', request.permission='OBJECT_OVERWRITE', request.permission='PAR_MANAGE'}}", HappyListmonkBucketName), }, }, } compartment.Name.ApplyT(func(compartmentName string) string { compartment.CompartmentId.ApplyT(func(compartmentId string) (string, error) { for _, p := range policies { var statements pulumi.StringArray for _, policy := range p.policy { statements = append(statements, pulumi.String(fmt.Sprintf(policy, compartmentName))) } _, err := identity.NewPolicy(ctx, p.name, &identity.PolicyArgs{ CompartmentId: pulumi.String(compartmentId), Name: pulumi.String(p.name), Description: pulumi.String(p.description), Statements: statements, }) if err != nil { log.Println(err.Error()) return "", err } } return "", nil }) return "" }) listmonkAuthToken, err := identity.NewCustomerSecretKey(ctx, "listmonk-user-secret-key", &identity.CustomerSecretKeyArgs{ UserId: listmonkUser.ID(), DisplayName: pulumi.String("Listmonk to S3"), }) if err != nil { return ns, nil, err } // Export the infos ctx.Export("listmonk-access-key", listmonkAuthToken.ID()) ctx.Export("listmonk-secret-key", listmonkAuthToken.Key) return ns, listmonkAuthToken, nil }