Skip to content

Commit

Permalink
feat: adds support to import security profiles (#342)
Browse files Browse the repository at this point in the history
* feat: exports sec profiles to a folder

* chore: pretty prints json in debug

* chore: fixes description of list params

* feat: adds support to import sec profiles

* feat: adds support to compute secu profile scores

* chore: fix linting errors

* feat: disable all revisions export #340

* feat: remove the ability to export revisions #340

* chore: fix linting issues
  • Loading branch information
srinandan authored Dec 12, 2023
1 parent abb146d commit 2c7312c
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 56 deletions.
1 change: 1 addition & 0 deletions cmd/apidocs/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package apidocs

import (
"fmt"

"internal/apiclient"

"internal/client/apidocs"
Expand Down
4 changes: 2 additions & 2 deletions cmd/org/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ var ExportCmd = &cobra.Command{

if orgs.GetAddOn("apiSecurityConfig") {
clilog.Info.Println("Exporting API Security Configuration...")
if err = securityprofiles.Export(conn, folder, allRevisions); proceedOnError(err) != nil {
if err = securityprofiles.Export(conn, securityProfilesFolderName); proceedOnError(err) != nil {
return err
}
}
Expand Down Expand Up @@ -319,7 +319,7 @@ func createFolders() (err error) {
if err = os.Mkdir(portalsFolderName, 0o755); err != nil {
return err
}
return nil
return os.Mkdir(securityProfilesFolderName, 0o755)
}

func exportKVMEntries(scope string, env string, listKVMBytes []byte) (err error) {
Expand Down
10 changes: 10 additions & 0 deletions cmd/org/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ import (
"internal/client/envgroups"
"internal/client/keystores"
"internal/client/kvm"
"internal/client/orgs"
"internal/client/products"
"internal/client/references"
"internal/client/sharedflows"
"internal/client/targetservers"

"internal/client/securityprofiles"

"github.com/apigee/apigeecli/cmd/utils"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -125,6 +128,13 @@ var ImportCmd = &cobra.Command{
}
}

if orgs.GetAddOn("apiSecurityConfig") {
clilog.Info.Println("Importing Security Profile Configuration...")
if err = securityprofiles.Import(conn, path.Join(folder, securityProfilesFolderName)); err != nil {
return err
}
}

var envRespBody []byte
if envRespBody, err = env.List(); err != nil {
return err
Expand Down
7 changes: 4 additions & 3 deletions cmd/org/variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ const (
tracecfgFileName = "_tracecfg.json"
referencesFileName = "references.json"

proxiesFolderName = "proxies"
sharedFlowsFolderName = "sharedflows"
portalsFolderName = "portals"
proxiesFolderName = "proxies"
sharedFlowsFolderName = "sharedflows"
portalsFolderName = "portals"
securityProfilesFolderName = "securityprofiles"
)

var conn int
89 changes: 89 additions & 0 deletions cmd/securityprofiles/compute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// 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 securityprofiles

import (
"fmt"
"time"

"internal/apiclient"
"internal/client/securityprofiles"

"github.com/spf13/cobra"
)

// ComputeCmd to list catalog items
var ComputeCmd = &cobra.Command{
Use: "compute",
Short: "Calculates scores for requested time range",
Long: "Calculates scores for requested time range for the specified security profile",
Args: func(cmd *cobra.Command, args []string) (err error) {
if startTime != "" {
if _, err = time.Parse(time.RFC3339, startTime); err != nil {
return fmt.Errorf("invalid format for startTime: %v", err)
}
}
if endTime != "" {
if _, err = time.Parse(time.RFC3339, endTime); err != nil {
return fmt.Errorf("invalid format for endTime: %v", err)
}
}
apiclient.SetApigeeEnv(environment)
return apiclient.SetApigeeOrg(org)
},
RunE: func(cmd *cobra.Command, args []string) (err error) {
if endTime == "" {
// if endTime is not set, then set current timestamp
endTime = time.Now().UTC().Format(time.RFC3339)
}
if startTime == "" {
// if startTime is not set, then set yesterday's timestamp
startTime = time.Now().AddDate(0, 0, -1).UTC().Format(time.RFC3339)
}
_, err = securityprofiles.Compute(name, startTime, endTime,
filters, pageSize, pageToken, full)
return
},
}

var (
startTime, endTime string
filters []string
full bool
)

func init() {
ComputeCmd.Flags().StringVarP(&name, "name", "n",
"", "Name of the security profile")
ComputeCmd.Flags().StringVarP(&environment, "env", "e",
"", "Apigee environment name")

ComputeCmd.Flags().StringVarP(&startTime, "start-time", "",
"", "Inclusive start of the interval; default is 24 hours ago")
ComputeCmd.Flags().StringVarP(&endTime, "end-time", "",
"", "Exclusive end of the interval; default current timestamp")

ComputeCmd.Flags().StringArrayVarP(&filters, "filters", "f",
nil, "Filters are used to filter scored components")
ComputeCmd.Flags().IntVarP(&pageSize, "page-size", "",
-1, "The maximum number of versions to return")
ComputeCmd.Flags().StringVarP(&pageToken, "page-token", "",
"", "A page token, received from a previous call")
ComputeCmd.Flags().BoolVarP(&full, "full", "",
false, "Generate all scores")

_ = ComputeCmd.MarkFlagRequired("name")
_ = ComputeCmd.MarkFlagRequired("env")
}
9 changes: 3 additions & 6 deletions cmd/securityprofiles/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,18 @@ var ExpCmd = &cobra.Command{
if err = apiclient.FolderExists(folder); err != nil {
return err
}
return securityprofiles.Export(conn, folder, allRevisions)
return securityprofiles.Export(conn, folder)
},
}

var (
conn int
folder string
allRevisions bool
conn int
folder string
)

func init() {
ExpCmd.Flags().IntVarP(&conn, "conn", "c",
4, "Number of connections")
ExpCmd.Flags().StringVarP(&folder, "folder", "f",
"", "folder to export Security Profiles")
ExpCmd.Flags().BoolVarP(&allRevisions, "all", "",
false, "Export all proxy revisions")
}
51 changes: 51 additions & 0 deletions cmd/securityprofiles/import.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// 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 securityprofiles

import (
"fmt"
"os"

"internal/apiclient"

"internal/client/securityprofiles"

"github.com/spf13/cobra"
)

// ImpCmd to import sec profiles
var ImpCmd = &cobra.Command{
Use: "import",
Short: "Import a folder containing Security Profiles",
Long: "Import a folder containing Security Profiles",
Args: func(cmd *cobra.Command, args []string) (err error) {
return apiclient.SetApigeeOrg(org)
},
RunE: func(cmd *cobra.Command, args []string) (err error) {
if stat, err := os.Stat(folder); err == nil && !stat.IsDir() {
return fmt.Errorf("supplied path is not a folder")
}
return securityprofiles.Import(conn, folder)
},
}

func init() {
ImpCmd.Flags().StringVarP(&folder, "folder", "f",
"", "folder containing one or more security profiles")
ImpCmd.Flags().IntVarP(&conn, "conn", "c",
4, "Number of connections")

_ = ImpCmd.MarkFlagRequired("folder")
}
4 changes: 2 additions & 2 deletions cmd/securityprofiles/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ var (
)

func init() {
ListCmd.Flags().IntVarP(&pageSize, "pageSize", "",
ListCmd.Flags().IntVarP(&pageSize, "page-size", "",
-1, "The maximum number of versions to return")
ListCmd.Flags().StringVarP(&pageToken, "pageToken", "",
ListCmd.Flags().StringVarP(&pageToken, "page-token", "",
"", "A page token, received from a previous call")
}
2 changes: 2 additions & 0 deletions cmd/securityprofiles/securityprofiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ func init() {
Cmd.AddCommand(ListRevisionsCmd)
Cmd.AddCommand(UpdateCmd)
Cmd.AddCommand(ExpCmd)
Cmd.AddCommand(ImpCmd)
Cmd.AddCommand(ComputeCmd)

_ = Cmd.MarkFlagRequired("org")
}
11 changes: 6 additions & 5 deletions internal/apiclient/httpclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,17 +275,14 @@ func HttpClient(params ...string) (respBody []byte, err error) {
return nil, err
}

if DryRun() {
return nil, nil
}

clilog.Debug.Println("Connecting to: ", params[0])

switch paramLen := len(params); paramLen {
case 1:
req, err = http.NewRequest(http.MethodGet, params[0], nil)
case 2:
clilog.Debug.Println("Payload: ", params[1])
payload, _ := PrettifyJSON([]byte(params[1]))
clilog.Debug.Println("Payload: ", string(payload))
req, err = http.NewRequest(http.MethodPost, params[0], bytes.NewBuffer([]byte(params[1])))
case 3:
if req, err = getRequest(params); err != nil {
Expand Down Expand Up @@ -313,6 +310,10 @@ func HttpClient(params ...string) (respBody []byte, err error) {
clilog.Debug.Println("Content-Type : ", contentType)
req.Header.Set("Content-Type", contentType)

if DryRun() {
return nil, nil
}

resp, err := ApigeeAPIClient.Do(req)
if err != nil {
clilog.Error.Println("error connecting: ", err)
Expand Down
13 changes: 6 additions & 7 deletions internal/client/apidocs/apidocs.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,14 @@ func Delete(siteid string, id string) (respBody []byte, err error) {
func UpdateDocumentation(siteid string, id string, displayName string,
openAPIDoc string, graphQLDoc string, endpointUri string,
) (respBody []byte, err error) {

var data map[string]interface{}
// var payload string
if openAPIDoc != "" {
data = map[string]interface{}{
"oasDocumentation": map[string]interface{}{
"spec": map[string]interface{}{
"displayName":displayName,
"contents":openAPIDoc,
"displayName": displayName,
"contents": openAPIDoc,
},
},
}
Expand All @@ -231,10 +230,10 @@ func UpdateDocumentation(siteid string, id string, displayName string,
if graphQLDoc != "" {
data = map[string]interface{}{
"graphqlDocumentation": map[string]interface{}{
"endpointUri":endpointUri,
"endpointUri": endpointUri,
"schema": map[string]interface{}{
"displayName":displayName,
"contents":graphQLDoc,
"displayName": displayName,
"contents": graphQLDoc,
},
},
}
Expand All @@ -245,7 +244,7 @@ func UpdateDocumentation(siteid string, id string, displayName string,
fmt.Printf("could not marshal json: %s\n", err)
return
}
payload := string(jsonData);
payload := string(jsonData)

u, _ := url.Parse(apiclient.BaseURL)
u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "sites", siteid, "apidocs", id, "documentation")
Expand Down
Loading

0 comments on commit 2c7312c

Please sign in to comment.