Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds feature to provision app integration #137 #138

Merged
merged 5 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions cmd/provision/provision.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package provision

import (
"fmt"
"regexp"

"internal/apiclient"
"internal/client/provision"

"github.com/spf13/cobra"
)

// Cmd to provision App Integration
var Cmd = &cobra.Command{
Use: "provision",
Short: "Provisions application integration",
Long: "Provisions application integration in the region",
Args: func(cmd *cobra.Command, args []string) (err error) {
cmdProject := cmd.Flag("proj")
cmdRegion := cmd.Flag("reg")
if err = apiclient.SetRegion(cmdRegion.Value.String()); err != nil {
return err
}
return apiclient.SetProjectID(cmdProject.Value.String())
},
RunE: func(cmd *cobra.Command, args []string) (err error) {
cloudKMS := cmd.Flag("cloudkms").Value.String()
serviceAccount := cmd.Flag("service-account").Value.String()

if cloudKMS != "" {
re := regexp.MustCompile(`projects\/([a-zA-Z0-9_-]+)\/locations\/([a-zA-Z0-9_-]+)\/` +
`keyRings\/([a-zA-Z0-9_-]+)\/cryptoKeys\/([a-zA-Z0-9_-]+)\/cryptoKeyVersions\/([0-9]+)`)
ok := re.Match([]byte(cloudKMS))
if !ok {
return fmt.Errorf("CloudKMS key must be of the format " +
"projects/{project}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{cryptoKey}" +
"/cryptoKeyVersions/{cryptoKeyVersion}")
}
}

if serviceAccount != "" {
re := regexp.MustCompile(`[a-zA-Z0-9-]+@[a-zA-Z0-9-]+\.iam\.gserviceaccount\.com`)
ok := re.Match([]byte(serviceAccount))
if !ok {
return fmt.Errorf("service account must of the format " +
"<name>@<project-id>.iam.gserviceaccount.com")
}
}

_, err = provision.Provision(cloudKMS, samples, gmek, serviceAccount)
return err
},
}

var samples, gmek bool

func init() {
var cloudKMS, serviceAccount, project, region string

Cmd.PersistentFlags().StringVarP(&project, "proj", "p",
"", "Integration GCP Project name")
Cmd.PersistentFlags().StringVarP(&region, "reg", "r",
"", "Integration region name")
Cmd.Flags().StringVarP(&cloudKMS, "cloudkms", "k",
"", "Cloud KMS config for AuthModule to encrypt/decrypt credentials")
Cmd.Flags().BoolVarP(&samples, "samples", "s",
true, "Indicates if sample workflow should be created along with provisioning")
Cmd.Flags().BoolVarP(&gmek, "gmek", "g",
true, "Indicates provision with GMEK or CMEK")
Cmd.Flags().StringVarP(&serviceAccount, "service-account", "",
"", "User input run-as service account")
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/application-integration-management-toolkit/cmd/endpoints"
"github.com/GoogleCloudPlatform/application-integration-management-toolkit/cmd/integrations"
"github.com/GoogleCloudPlatform/application-integration-management-toolkit/cmd/preferences"
"github.com/GoogleCloudPlatform/application-integration-management-toolkit/cmd/provision"
"github.com/GoogleCloudPlatform/application-integration-management-toolkit/cmd/sfdcchannels"
"github.com/GoogleCloudPlatform/application-integration-management-toolkit/cmd/sfdcinstances"
"github.com/GoogleCloudPlatform/application-integration-management-toolkit/cmd/token"
Expand Down Expand Up @@ -142,6 +143,7 @@ func init() {
RootCmd.AddCommand(sfdcinstances.Cmd)
RootCmd.AddCommand(sfdcchannels.Cmd)
RootCmd.AddCommand(endpoints.Cmd)
RootCmd.AddCommand(provision.Cmd)
}

func initConfig() {
Expand Down
2 changes: 0 additions & 2 deletions internal/client/integrations/integrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,6 @@ func GetSfdcInstances(integration []byte) (instances map[string]string, err erro

// GetConnections
func GetConnections(integration []byte) (connections []string, err error) {

iversion := integrationVersion{}

err = json.Unmarshal(integration, &iversion)
Expand All @@ -779,7 +778,6 @@ func GetConnections(integration []byte) (connections []string, err error) {

// GetConnectionsWithRegion
func GetConnectionsWithRegion(integration []byte) (connections []integrationConnection, err error) {

iversion := integrationVersion{}

err = json.Unmarshal(integration, &iversion)
Expand Down
55 changes: 55 additions & 0 deletions internal/client/provision/provision.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package provision

import (
"fmt"
"net/url"
"path"
"strconv"
"strings"

"internal/apiclient"
)

// Provision
func Provision(cloudkms string, samples bool, gmek bool, serviceAccount string) (respBody []byte, err error) {
u, _ := url.Parse(apiclient.GetBaseIntegrationURL())
provStr := []string{}

if serviceAccount != "" {
provStr = append(provStr, "\"runAsServiceAccount\":\""+serviceAccount+"\"")
}

if cloudkms != "" {
kmsConfig := getCloudKMSConfig(cloudkms)
provStr = append(provStr, "\"cloudKmsConfig\":"+kmsConfig)
}

provStr = append(provStr, "\"createSampleWorkflows\":"+strconv.FormatBool(samples))
provStr = append(provStr, "\"provisionGmek\":"+strconv.FormatBool(gmek))

u.Path = path.Join(u.Path, "client:provision")

payload := "{" + strings.Join(provStr, ",") + "}"
respBody, err = apiclient.HttpClient(u.String(), payload)
return respBody, err
}

func getCloudKMSConfig(cloudkms string) string {
kmsParts := strings.Split(cloudkms, "/")
return fmt.Sprintf("{\"kmsLocation\":\"%s\",\"kmsRing\":\"%s\",\"key\":\"%s\",\"keyVersion\":\"%s\",\"kmsProjectId\":\"%s\"}",
kmsParts[3], kmsParts[5], kmsParts[7], kmsParts[9], kmsParts[1])
}