mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves https://github.com/fleetdm/confidential/issues/13934 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually
123 lines
3 KiB
Go
123 lines
3 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/fleetdm/fleet/v4/pkg/file"
|
|
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
|
|
"github.com/fleetdm/fleet/v4/server/contexts/installersize"
|
|
"github.com/fleetdm/fleet/v4/server/fleet"
|
|
)
|
|
|
|
func main() {
|
|
url := flag.String("url", "", "URL of the custom package")
|
|
path := flag.String("path", "", "File path of the custom package (or a directory of packages)")
|
|
flag.Parse()
|
|
|
|
switch {
|
|
case *url != "" && *path != "":
|
|
log.Fatalf("-url and -path are mutually exclusive")
|
|
case *url != "":
|
|
metadata, err := processPackageFromUrl(*url)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
output(metadata)
|
|
case *path != "":
|
|
pathInfo, err := os.Stat(*path)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if pathInfo.IsDir() {
|
|
files, err := os.ReadDir(*path)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
for _, selectedFile := range files {
|
|
if selectedFile.IsDir() || strings.HasPrefix(selectedFile.Name(), ".") {
|
|
continue
|
|
}
|
|
|
|
fmt.Printf("File: %s\n", selectedFile.Name())
|
|
metadata, err := processPackageFromLocal(filepath.Join(*path, selectedFile.Name()))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
output(metadata)
|
|
}
|
|
} else {
|
|
metadata, err := processPackageFromLocal(*path)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
output(metadata)
|
|
}
|
|
default:
|
|
flag.Usage()
|
|
}
|
|
}
|
|
|
|
func output(metadata *file.InstallerMetadata) {
|
|
slices.Sort(metadata.PackageIDs)
|
|
fmt.Printf(
|
|
"- Name: '%s'\n- Bundle Identifier: '%s'\n- Package IDs: '%s'\n- Version: %s\n\n",
|
|
metadata.Name, metadata.BundleIdentifier, strings.Join(metadata.PackageIDs, ","), metadata.Version,
|
|
)
|
|
}
|
|
|
|
func processPackageFromUrl(url string) (*file.InstallerMetadata, error) {
|
|
client := fleethttp.NewClient()
|
|
client.Transport = fleethttp.NewSizeLimitTransport(installersize.MaxSoftwareInstallerSize)
|
|
|
|
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create http request: %s", err)
|
|
}
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get request: %s", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
// Allow all 2xx and 3xx status codes in this pass.
|
|
if resp.StatusCode >= 400 {
|
|
return nil, fmt.Errorf("get request failed with status: %d", resp.StatusCode)
|
|
}
|
|
|
|
tfr, err := fleet.NewTempFileReader(resp.Body, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("reading custom package: %d", resp.StatusCode)
|
|
}
|
|
defer tfr.Close()
|
|
|
|
metadata, err := file.ExtractInstallerMetadata(tfr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("extract installer metadata: %s", err)
|
|
}
|
|
return metadata, nil
|
|
}
|
|
|
|
func processPackageFromLocal(path string) (*file.InstallerMetadata, error) {
|
|
fp, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open file: %s", err)
|
|
}
|
|
tfr := &fleet.TempFileReader{
|
|
File: fp,
|
|
}
|
|
|
|
metadata, err := file.ExtractInstallerMetadata(tfr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("extract installer metadata: %s", err)
|
|
}
|
|
return metadata, nil
|
|
}
|