This repository has been archived by the owner on Jul 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 33
[OBS-405]Add setup command for EC2 installation #242
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
e8b6650
[OBS-405]Add setup command for EC2 installation
gmann42 6fc01c9
Add docs for EC2 installtion
gmann42 2b3f8a0
Add template files and systemd config steps
gmann42 9893cbd
Remove new lines from telemetry
gmann42 ac97ad0
Improve error messages
gmann42 0a0ddea
Check for systemctl instead of systemd
gmann42 62419c9
Update README.md
gmann42 6300f97
Fix extra api dump args
gmann42 b9a5062
Update cmd/internal/ec2/add.go
gmann42 f064dfc
Remove unused dry-run flag
gmann42 26bd10c
Update cmd/internal/ec2/add.go
gmann42 09a63ee
Update cmd/internal/ec2/add.go
gmann42 f6a51c5
Remove unused file usage_error.go
gmann42 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
### Amazon EC2/ Linux Server | ||
|
||
### Introduction | ||
|
||
- The Postman Live Collection Agent (LCA) runs as a systemd service on your server | ||
- The Postman collection is populated with endpoints observed from the traffic arriving at your service. | ||
|
||
### Prerequisites | ||
|
||
- Your server's OS supports `systemd` | ||
- `root` user | ||
|
||
### Usage | ||
|
||
- Log in as root user, or use `sudo su` to enable root before running the below command | ||
``` | ||
POSTMAN_API_KEY=<postman-api-key> postman-lc-agent setup --collection <postman-collectionID> | ||
``` | ||
|
||
To check the status or logs please use | ||
|
||
``` | ||
journalctl -fu postman-lc-agent | ||
``` | ||
|
||
#### Why is root required? | ||
|
||
- To enable and configure the agent as a systemd services | ||
- Env Configuration file location `/etc/default/postman-lc-agent` | ||
- Systemd service file location `/usr/lib/systemd/system/postman-lc-agent.service` | ||
|
||
### Uninstall | ||
|
||
- You can disable the systemd service using | ||
|
||
`sudo systemctl disable --now postman-lc-agent` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
package ec2 | ||
|
||
import ( | ||
"embed" | ||
"os" | ||
"os/exec" | ||
"os/user" | ||
"strings" | ||
"text/template" | ||
|
||
"github.com/akitasoftware/akita-cli/printer" | ||
"github.com/akitasoftware/akita-cli/telemetry" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
const ( | ||
envFileName = "postman-lc-agent" | ||
envFileTemplateName = "postman-lc-agent.tmpl" | ||
envFileBasePath = "/etc/default/" | ||
envFilePath = envFileBasePath + envFileName | ||
|
||
serviceFileName = "postman-lc-agent.service" | ||
serviceFileBasePath = "/usr/lib/systemd/system/" | ||
serviceFilePath = serviceFileBasePath + serviceFileName | ||
) | ||
|
||
// Embed files inside the binary. Requires Go >=1.16 | ||
|
||
//go:embed postman-lc-agent.service | ||
var serviceFile string | ||
|
||
// FS is used for easier template parsing | ||
|
||
//go:embed postman-lc-agent.tmpl | ||
var envFileFS embed.FS | ||
|
||
// Helper function for reporting telemetry | ||
func reportStep(stepName string) { | ||
telemetry.WorkflowStep("Starting systemd conguration", stepName) | ||
} | ||
|
||
func setupAgentForServer(collectionId string) error { | ||
|
||
err := checkUserPermissions() | ||
if err != nil { | ||
return err | ||
} | ||
err = checkSystemdExists() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = configureSystemdFiles(collectionId) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = enablePostmanAgent() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func checkUserPermissions() error { | ||
// TODO: Make this work without root | ||
|
||
// Exact permissions required are | ||
// read/write permissions on /etc/default/postman-lc-agent | ||
// read/write permission on /usr/lib/system/systemd | ||
// enable, daemon-reload, start, stop permission for systemctl | ||
|
||
printer.Infof("Checking user permissions \n") | ||
cu, err := user.Current() | ||
if err != nil { | ||
return errors.Wrapf(err, "could not get current user") | ||
} | ||
if !strings.EqualFold(cu.Name, "root") { | ||
printer.Errorf("root user is required to setup systemd service and edit related files.\n") | ||
return errors.Errorf("Please run the command again with root user") | ||
} | ||
return nil | ||
} | ||
|
||
func checkSystemdExists() error { | ||
message := "Checking if systemd exists" | ||
printer.Infof(message + "\n") | ||
reportStep(message) | ||
|
||
_, serr := exec.LookPath("systemctl") | ||
if serr != nil { | ||
printer.Errorf("We don't have support for non-systemd OS as of now.\n For more information please contact [email protected].\n") | ||
return errors.Errorf("Could not find systemd binary in your OS.") | ||
} | ||
return nil | ||
} | ||
|
||
func configureSystemdFiles(collectionId string) error { | ||
message := "Configuring systemd files" | ||
printer.Infof(message + "\n") | ||
reportStep(message) | ||
|
||
// Write collectionId and postman-api-key to go template file | ||
|
||
tmpl, err := template.ParseFS(envFileFS, envFileTemplateName) | ||
if err != nil { | ||
return errors.Wrapf(err, "systemd env file parsing failed") | ||
} | ||
|
||
data := struct { | ||
PostmanAPIKey string | ||
CollectionId string | ||
}{ | ||
gmann42 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
PostmanAPIKey: os.Getenv("POSTMAN_API_KEY"), | ||
CollectionId: collectionId, | ||
} | ||
|
||
// Ensure /etc/default exists | ||
cmd := exec.Command("mkdir", []string{"-p", envFileBasePath}...) | ||
_, err = cmd.CombinedOutput() | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to create %s directory\n", envFileBasePath) | ||
} | ||
|
||
envFile, err := os.Create(envFilePath) | ||
if err != nil { | ||
printer.Errorf("Failed to create systemd env file") | ||
return err | ||
} | ||
|
||
err = tmpl.Execute(envFile, data) | ||
if err != nil { | ||
printer.Errorf("Failed to write values to systemd env file") | ||
return err | ||
} | ||
|
||
// Ensure /usr/lib/systemd/system exists | ||
cmd = exec.Command("mkdir", []string{"-p", serviceFileBasePath}...) | ||
_, err = cmd.CombinedOutput() | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to create %s directory", serviceFileBasePath) | ||
} | ||
|
||
err = os.WriteFile(serviceFilePath, []byte(serviceFile), 0600) | ||
if err != nil { | ||
printer.Errorf("failed to create %s file in %s directory with err %q \n", serviceFileName, serviceFilePath, err) | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Starts the postman LCA agent as a systemd service | ||
func enablePostmanAgent() error { | ||
message := "Enabling postman-lc-agent as a service" | ||
reportStep(message) | ||
printer.Infof(message + "\n") | ||
|
||
cmd := exec.Command("systemctl", []string{"daemon-reload"}...) | ||
_, err := cmd.CombinedOutput() | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to run systemctl daemon-reload") | ||
} | ||
// systemctl start postman-lc-service | ||
cmd = exec.Command("systemctl", []string{"enable", "--now", serviceFileName}...) | ||
_, err = cmd.CombinedOutput() | ||
if err != nil { | ||
return errors.Wrapf(err, "faild to run systemctl enable --now") | ||
} | ||
printer.Infof("Postman LC Agent enabled as a systemd service. Please check logs using the below command \n") | ||
printer.Infof("journalctl -fu postman-lc-agent \n") | ||
|
||
return nil | ||
} | ||
|
||
// Run post-checks | ||
func postChecks() error { | ||
reportStep("EC2:Running post checks") | ||
|
||
// TODO: How to Verify if traffic is being captured ? | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package ec2 | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/akitasoftware/akita-cli/cmd/internal/cmderr" | ||
"github.com/akitasoftware/akita-cli/rest" | ||
"github.com/akitasoftware/akita-cli/telemetry" | ||
"github.com/akitasoftware/akita-cli/util" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
// Mandatory flag: Postman collection id | ||
collectionId string | ||
) | ||
|
||
var Cmd = &cobra.Command{ | ||
Use: "setup", | ||
Short: "Add the Postman Live Collections Agent to the current server.", | ||
Long: "The CLI will add the Postman Live Collections Agent as a systemd service to your current server.", | ||
SilenceUsage: true, | ||
RunE: addAgentToEC2, | ||
} | ||
|
||
var RemoveFromEC2Cmd = &cobra.Command{ | ||
Use: "remove", | ||
Short: "Remove the Postman Live Collections Agent from EC2.", | ||
Long: "Remove a previously installed Postman agent from an EC2 server.", | ||
SilenceUsage: true, | ||
RunE: removeAgentFromEC2, | ||
|
||
// Temporarily hide from users until complete | ||
Hidden: true, | ||
} | ||
|
||
func init() { | ||
Cmd.PersistentFlags().StringVar(&collectionId, "collection", "", "Your Postman collection ID") | ||
Cmd.MarkPersistentFlagRequired("collection") | ||
|
||
Cmd.AddCommand(RemoveFromEC2Cmd) | ||
} | ||
|
||
func addAgentToEC2(cmd *cobra.Command, args []string) error { | ||
// Check for API key | ||
_, err := cmderr.RequirePostmanAPICredentials("The Postman Live Collections Agent must have an API key in order to capture traces.") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Check collecton Id's existence | ||
if collectionId == "" { | ||
return errors.New("Must specify the ID of your collection with the --collection flag.") | ||
} | ||
frontClient := rest.NewFrontClient(rest.Domain, telemetry.GetClientID()) | ||
_, err = util.GetOrCreateServiceIDByPostmanCollectionID(frontClient, collectionId) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return setupAgentForServer(collectionId) | ||
} | ||
|
||
func removeAgentFromEC2(cmd *cobra.Command, args []string) error { | ||
return fmt.Errorf("this command is not yet implemented") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[Unit] | ||
Description=Postman Live Collections Agent | ||
Wants=network-online.target | ||
After=network-online.target NetworkManager.service systemd-resolved.service | ||
|
||
[Service] | ||
EnvironmentFile=/etc/default/postman-lc-agent | ||
# DO NOT CHANGE | ||
# "${FOO}" uses the arguement as is, while "$FOO" splits the string on white space | ||
# Reference: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines | ||
ExecStart=/usr/bin/postman-lc-agent apidump --collection "${COLLECTION_ID}" --interfaces "${INTERFACES}" --filter "${FILTER}" "$EXTRA_APIDUMP_ARGS" | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Add your Postman API key below. For example: | ||
# | ||
# POSTMAN_API_KEY=PMAC-XXXXXXX | ||
# | ||
# This is required. | ||
|
||
POSTMAN_API_KEY={{.PostmanAPIKey}} | ||
|
||
|
||
# Add your your Postman Live Collection ID. | ||
#This is required. | ||
|
||
COLLECTION_ID={{.CollectionId}} | ||
|
||
# For example, | ||
# COLLECTION_ID=1234567-890abcde-f123-4567-890a-bcdef1234567 | ||
|
||
|
||
# INTERFACES is optional. If left blank, the agent will listen on all available | ||
# network interfaces. | ||
# | ||
# FILTER is optional. If left blank, no packet-capture filter will be applied. | ||
# For example | ||
# INTERFACES=lo,eth0,eth1 | ||
# FILTER="port 80 or port 8080" | ||
# | ||
|
||
INTERFACES= | ||
FILTER= | ||
|
||
|
||
# Configure any extra arguments you wish to provide to the | ||
# 'postman-lc-agent apidump' command. For example, | ||
# | ||
# EXTRA_APIDUMP_ARGS="--rate-limit 100" | ||
# | ||
# This is optional and can be left blank. | ||
|
||
EXTRA_APIDUMP_ARGS= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error messages here are all minimally informational to the end user. What are they supposed to do next?
Probably, contact the support email for most of them, but are there any that can be corrected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't think user can do anything. because lack of systemd is quite unfixable.