From 4e6e1a8435abd34db3c56132ba4b41a64f9d5a7e Mon Sep 17 00:00:00 2001 From: Dibya Prakash Date: Fri, 27 Jun 2025 17:26:56 +0530 Subject: [PATCH 1/3] chnaged folder name from cmd to kmipcli like other cli --- {cmd => kmipcli}/KMIPCLIutils.go | 0 {cmd => kmipcli}/configureHPCSKEK.go | 0 {cmd => kmipcli}/configureHSMKEK.go | 0 {cmd => kmipcli}/createClientCert.go | 0 {cmd => kmipcli}/createPolicy.go | 0 {cmd => kmipcli}/deleteClientCert.go | 0 {cmd => kmipcli}/disableKEK.go | 0 {cmd => kmipcli}/downloadClientCert.go | 0 {cmd => kmipcli}/getClientCert.go | 0 {cmd => kmipcli}/getHSMInfo.go | 0 {cmd => kmipcli}/getKEKSetting.go | 0 {cmd => kmipcli}/getKmipObject.go | 0 {cmd => kmipcli}/getKmipObjectCount.go | 0 {cmd => kmipcli}/getPlatformInfo.go | 0 {cmd => kmipcli}/getTenantInfo.go | 0 {cmd => kmipcli}/getTenantSettings.go | 0 {cmd => kmipcli}/listClientCerts.go | 0 {cmd => kmipcli}/listKmipObjects.go | 0 {cmd => kmipcli}/locateRootKey.go | 0 {cmd => kmipcli}/login.go | 0 {cmd => kmipcli}/rekeyKEK.go | 0 {cmd => kmipcli}/root.go | 0 {cmd => kmipcli}/updateKmipObject.go | 0 {cmd => kmipcli}/updatePolicy.go | 0 {cmd => kmipcli}/updateTenantSettings.go | 0 {cmd => kmipcli}/version.go | 0 26 files changed, 0 insertions(+), 0 deletions(-) rename {cmd => kmipcli}/KMIPCLIutils.go (100%) rename {cmd => kmipcli}/configureHPCSKEK.go (100%) rename {cmd => kmipcli}/configureHSMKEK.go (100%) rename {cmd => kmipcli}/createClientCert.go (100%) rename {cmd => kmipcli}/createPolicy.go (100%) rename {cmd => kmipcli}/deleteClientCert.go (100%) rename {cmd => kmipcli}/disableKEK.go (100%) rename {cmd => kmipcli}/downloadClientCert.go (100%) rename {cmd => kmipcli}/getClientCert.go (100%) rename {cmd => kmipcli}/getHSMInfo.go (100%) rename {cmd => kmipcli}/getKEKSetting.go (100%) rename {cmd => kmipcli}/getKmipObject.go (100%) rename {cmd => kmipcli}/getKmipObjectCount.go (100%) rename {cmd => kmipcli}/getPlatformInfo.go (100%) rename {cmd => kmipcli}/getTenantInfo.go (100%) rename {cmd => kmipcli}/getTenantSettings.go (100%) rename {cmd => kmipcli}/listClientCerts.go (100%) rename {cmd => kmipcli}/listKmipObjects.go (100%) rename {cmd => kmipcli}/locateRootKey.go (100%) rename {cmd => kmipcli}/login.go (100%) rename {cmd => kmipcli}/rekeyKEK.go (100%) rename {cmd => kmipcli}/root.go (100%) rename {cmd => kmipcli}/updateKmipObject.go (100%) rename {cmd => kmipcli}/updatePolicy.go (100%) rename {cmd => kmipcli}/updateTenantSettings.go (100%) rename {cmd => kmipcli}/version.go (100%) diff --git a/cmd/KMIPCLIutils.go b/kmipcli/KMIPCLIutils.go similarity index 100% rename from cmd/KMIPCLIutils.go rename to kmipcli/KMIPCLIutils.go diff --git a/cmd/configureHPCSKEK.go b/kmipcli/configureHPCSKEK.go similarity index 100% rename from cmd/configureHPCSKEK.go rename to kmipcli/configureHPCSKEK.go diff --git a/cmd/configureHSMKEK.go b/kmipcli/configureHSMKEK.go similarity index 100% rename from cmd/configureHSMKEK.go rename to kmipcli/configureHSMKEK.go diff --git a/cmd/createClientCert.go b/kmipcli/createClientCert.go similarity index 100% rename from cmd/createClientCert.go rename to kmipcli/createClientCert.go diff --git a/cmd/createPolicy.go b/kmipcli/createPolicy.go similarity index 100% rename from cmd/createPolicy.go rename to kmipcli/createPolicy.go diff --git a/cmd/deleteClientCert.go b/kmipcli/deleteClientCert.go similarity index 100% rename from cmd/deleteClientCert.go rename to kmipcli/deleteClientCert.go diff --git a/cmd/disableKEK.go b/kmipcli/disableKEK.go similarity index 100% rename from cmd/disableKEK.go rename to kmipcli/disableKEK.go diff --git a/cmd/downloadClientCert.go b/kmipcli/downloadClientCert.go similarity index 100% rename from cmd/downloadClientCert.go rename to kmipcli/downloadClientCert.go diff --git a/cmd/getClientCert.go b/kmipcli/getClientCert.go similarity index 100% rename from cmd/getClientCert.go rename to kmipcli/getClientCert.go diff --git a/cmd/getHSMInfo.go b/kmipcli/getHSMInfo.go similarity index 100% rename from cmd/getHSMInfo.go rename to kmipcli/getHSMInfo.go diff --git a/cmd/getKEKSetting.go b/kmipcli/getKEKSetting.go similarity index 100% rename from cmd/getKEKSetting.go rename to kmipcli/getKEKSetting.go diff --git a/cmd/getKmipObject.go b/kmipcli/getKmipObject.go similarity index 100% rename from cmd/getKmipObject.go rename to kmipcli/getKmipObject.go diff --git a/cmd/getKmipObjectCount.go b/kmipcli/getKmipObjectCount.go similarity index 100% rename from cmd/getKmipObjectCount.go rename to kmipcli/getKmipObjectCount.go diff --git a/cmd/getPlatformInfo.go b/kmipcli/getPlatformInfo.go similarity index 100% rename from cmd/getPlatformInfo.go rename to kmipcli/getPlatformInfo.go diff --git a/cmd/getTenantInfo.go b/kmipcli/getTenantInfo.go similarity index 100% rename from cmd/getTenantInfo.go rename to kmipcli/getTenantInfo.go diff --git a/cmd/getTenantSettings.go b/kmipcli/getTenantSettings.go similarity index 100% rename from cmd/getTenantSettings.go rename to kmipcli/getTenantSettings.go diff --git a/cmd/listClientCerts.go b/kmipcli/listClientCerts.go similarity index 100% rename from cmd/listClientCerts.go rename to kmipcli/listClientCerts.go diff --git a/cmd/listKmipObjects.go b/kmipcli/listKmipObjects.go similarity index 100% rename from cmd/listKmipObjects.go rename to kmipcli/listKmipObjects.go diff --git a/cmd/locateRootKey.go b/kmipcli/locateRootKey.go similarity index 100% rename from cmd/locateRootKey.go rename to kmipcli/locateRootKey.go diff --git a/cmd/login.go b/kmipcli/login.go similarity index 100% rename from cmd/login.go rename to kmipcli/login.go diff --git a/cmd/rekeyKEK.go b/kmipcli/rekeyKEK.go similarity index 100% rename from cmd/rekeyKEK.go rename to kmipcli/rekeyKEK.go diff --git a/cmd/root.go b/kmipcli/root.go similarity index 100% rename from cmd/root.go rename to kmipcli/root.go diff --git a/cmd/updateKmipObject.go b/kmipcli/updateKmipObject.go similarity index 100% rename from cmd/updateKmipObject.go rename to kmipcli/updateKmipObject.go diff --git a/cmd/updatePolicy.go b/kmipcli/updatePolicy.go similarity index 100% rename from cmd/updatePolicy.go rename to kmipcli/updatePolicy.go diff --git a/cmd/updateTenantSettings.go b/kmipcli/updateTenantSettings.go similarity index 100% rename from cmd/updateTenantSettings.go rename to kmipcli/updateTenantSettings.go diff --git a/cmd/version.go b/kmipcli/version.go similarity index 100% rename from cmd/version.go rename to kmipcli/version.go From b1fe73530a8257756121a7c509d440e323cdf5e7 Mon Sep 17 00:00:00 2001 From: Dibya Prakash Date: Fri, 27 Jun 2025 17:28:30 +0530 Subject: [PATCH 2/3] Added cmd and getpasswd folder which is commom for all cli --- cmd/ADSettings.go | 431 ++++++++++++++++++++ cmd/api.go | 632 ++++++++++++++++++++++++++++++ cmd/createLocalUser.go | 110 ++++++ cmd/createPersonalAccessToken.go | 99 +++++ cmd/deleteLocalUser.go | 91 +++++ cmd/deletePersonalAccessToken.go | 80 ++++ cmd/deletePolicy.go | 95 +++++ cmd/downloadAudit.go | 50 +++ cmd/getADGroup.go | 90 +++++ cmd/getADSettings.go | 90 +++++ cmd/getADUser.go | 90 +++++ cmd/getAuditMessageTemplate.go | 90 +++++ cmd/getAuditSettings.go | 80 ++++ cmd/getLocalUser.go | 90 +++++ cmd/getPersonalAccessToken.go | 80 ++++ cmd/getPolicy.go | 98 +++++ cmd/listAuditMessageTemplates.go | 98 +++++ cmd/listAuditMessages.go | 199 ++++++++++ cmd/listLocalUsers.go | 121 ++++++ cmd/listPersonalAccessTokens.go | 64 +++ cmd/listPolicies.go | 120 ++++++ cmd/listPolicyVersions.go | 92 +++++ cmd/renew.go | 80 ++++ cmd/setPolicyVersion.go | 97 +++++ cmd/updateAuditSettings.go | 115 ++++++ cmd/updateLocalUser.go | 117 ++++++ cmd/updatePersonalAccessToken.go | 112 ++++++ cmd/updateTenantAuthMethodToAD.go | 265 +++++++++++++ cmd/utils.go | 261 ++++++++++++ getpasswd/getpasswd_nix.go | 34 ++ getpasswd/getpasswd_windows.go | 73 ++++ 31 files changed, 4144 insertions(+) create mode 100644 cmd/ADSettings.go create mode 100644 cmd/api.go create mode 100644 cmd/createLocalUser.go create mode 100644 cmd/createPersonalAccessToken.go create mode 100644 cmd/deleteLocalUser.go create mode 100644 cmd/deletePersonalAccessToken.go create mode 100644 cmd/deletePolicy.go create mode 100644 cmd/downloadAudit.go create mode 100644 cmd/getADGroup.go create mode 100644 cmd/getADSettings.go create mode 100644 cmd/getADUser.go create mode 100644 cmd/getAuditMessageTemplate.go create mode 100644 cmd/getAuditSettings.go create mode 100644 cmd/getLocalUser.go create mode 100644 cmd/getPersonalAccessToken.go create mode 100644 cmd/getPolicy.go create mode 100644 cmd/listAuditMessageTemplates.go create mode 100644 cmd/listAuditMessages.go create mode 100644 cmd/listLocalUsers.go create mode 100644 cmd/listPersonalAccessTokens.go create mode 100644 cmd/listPolicies.go create mode 100644 cmd/listPolicyVersions.go create mode 100644 cmd/renew.go create mode 100644 cmd/setPolicyVersion.go create mode 100644 cmd/updateAuditSettings.go create mode 100644 cmd/updateLocalUser.go create mode 100644 cmd/updatePersonalAccessToken.go create mode 100644 cmd/updateTenantAuthMethodToAD.go create mode 100644 cmd/utils.go create mode 100644 getpasswd/getpasswd_nix.go create mode 100644 getpasswd/getpasswd_windows.go diff --git a/cmd/ADSettings.go b/cmd/ADSettings.go new file mode 100644 index 0000000..3bc4c0e --- /dev/null +++ b/cmd/ADSettings.go @@ -0,0 +1,431 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "bytes" + "encoding/json" + "fmt" + "os" + // external + "github.com/spf13/cobra" +) + +// UpdateADSetting command line arguments +const ( + adDomainName = "domain-name" + adSettingID = "ad-setting-id" + adSettingUIDAttribute = "uid-attribute" + adSettingType = "type" + adSettingNetBIOSName = "netbios-name" + adSettingServiceAccount = "service-account" + adSettingServicePassword = "service-password" + adSettingServersJSONFile = "servers-json-file" + adSettingRevision = "revision" +) + +type ADServer struct { + ServerURL string `json:"server_url"` + TLS bool `json:"tls,omitempty"` + UserBaseDN string `json:"user_base_dn,omitempty"` + GroupBaseDN string `json:"group_base_dn,omitempty"` + Timeout int `json:"timeout,omitempty"` + CACert string `json:"cacert,omitempty"` +} + +// UpdateADSetting REST API Request +// (and possible for CreateADSetting in the future) +type ADSetting struct { + Name string `json:"name,omitempty"` + ID string `json:"ad_setting_id,omitempty"` + Revision int `json:"revision,omitempty"` + ServiceAccount string `json:"service_account,omitempty"` + ServicePassword string `json:"service_password,omitempty"` + UIDAttribute string `json:"uid_attribute,omitempty"` + Type string `json:"type,omitempty"` + NetBIOSName string `json:"netbios_name,omitempty"` + Servers []ADServer `json:"servers,omitempty"` +} + +// listADSettingsCmd represents the list-box command +var listADSettingsCmd = &cobra.Command{ + Use: "list-ad-settings", + Short: "List all AD settings", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + if flags.Changed("prefix") { + prefix, _ := flags.GetString("prefix") + params["prefix"] = prefix + } + + if flags.Changed("filters") { + filters, _ := flags.GetString("filters") + params["filters"] = filters + } + + if flags.Changed("max-items") { + maxItems, _ := flags.GetInt("max-items") + params["max_items"] = maxItems + } + + if flags.Changed("field") { + fieldsArray, _ := flags.GetStringArray("field") + params["fields"] = fieldsArray + } + + if flags.Changed("next-token") { + nextToken, _ := flags.GetString("next-token") + params["next_token"] = nextToken + } + + // JSONify + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "ListADSettings") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nAD Settings not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func parseServersJSONFile(JSONFile string, v interface{}) error { + file, err := os.Open(JSONFile) + if err != nil { + fmt.Printf("Error opening file %s - %v\n", JSONFile, err) + return err + } + defer file.Close() + + err = json.NewDecoder(file).Decode(v) + if err != nil { + fmt.Printf("Error decoding Servers JSON - %v\n", err) + return err + } + return nil +} + +func parseCACertFile(Servers []ADServer) error { + for idx := range Servers { + if Servers[idx].CACert != "" { + encoded, err := LoadAndEncodeCACertFile(Servers[idx].CACert) + if err != nil { + fmt.Printf("%v\n", err) + return err + } + Servers[idx].CACert = encoded + } + } + return nil +} + +//////////////////////////////////////////////////////////////////////////////// +// Commmand: update-ad-setting + +// UpdateADSetting REST API Response +type updateADSettingResponse struct { + Name string `json:"name"` + ID string `json:"ad_setting_id"` + Revision int `json:"revision"` +} + +func updateADSetting(cmd *cobra.Command, args []string) { + + var adSetting ADSetting + + // Build adSetting from Command Line Arguments + flags := cmd.Flags() + + serviceAccountReset := false + adSetting.ID, _ = flags.GetString(adSettingID) + adSetting.Revision, _ = flags.GetInt(adSettingRevision) + adSetting.ServiceAccount, _ = flags.GetString(adSettingServiceAccount) + if adSetting.ServiceAccount == "unset" { + serviceAccountReset = true + } + adSetting.ServicePassword, _ = flags.GetString(adSettingServicePassword) + adSetting.UIDAttribute, _ = flags.GetString(adSettingUIDAttribute) + adSetting.Type, _ = flags.GetString(adSettingType) + adSetting.NetBIOSName, _ = flags.GetString(adSettingNetBIOSName) + + // Servers JSON + JSONFile, _ := flags.GetString(adSettingServersJSONFile) + if JSONFile != "" { + err := parseServersJSONFile(JSONFile, &adSetting.Servers) + if err != nil { + os.Exit(1) + } + // parse the CACert if provided + err = parseCACertFile(adSetting.Servers) + if err != nil { + os.Exit(1) + } + } + + // one of the AD Setting attribute must be updated + if adSetting.ServiceAccount == "" && adSetting.ServicePassword == "" && + adSetting.UIDAttribute == "" && adSetting.NetBIOSName == "" && + adSetting.Type == "" && len(adSetting.Servers) == 0 { + fmt.Printf("\nOne or more parameter(s) is missing. Usage below.\n\n") + cmd.Help() + os.Exit(1) + } + + // Encode request param into JSON + jsonParams, err := json.Marshal(adSetting) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // this is handle if service account needs to be cleared + if serviceAccountReset { + params := JsonStrToMap(string(jsonParams)) + params["service_account"] = "" + + // JSONify + jsonParams, err = json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + } + + // send request + var respData updateADSettingResponse + endpoint := GetEndPoint("", "1.0", "UpdateADSetting") + _, err = DoPost2(endpoint, GetCACertFile(), + AuthTokenKV(), + jsonParams, ContentTypeJSON, &respData, nil) + if err != nil { + fmt.Printf("\nUpdating Active Directory Setting failed:\n\n%v\n", err) + os.Exit(1) + } + + // print the response + fmt.Printf("\nActive Directory Setting updated successfully.\n") + fmt.Printf("\nRevision : %d\n", respData.Revision) + fmt.Printf("Name : %s\n", respData.Name) + fmt.Printf("ID : %s\n", respData.ID) +} + +//////////////////////////////////////////////////////////////////////////////// +// Commmand: change-ad-domain + +func changeADDomain(cmd *cobra.Command, args []string) { + + var adSetting ADSetting + + // Build adSetting from Command Line Arguments + flags := cmd.Flags() + + adSetting.Name, _ = flags.GetString(adDomainName) + adSetting.Type, _ = flags.GetString(adSettingType) + adSetting.ServiceAccount, _ = flags.GetString(adSettingServiceAccount) + adSetting.ServicePassword, _ = flags.GetString(adSettingServicePassword) + adSetting.UIDAttribute, _ = flags.GetString(adSettingUIDAttribute) + adSetting.NetBIOSName, _ = flags.GetString(adSettingNetBIOSName) + + // Servers JSON + JSONFile, _ := flags.GetString(adSettingServersJSONFile) + if JSONFile != "" { + err := parseServersJSONFile(JSONFile, &adSetting.Servers) + if err != nil { + os.Exit(1) + } + // parse the CACert if provided + err = parseCACertFile(adSetting.Servers) + if err != nil { + os.Exit(1) + } + } + + // Encode request param into JSON + jsonParams, err := json.Marshal(adSetting) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // send request + var respData updateADSettingResponse + endpoint := GetEndPoint("", "1.0", "ChangeADDomain") + _, err = DoPost2(endpoint, GetCACertFile(), + AuthTokenKV(), + jsonParams, ContentTypeJSON, &respData, nil) + if err != nil { + fmt.Printf("\nChanging AD Domain failed:\n\n%v\n", err) + os.Exit(1) + } + + // print the response + fmt.Printf("\nAD Domain changed successfully.\n") + fmt.Printf("\nRevision : %d\n", respData.Revision) + fmt.Printf("Name : %s\n", respData.Name) + fmt.Printf("ID : %s\n", respData.ID) +} + +func init() { + // Commmand: list-ad-setting + rootCmd.AddCommand(listADSettingsCmd) + listADSettingsCmd.Flags().StringP("prefix", "p", "", + "List only those AD settings prefixed with this "+ + "string") + listADSettingsCmd.Flags().StringP("filters", "l", "", + "Conditional expression to filter "+ + "AD settings") + listADSettingsCmd.Flags().IntP("max-items", "m", 0, + "Maximum number of items to include in "+ + "response") + listADSettingsCmd.Flags().StringArrayP("field", "f", []string{}, + "AD setting fields to include in the response") + listADSettingsCmd.Flags().StringP("next-token", "n", "", + "Token from which subsequent AD settings would "+ + "be listed") + + // Commmand: update-ad-setting + var updateADSettingsCommand = &cobra.Command{ + Use: "update-ad-settings", + Short: "Update Active Directory Settings", + Run: updateADSetting, + } + updateADSettingsCommand.Flags().StringP(adSettingID, "a", "", + "Active Directory Setting ID or Name") + updateADSettingsCommand.Flags().StringP(adSettingUIDAttribute, "u", "", + "Active Directory UID Attribute") + updateADSettingsCommand.Flags().StringP(adSettingType, "t", "", + "Domain type") + updateADSettingsCommand.Flags().StringP(adSettingNetBIOSName, "n", "", + "Active Directory NetBIOS name") + updateADSettingsCommand.Flags().StringP(adSettingServiceAccount, "s", "", + "Active Directory Service Account User Name. " + + "To clear, set it to \"unset\".") + updateADSettingsCommand.Flags().StringP(adSettingServicePassword, "p", "", + "Active Directory Service Account Password") + updateADSettingsCommand.Flags().StringP(adSettingServersJSONFile, "j", "", + "Active Directory Domain Controller List JSON File. This is to be " + + "a array of JSON objects, each object representing a Domain Controller. " + + "Following keys are supported, \n" + + "server_url (mandatory) full url of the Domain Controller\n" + + "cacert (optional) path to CA Certificiate to verify with\n" + + "user_base_dn (optional) user base DN\n" + + "group_base_dn (optional) group base DN\n" + + "timeout (optional) connection timeout in seconds, defaults to 5 seconds\n" + + "tls (optional) enable StartTLS or not, defaults to false\n" + + "\n" + + "Example: \n" + + "\n" + + "[\n" + + " {\n" + + " \"server_url\": \"ldaps://dc1.mycompany.eng.com\",\n" + + " \"cacert\": \"/root/cacert.pem\",\n" + + " \"user_base_dn\": \"DC=mycompany,DC=eng,DC=com\",\n" + + " \"group_base_dn\": \"DC=mycompany,DC=eng,DC=com\",\n" + + " \"timeout\": 10,\n" + + " \"tls\": false,\n" + + " }\n" + + "]\n") + updateADSettingsCommand.Flags().IntP(adSettingRevision, "r", 0, + "Active Directory Setting Current Revision") + // mark mandatory fields as required + updateADSettingsCommand.MarkFlagRequired(adSettingID) + updateADSettingsCommand.MarkFlagRequired(adSettingRevision) + rootCmd.AddCommand(updateADSettingsCommand) + + // Commmand: change-ad-domain + var changeADDomainCommand = &cobra.Command{ + Use: "change-ad-domain", + Short: "Change Active Directory Domain", + Run: changeADDomain, + } + changeADDomainCommand.Flags().StringP(adDomainName, "d", "", + "Active Directory Domain Name") + changeADDomainCommand.Flags().StringP(adSettingUIDAttribute, "u", "", + "Active Directory UID Attribute") + changeADDomainCommand.Flags().StringP(adSettingType, "t", "", + "Domain type") + changeADDomainCommand.Flags().StringP(adSettingNetBIOSName, "n", "", + "Active Directory NetBIOS name") + changeADDomainCommand.Flags().StringP(adSettingServiceAccount, "s", "", + "Active Directory Service Account User Name. " + + "To clear, set it to \"unset\".") + changeADDomainCommand.Flags().StringP(adSettingServicePassword, "p", "", + "Active Directory Service Account Password") + changeADDomainCommand.Flags().StringP(adSettingServersJSONFile, "j", "", + "Active Directory Domain Controller List JSON File. This is to be " + + "a array of JSON objects, each object representing a Domain Controller. " + + "Following keys are supported, \n" + + "server_url (mandatory) full url of the Domain Controller\n" + + "cacert (optional) path to CA Certificiate to verify with\n" + + "user_base_dn (optional) user base DN\n" + + "group_base_dn (optional) group base DN\n" + + "timeout (optional) connection timeout in seconds, defaults to 5 seconds\n" + + "tls (optional) enable StartTLS or not, defaults to false\n" + + "\n" + + "Example: \n" + + "\n" + + "[\n" + + " {\n" + + " \"server_url\": \"ldaps://dc1.mycompany.eng.com\",\n" + + " \"cacert\": \"/root/cacert.pem\",\n" + + " \"user_base_dn\": \"DC=mycompany,DC=eng,DC=com\",\n" + + " \"group_base_dn\": \"DC=mycompany,DC=eng,DC=com\",\n" + + " \"timeout\": 10,\n" + + " \"tls\": false,\n" + + " }\n" + + "]\n") + // mark mandatory fields as required + changeADDomainCommand.MarkFlagRequired(adDomainName) + changeADDomainCommand.MarkFlagRequired(adSettingType) + changeADDomainCommand.MarkFlagRequired(adSettingServersJSONFile) + changeADDomainCommand.MarkFlagRequired(adSettingUIDAttribute) + rootCmd.AddCommand(changeADDomainCommand) +} diff --git a/cmd/api.go b/cmd/api.go new file mode 100644 index 0000000..4966760 --- /dev/null +++ b/cmd/api.go @@ -0,0 +1,632 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "encoding/json" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "os" + "regexp" + "strings" +) + +// ContentTypeJSON defines JSON content type +const ( + ContentTypeJSON = "application/json" +) + +// DoPostFormData sends an API request +func DoPostFormData(endpoint string, + cacert string, + headers map[string]string, + jsonParams []byte, + contentType string) (map[string]interface{}, error) { + + params := map[string]interface{}{} + json.Unmarshal(jsonParams, ¶ms) + values := map[string]io.Reader{} + + if _, keyPresent := params["public_key"]; keyPresent { + values["public_key"] = mustOpen(params["public_key"].(string)) + } + if _, keyPresent := params["csv_file"]; keyPresent { + values["csv_file"] = mustOpen(params["csv_file"].(string)) + } + if _, keyPresent := params["secret_type"]; keyPresent { + values["secret_type"] = strings.NewReader(params["secret_type"].(string)) + } + var b bytes.Buffer + var err error + w := multipart.NewWriter(&b) + for key, r := range values { + var fw io.Writer + if x, ok := r.(io.Closer); ok { + defer x.Close() + } + if x, ok := r.(*os.File); ok { + if fw, err = w.CreateFormFile(key, x.Name()); err != nil { + // this is to avoid Go's unused error message + _ = fw + return nil, err + } + } else { + if fw, err = w.CreateFormField(key); err != nil { + // this is to avoid Go's unused error message + _ = fw + return nil, err + } + } + if _, err := io.Copy(fw, r); err != nil { + return nil, err + } + } + w.Close() + request, err := http.NewRequest("POST", endpoint, &b) + if err != nil { + return nil, err + } + + // close connection once done + request.Close = true + request.Header.Set("Content-Type", w.FormDataContentType()) + for header, value := range headers { + request.Header.Set(header, value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + // Create a CA certificate pool and add cacert to it + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + ret := map[string]interface{}{} + response, err := client.Do(request) + if err != nil { + return ret, err + } else { + data, _ := io.ReadAll(response.Body) + dst := &bytes.Buffer{} + if len(data) != 0 { + if err := json.Indent(dst, data, "", " "); err != nil { + // probably this is not of json format, print & exit + fmt.Println("\n" + string(data) + "\n") + os.Exit(4) + } + } + + ret["status"] = response.StatusCode + ret["data"] = dst + return ret, nil + } +} + +func mustOpen(f string) *os.File { + r, err := os.Open(f) + if err != nil { + panic(err) + } + return r +} + +// DoGet sends an API request +func DoGet(endpoint string, + cacert string, + headers map[string]string, + jsonParams []byte, + contentType string) (map[string]interface{}, error) { + request, _ := http.NewRequest("GET", endpoint, bytes.NewBuffer(jsonParams)) + + // close connection once done + request.Close = true + request.Header.Set("Content-Type", contentType) + for header, value := range headers { + request.Header.Set(header, value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + // Create a CA certificate pool and add cacert to it + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + ret := map[string]interface{}{} + response, err := client.Do(request) + if err != nil { + return ret, err + } else { + data, _ := io.ReadAll(response.Body) + dst := &bytes.Buffer{} + if len(data) != 0 { + if err := json.Indent(dst, data, "", " "); err != nil { + // probably this is not of json format, print & exit + fmt.Println("\n" + string(data) + "\n") + os.Exit(4) + } + } + + ret["status"] = response.StatusCode + ret["data"] = dst + return ret, nil + } +} + +// DoDelete sends an API request +func DoDelete(endpoint string, + cacert string, + headers map[string]string, + jsonParams []byte, + contentType string) (map[string]interface{}, error) { + request, _ := http.NewRequest("DELETE", endpoint, bytes.NewBuffer(jsonParams)) + + // close connection once done + request.Close = true + request.Header.Set("Content-Type", contentType) + for header, value := range headers { + request.Header.Set(header, value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + // Create a CA certificate pool and add cacert to it + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + ret := map[string]interface{}{} + response, err := client.Do(request) + if err != nil { + return ret, err + } else { + data, _ := io.ReadAll(response.Body) + dst := &bytes.Buffer{} + if len(data) != 0 { + if err := json.Indent(dst, data, "", " "); err != nil { + // probably this is not of json format, print & exit + fmt.Println("\n" + string(data) + "\n") + os.Exit(4) + } + } + + ret["status"] = response.StatusCode + ret["data"] = dst + return ret, nil + } +} + +func DoPatch(endpoint string, + cacert string, + headers map[string]string, + jsonParams []byte, + contentType string) (map[string]interface{}, error) { + request, _ := http.NewRequest("PATCH", endpoint, bytes.NewBuffer(jsonParams)) + + request.Close = true + request.Header.Set("Content-Type", contentType) + for header, value := range headers { + request.Header.Set(header, value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + ret := map[string]interface{}{} + response, err := client.Do(request) + if err != nil { + return ret, err + } + data, _ := io.ReadAll(response.Body) + dst := &bytes.Buffer{} + if len(data) != 0 { + if err := json.Indent(dst, data, "", " "); err != nil { + fmt.Println("\n" + string(data) + "\n") + os.Exit(4) + } + } + + ret["status"] = response.StatusCode + ret["data"] = dst + return ret, nil +} + +// DoPost sends an API request +func DoPost(endpoint string, + cacert string, + headers map[string]string, + jsonParams []byte, + contentType string) (map[string]interface{}, error) { + request, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonParams)) + + // close connection once done + request.Close = true + request.Header.Set("Content-Type", contentType) + for header, value := range headers { + request.Header.Set(header, value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + // Create a CA certificate pool and add cacert to it + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + ret := map[string]interface{}{} + response, err := client.Do(request) + if err != nil { + return ret, err + } else { + data, _ := io.ReadAll(response.Body) + dst := &bytes.Buffer{} + if len(data) != 0 { + if err := json.Indent(dst, data, "", " "); err != nil { + // probably this is not of json format, print & exit + fmt.Println("\n" + string(data) + "\n") + os.Exit(4) + } + } + + ret["status"] = response.StatusCode + ret["data"] = dst + return ret, nil + } +} + +// APIError contains error details of API request failure +type APIError struct { + RequestURL string + HttpStatusCode int // e.g. 200 + HttpStatus string // e.g. "200 OK" + ErrorJSON []byte // Error Message from the Server +} + +func (e APIError) Error() string { + if len(e.ErrorJSON) > 0 { + return fmt.Sprintf("%s\n%s\n%s", e.RequestURL, e.HttpStatus, + string(e.ErrorJSON)) + } + return fmt.Sprintf("%s\n%s", e.RequestURL, e.HttpStatus) +} + +func newAPIError(requestURL string, response *http.Response) APIError { + + var apiError APIError + apiError.RequestURL = requestURL + apiError.HttpStatusCode = response.StatusCode + apiError.HttpStatus = response.Status + contentType := response.Header.Get("Content-Type") + if contentType == ContentTypeJSON { + apiError.ErrorJSON, _ = io.ReadAll(response.Body) + } + return apiError +} + +// ResponseHandler can process the HTTP Response fully +type ResponseHandler interface { + ProcessResponse(response *http.Response, responseData interface{}, + request *http.Request, requestURL string) (interface{}, error) +} + +// DoPost2 sends an API request +func DoPost2(endpoint string, + cacert string, + headers map[string]string, + jsonParams []byte, + contentType string, + responseData interface{}, + respCallback ResponseHandler) (interface{}, error) { + + request, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonParams)) + + // close connection once done + request.Close = true + request.Header.Set("Content-Type", contentType) + for header, value := range headers { + request.Header.Set(header, value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + // Create a CA certificate pool and add cacert to it + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + response, err := client.Do(request) + if err != nil { + return nil, err + } + + // invoke ResponseHandler if provided + if cb, ok := respCallback.(ResponseHandler); ok { + return cb.ProcessResponse(response, responseData, request, endpoint) + } + + switch response.StatusCode { + case http.StatusOK, http.StatusCreated: + if responseData == nil { + return io.ReadAll(response.Body) + } + + contentType := response.Header.Get("Content-Type") + if contentType != ContentTypeJSON { + return nil, fmt.Errorf("Invalid Content-Type: %v", contentType) + } + return nil, json.NewDecoder(response.Body).Decode(responseData) + + default: + return nil, newAPIError(endpoint, response) + } +} + +// DoDownload sends an API request +func DoDownload(endpoint string, + method string, + cacert string, + headers map[string]string, + jsonParams []byte) (string, error) { + request, _ := http.NewRequest(method, endpoint, bytes.NewBuffer(jsonParams)) + // close connection once done + request.Close = true + + for header, value := range headers { + request.Header.Set(header, value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + // Create a CA certificate pool and add cacert to it + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + response, err := client.Do(request) + if err != nil { + return "", err + } else { + // server responded with some error - capture & exit + if response.StatusCode != 200 { + data, _ := io.ReadAll(response.Body) + fmt.Println("\n" + string(data) + "\n") + os.Exit(3) + } + + fname, err := GetValueFromKVString( + response.Header.Get("Content-Disposition"), "filename") + if err != nil { + return "", err + } + + // create file + outFile, err := os.Create(fname) + if err != nil { + return "", err + } + defer outFile.Close() + + // write body to file + _, err = io.Copy(outFile, response.Body) + if err != nil { + return "", err + } + return fname, nil + } +} + +// DoGetDownload sends an API request +func DoGetDownload(endpoint string, + cacert string, + headers map[string]string) (string, error) { + request, _ := http.NewRequest("GET", endpoint, nil) + // close connection once done + request.Close = true + + for header, value := range headers { + request.Header.Set(string(header), value) + } + + client := &http.Client{} + tr := &http.Transport{} + if cacert != "" { + // Create a CA certificate pool and add cacert to it + caCert, err := os.ReadFile(cacert) + if err != nil { + fmt.Println("Error reading CA Certificate: ", err) + os.Exit(1) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + tr.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + fmt.Println("\n###############################################################################\n" + + "Insecure request. Entrust Vault certificate not verified. \n" + + "It is strongly recommended to verify the same by specifying CA \n" + + "Certificate, using the --cacert option, to mitigate Man-in-the-middle attack\n" + + "###############################################################################") + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + client.Transport = tr + response, err := client.Do(request) + if err != nil { + return "", err + } else { + // server responded with some error - capture & exit + if response.StatusCode != 200 { + data, _ := io.ReadAll(response.Body) + fmt.Println("\n" + string(data) + "\n") + os.Exit(3) + } + + fname, err := GetValueFromKVString( + response.Header.Get("Content-Disposition"), "filename") + if err != nil { + return "", err + } + + // create file + outFile, err := os.Create(fname) + if err != nil { + return "", err + } + defer outFile.Close() + + // write body to file + _, err = io.Copy(outFile, response.Body) + if err != nil { + return "", err + } + return fname, nil + } +} + +func GetValueFromKVString(kvString string, key string) (string, error) { + regex := fmt.Sprintf("(%s)=([a-z]+)", key) + re := regexp.MustCompile(regex) + result := re.FindAllStringSubmatchIndex(kvString, -1) + if len(result) == 0 || len(result[0]) < 5 { + errMsg := fmt.Sprintf("%s not found", key) + return "", errors.New(errMsg) + } + match := result[0] + return string(kvString[match[4]:]), nil +} diff --git a/cmd/createLocalUser.go b/cmd/createLocalUser.go new file mode 100644 index 0000000..8aacc8b --- /dev/null +++ b/cmd/createLocalUser.go @@ -0,0 +1,110 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + +// error checking for exceeding 256 chars +func charCheck(length int) { + if (length > 256) { + fmt.Println("Exceeded 256 characters. Please provide an " + + "input length <= 256 characters") + os.Exit(1) + } +} + +// createLocalUserCmd represents the create-local-user command +var createLocalUserCmd = &cobra.Command{ + Use: "create-local-user", + Short: "Create a Local User", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + params["account_state"] = true + + email, _ := flags.GetString("email") + charCheck(len(email)) + params["email"] = email + + name, _ := flags.GetString("name") + charCheck(len(name)) + params["name"] = name + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "CreateLocalUser") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + fmt.Println("Local user successfully created for", name, + "with username", email, "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(createLocalUserCmd) + createLocalUserCmd.Flags().StringP("email", "e", "", + "Email of the User") + createLocalUserCmd.Flags().StringP("name", "n", "", + "Full name of the user") + + // mark mandatory fields as required + createLocalUserCmd.MarkFlagRequired("email") + createLocalUserCmd.MarkFlagRequired("name") +} diff --git a/cmd/createPersonalAccessToken.go b/cmd/createPersonalAccessToken.go new file mode 100644 index 0000000..b71b67d --- /dev/null +++ b/cmd/createPersonalAccessToken.go @@ -0,0 +1,99 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/spf13/cobra" + "os" + "time" +) + +var createPersonalAccessTokenCmd = &cobra.Command{ + Use: "create-personal-access-token", + Short: "Create a Personal Access Token", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + name, _ := flags.GetString("name") + params["name"] = name + + if flags.Changed("description") { + description, _ := flags.GetString("description") + params["description"] = description + } + + expiry, _ := flags.GetString("expiry") + expiry = expiry + "T10:00:00Z" + thetime, e := time.Parse(time.RFC3339, expiry) + if e != nil { + panic("Can't parse time format\n") + } + params["expiry"] = thetime.Unix() + + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + endpoint := GetEndPoint("", "1.0", "CreatePersonalAccessToken") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("\n" + retStr + "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(createPersonalAccessTokenCmd) + createPersonalAccessTokenCmd.Flags().StringP("description", "d", "", + "Description of personal access token") + createPersonalAccessTokenCmd.Flags().StringP("name", "n", "", + "Name of personal access token") + createPersonalAccessTokenCmd.Flags().StringP("expiry", "e", "", + "Date on which personal access token expires in yyyy-mm-dd format") + + createPersonalAccessTokenCmd.MarkFlagRequired("name") + createPersonalAccessTokenCmd.MarkFlagRequired("expiry") +} diff --git a/cmd/deleteLocalUser.go b/cmd/deleteLocalUser.go new file mode 100644 index 0000000..7000fe6 --- /dev/null +++ b/cmd/deleteLocalUser.go @@ -0,0 +1,91 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// deleteUserCmd represents the delete-local-user command +var deleteUserCmd = &cobra.Command{ + Use: "delete-local-user", + Short: "Delete a Local User", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + user, _ := flags.GetString("user") + charCheck(len(user)) + params["username"] = user + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "DeleteLocalUser") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("Local user successfully deleted for with username/ID", user, "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(deleteUserCmd) + deleteUserCmd.Flags().StringP("user", "u", "", + "Username of the user to be deleted.") + + // mark mandatory fields as required + deleteUserCmd.MarkFlagRequired("user") +} diff --git a/cmd/deletePersonalAccessToken.go b/cmd/deletePersonalAccessToken.go new file mode 100644 index 0000000..c4a27f1 --- /dev/null +++ b/cmd/deletePersonalAccessToken.go @@ -0,0 +1,80 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/spf13/cobra" + "os" +) + +var deletePersonalAccessTokenCmd = &cobra.Command{ + Use: "delete-personal-access-token", + Short: "Delete a Personal Access Token", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + name, _ := flags.GetString("name") + params["name"] = name + + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + endpoint := GetEndPoint("", "1.0", "DeletePersonalAccessToken") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("\n" + retStr + "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(deletePersonalAccessTokenCmd) + deletePersonalAccessTokenCmd.Flags().StringP("name", "n", "", + "Name of personal access token") + + deletePersonalAccessTokenCmd.MarkFlagRequired("name") +} diff --git a/cmd/deletePolicy.go b/cmd/deletePolicy.go new file mode 100644 index 0000000..c332542 --- /dev/null +++ b/cmd/deletePolicy.go @@ -0,0 +1,95 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// deletePolicyCmd represents the delete-policy command +var deletePolicyCmd = &cobra.Command{ + Use: "delete-policy", + Short: "Delete Policy", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + policyid, _ := flags.GetString("policyid") + params["policy_id"] = policyid + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "DeletePolicy") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nPolicy not found\n") + os.Exit(5) + } + + if retStatus == 200 { + fmt.Println("\nPolicy deleted successfully\n") + os.Exit(0) + } else { + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(100) + } + } + } + }, +} + +func init() { + rootCmd.AddCommand(deletePolicyCmd) + deletePolicyCmd.Flags().StringP("policyid", "p", "", + "Id or name of the Policy to be deleted") + + // mark mandatory fields as required + deletePolicyCmd.MarkFlagRequired("policyid") +} diff --git a/cmd/downloadAudit.go b/cmd/downloadAudit.go new file mode 100644 index 0000000..a04d43b --- /dev/null +++ b/cmd/downloadAudit.go @@ -0,0 +1,50 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + // external + "github.com/spf13/cobra" +) + + +// downloadAuditCmd represents the download-audit command +var downloadAuditCmd = &cobra.Command{ + Use: "download-audit", + Short: "Download audit log bundle", + Run: func(cmd *cobra.Command, args []string) { + + // now GET + endpoint := GetEndPoint("", "1.0", "GetAuditBundle") + fname, err := DoGetDownload(endpoint, GetCACertFile(), + AuthTokenKV()) + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + fmt.Println("\nSuccessfully downloaded audit log bundle " + + "as - " + fname + "\n") + } + }, +} + +func init() { + rootCmd.AddCommand(downloadAuditCmd) +} diff --git a/cmd/getADGroup.go b/cmd/getADGroup.go new file mode 100644 index 0000000..75db2ac --- /dev/null +++ b/cmd/getADGroup.go @@ -0,0 +1,90 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// getADGroupCmd represents the get-ad-group command +var getADGroupCmd = &cobra.Command{ + Use: "get-ad-group", + Short: "Search Active Directory group", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + ADGroupname, _ := flags.GetString("name") + params["name"] = ADGroupname + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetADGroup") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nNo AD User(s) found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getADGroupCmd) + getADGroupCmd.Flags().StringP("name", "n", "", + "Prefix of the group name for searching") + + // mark mandatory fields as required + getADGroupCmd.MarkFlagRequired("name") +} diff --git a/cmd/getADSettings.go b/cmd/getADSettings.go new file mode 100644 index 0000000..787b393 --- /dev/null +++ b/cmd/getADSettings.go @@ -0,0 +1,90 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// getADSettingsCmd represents the get-ad-settings command +var getADSettingsCmd = &cobra.Command{ + Use: "get-ad-settings", + Short: "Get AD Setting details", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + ADSettingID, _ := flags.GetString("ad-setting-id") + params["ad_setting_id"] = ADSettingID + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetADSetting") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAD setting not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getADSettingsCmd) + getADSettingsCmd.Flags().StringP("ad-setting-id", "a", "", + "Id or name of the AD Setting to get") + + // mark mandatory fields as required + getADSettingsCmd.MarkFlagRequired("ad-setting-id") +} diff --git a/cmd/getADUser.go b/cmd/getADUser.go new file mode 100644 index 0000000..2089c92 --- /dev/null +++ b/cmd/getADUser.go @@ -0,0 +1,90 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// getADUserCmd represents the get-ad-user command +var getADUserCmd = &cobra.Command{ + Use: "get-ad-user", + Short: "Search Active Directory users", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + ADUsername, _ := flags.GetString("name") + params["name"] = ADUsername + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetADUser") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nNo AD User(s) found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getADUserCmd) + getADUserCmd.Flags().StringP("name", "n", "", + "Prefix of the username for searching") + + // mark mandatory fields as required + getADUserCmd.MarkFlagRequired("name") +} diff --git a/cmd/getAuditMessageTemplate.go b/cmd/getAuditMessageTemplate.go new file mode 100644 index 0000000..26f9f00 --- /dev/null +++ b/cmd/getAuditMessageTemplate.go @@ -0,0 +1,90 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// getAuditMessageTemplateCmd represents the get-audit-message-template command +var getAuditMessageTemplateCmd = &cobra.Command{ + Use: "get-audit-message-template", + Short: "Given a message id, get corresponding audit message template", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + msgid, _ := flags.GetInt("msgid") + params["message_id"] = msgid + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetAuditMessageTemplate") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAD message template not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getAuditMessageTemplateCmd) + getAuditMessageTemplateCmd.Flags().IntP("msgid", "m", 0, + "Message id of audit message template to fetch") + + // mark mandatory fields as required + getAuditMessageTemplateCmd.MarkFlagRequired("msgid") +} diff --git a/cmd/getAuditSettings.go b/cmd/getAuditSettings.go new file mode 100644 index 0000000..89ded96 --- /dev/null +++ b/cmd/getAuditSettings.go @@ -0,0 +1,80 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// getAuditSettingsCmd represents the get-audit-settings command +var getAuditSettingsCmd = &cobra.Command{ + Use: "get-audit-settings", + Short: "Get audit settings", + Run: func(cmd *cobra.Command, args []string) { + params := map[string]interface{}{} + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetAuditSetting") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAudit settings not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getAuditSettingsCmd) +} diff --git a/cmd/getLocalUser.go b/cmd/getLocalUser.go new file mode 100644 index 0000000..c8eeb4c --- /dev/null +++ b/cmd/getLocalUser.go @@ -0,0 +1,90 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// getLocalUserCmd represents the get-local-user command +var getLocalUserCmd = &cobra.Command{ + Use: "get-local-user", + Short: "Get Local User details", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + user, _ := flags.GetString("user") + params["username"] = user + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetLocalUser") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("\n" + retStr + "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getLocalUserCmd) + getLocalUserCmd.Flags().StringP("user", "u", "", + "Username of the local user") + + // mark mandatory fields as required + getLocalUserCmd.MarkFlagRequired("user") +} diff --git a/cmd/getPersonalAccessToken.go b/cmd/getPersonalAccessToken.go new file mode 100644 index 0000000..2d1ab11 --- /dev/null +++ b/cmd/getPersonalAccessToken.go @@ -0,0 +1,80 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/spf13/cobra" + "os" +) + +var getPersonalAccessTokenCmd = &cobra.Command{ + Use: "get-personal-access-token", + Short: "Get Personal Access Token details", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + name, _ := flags.GetString("name") + params["name"] = name + + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + endpoint := GetEndPoint("", "1.0", "GetPersonalAccessToken") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("\n" + retStr + "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getPersonalAccessTokenCmd) + getPersonalAccessTokenCmd.Flags().StringP("name", "n", "", + "Name of personal access token") + + getPersonalAccessTokenCmd.MarkFlagRequired("name") +} diff --git a/cmd/getPolicy.go b/cmd/getPolicy.go new file mode 100644 index 0000000..d6446ce --- /dev/null +++ b/cmd/getPolicy.go @@ -0,0 +1,98 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// getPolicyCmd represents the get-policy command +var getPolicyCmd = &cobra.Command{ + Use: "get-policy", + Short: "Get Policy details", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + policyid, _ := flags.GetString("policyid") + params["policy_id"] = policyid + + if flags.Changed("version") { + version, _ := flags.GetInt("version") + params["version"] = version + } + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetPolicy") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nPolicy not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getPolicyCmd) + getPolicyCmd.Flags().StringP("policyid", "p", "", + "Id or name of the Policy to get") + getPolicyCmd.Flags().IntP("version", "v", 0, + "Version of the Policy to fetch. If not " + + "specified, fetches the current version") + + // mark mandatory fields as required + getPolicyCmd.MarkFlagRequired("policyid") +} diff --git a/cmd/listAuditMessageTemplates.go b/cmd/listAuditMessageTemplates.go new file mode 100644 index 0000000..1d625b5 --- /dev/null +++ b/cmd/listAuditMessageTemplates.go @@ -0,0 +1,98 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// listAuditMessageTemplatesCmd represents the list-audit-message command +var listAuditMessageTemplatesCmd = &cobra.Command{ + Use: "list-audit-message-templates", + Short: "List available audit messages templates", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + if flags.Changed("max-items") { + maxItems, _ := flags.GetInt("max-items") + params["max_items"] = maxItems + } + + if flags.Changed("next-token") { + nextToken, _ := flags.GetString("next-token") + params["next_token"] = nextToken + } + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "ListAuditMessageTemplates") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAudit message templates not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(listAuditMessageTemplatesCmd) + listAuditMessageTemplatesCmd.Flags().IntP("max-items", "m", 0, + "Maximum number of items to include in " + + "response") + listAuditMessageTemplatesCmd.Flags().StringP("next-token", "n", "", + "Token from which subsequent Audit " + + "messages would be listed") +} diff --git a/cmd/listAuditMessages.go b/cmd/listAuditMessages.go new file mode 100644 index 0000000..436270c --- /dev/null +++ b/cmd/listAuditMessages.go @@ -0,0 +1,199 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + + "bytes" + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + "time" + // external + "github.com/spf13/cobra" +) + +const ( + listAuditOptionJSONOutput = "json-output" + listAuditOptionIncludeInfo = "include-info" + listAuditOptionLocalTime = "local-time" +) + +type auditMessage struct { + CreatedAt string `json:"created_at"` + UserContext string `json:"user_context"` + Message string `json:"message"` + Info map[string]interface{} `json:"info,omitempty"` +} + +type listAuditMessagesResponse struct { + Messages []auditMessage `json:"audit_messages"` +} + +func printAuditMessages(data []byte, cmd *cobra.Command) { + flags := cmd.Flags() + + // JSON output + if ok, _ := flags.GetBool(listAuditOptionJSONOutput); ok { + dst := &bytes.Buffer{} + if err := json.Indent(dst, data, "", " "); err != nil { + // probably this is not of json format, print & exit + fmt.Println(string(data)) + os.Exit(4) + } else { + fmt.Println(dst.String()) + } + return + } + + // text line-by-line custom output + // without additional info: + // (timestamp user-context message) + // with additional info: + // (timestamp user-context message) + // name: value + // name: value + var resp listAuditMessagesResponse + err := json.Unmarshal(data, &resp) + if err != nil { + fmt.Printf("\nInvalid response - %v\n", err) + return + } + + includeInfo, _ := flags.GetBool(listAuditOptionIncludeInfo) + localTime, _ := flags.GetBool(listAuditOptionLocalTime) + var location *time.Location + if localTime { + location, err = time.LoadLocation("Local") + if err != nil { + // lets print timestamp in UTC instead of failing the call + localTime = false + } + } + + for _, msg := range resp.Messages { + var createdAt time.Time + createdAt, err = time.Parse(time.RFC3339, msg.CreatedAt) + if err != nil { + continue + } + + var ts string + if localTime { + createdAt = createdAt.In(location) + ts = createdAt.Format(time.RFC1123) + } else { + ts = createdAt.Format(time.RFC1123) + } + + fmt.Printf("%s %s %s\n", ts, msg.UserContext, msg.Message) + if !includeInfo || msg.Info == nil { + continue + } + for name, value := range msg.Info { + fmt.Printf("%s: %v\n", name, value) + } + } +} + +func listAuditMessageAPI(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + if flags.Changed("filters") { + filters, _ := flags.GetString("filters") + params["filters"] = filters + } + + if flags.Changed("max-items") { + maxItems, _ := flags.GetInt("max-items") + params["max_items"] = maxItems + } + + if flags.Changed("field") { + fieldsArray, _ := flags.GetStringArray("field") + params["fields"] = fieldsArray + } + + if flags.Changed("next-token") { + nextToken, _ := flags.GetString("next-token") + params["next_token"] = nextToken + } + + // JSONify + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "ListAuditMessages") + ret, err := DoPost2(endpoint, GetCACertFile(), + AuthTokenKV(), + jsonParams, ContentTypeJSON, nil, nil) + if err != nil { + var apiError APIError + if errors.As(err, &apiError) && apiError.HttpStatusCode == http.StatusNotFound { + fmt.Println("\nAudit messages not found\n") + os.Exit(5) + } + fmt.Printf("\nHTTP request failed:\n%v\n", err) + os.Exit(4) + } else { + data := ret.([]byte) + if len(data) == 0 { + fmt.Printf("\nEmpty response\n") + os.Exit(3) + } else { + printAuditMessages(data, cmd) + os.Exit(0) + } + } +} + +// listAuditMessagesCmd represents the list-audit-message command +var listAuditMessagesCmd = &cobra.Command{ + Use: "list-audit-messages", + Short: "List all audit messages", + Run: listAuditMessageAPI, +} + +func init() { + rootCmd.AddCommand(listAuditMessagesCmd) + listAuditMessagesCmd.Flags().StringP("filters", "l", "", + "Conditional filter expression to apply") + listAuditMessagesCmd.Flags().IntP("max-items", "m", 0, + "Maximum number of items to include in "+ + "response") + listAuditMessagesCmd.Flags().StringArrayP("field", "f", []string{}, + "Audit message fields to include "+ + "in the response") + listAuditMessagesCmd.Flags().StringP("next-token", "n", "", + "Token from which subsequent Audit "+ + "messages would be listed") + listAuditMessagesCmd.Flags().BoolP(listAuditOptionJSONOutput, "j", false, + "Show JSON formatted audit messages") + listAuditMessagesCmd.Flags().BoolP(listAuditOptionIncludeInfo, "i", false, + "Show Additional Information if available") + listAuditMessagesCmd.Flags().BoolP(listAuditOptionLocalTime, "t", false, + "Convert audit message timestamp to local time.") +} diff --git a/cmd/listLocalUsers.go b/cmd/listLocalUsers.go new file mode 100644 index 0000000..a8375a1 --- /dev/null +++ b/cmd/listLocalUsers.go @@ -0,0 +1,121 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "encoding/json" + "bytes" + + // external + "github.com/spf13/cobra" +) + + +// listLocalUsersCmd represents the list-local-users command +var listLocalUsersCmd = &cobra.Command{ + Use: "list-local-users", + Short: "List all Local Users", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + if flags.Changed("prefix") { + prefix, _ := flags.GetString("prefix") + params["prefix"] = prefix + } + + if flags.Changed("filters") { + filters, _ := flags.GetString("filters") + params["filters"] = filters + } + + if flags.Changed("max-items") { + maxItems, _ := flags.GetInt("max-items") + params["max_items"] = maxItems + } + + if flags.Changed("fields") { + fieldsArray, _ := flags.GetStringArray("fields") + params["fields"] = fieldsArray + } + + if flags.Changed("next-token") { + nextToken, _ := flags.GetString("next-token") + params["next_token"] = nextToken + } + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "ListLocalUsers") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("\n" + retStr + "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(listLocalUsersCmd) + listLocalUsersCmd.Flags().StringP("prefix", "p", "", + "Prefix to list Users with") + listLocalUsersCmd.Flags().StringP("filters", "l", "", + "Conditional expression to list filtered " + + "users") + listLocalUsersCmd.Flags().IntP("max-items", "m", 0, + "Maximum number of items to include " + + "in the response") + listLocalUsersCmd.Flags().StringArrayP("fields", "f", []string{}, + "Fields to include in the response") + listLocalUsersCmd.Flags().StringP("next-token", "n", "", + "Token from which subsequent Users would " + + "be listed") +} diff --git a/cmd/listPersonalAccessTokens.go b/cmd/listPersonalAccessTokens.go new file mode 100644 index 0000000..da2a9f6 --- /dev/null +++ b/cmd/listPersonalAccessTokens.go @@ -0,0 +1,64 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + "bytes" + "fmt" + "github.com/spf13/cobra" + "os" +) + +var listPersonalAccessTokensCmd = &cobra.Command{ + Use: "list-personal-access-tokens", + Short: "List Personal Access Tokens", + Run: func(cmd *cobra.Command, args []string) { + + endpoint := GetEndPoint("", "1.0", "ListPersonalAccessTokens") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + nil, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("\n" + retStr + "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(listPersonalAccessTokensCmd) +} diff --git a/cmd/listPolicies.go b/cmd/listPolicies.go new file mode 100644 index 0000000..90158b7 --- /dev/null +++ b/cmd/listPolicies.go @@ -0,0 +1,120 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// listPoliciesCmd represents the list-policy command +var listPoliciesCmd = &cobra.Command{ + Use: "list-policies", + Short: "List all Policies", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + if flags.Changed("prefix") { + prefix, _ := flags.GetString("prefix") + params["prefix"] = prefix + } + + if flags.Changed("filters") { + filters, _ := flags.GetString("filters") + params["filters"] = filters + } + + if flags.Changed("max-items") { + maxItems, _ := flags.GetInt("max-items") + params["max_items"] = maxItems + } + + if flags.Changed("field") { + fieldsArray, _ := flags.GetStringArray("field") + params["fields"] = fieldsArray + } + + if flags.Changed("next-token") { + nextToken, _ := flags.GetString("next-token") + params["next_token"] = nextToken + } + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "ListPolicies") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nPolicies not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(listPoliciesCmd) + listPoliciesCmd.Flags().StringP("prefix", "p", "", + "Prefix to list Policies with") + listPoliciesCmd.Flags().StringP("filters", "l", "", + "Conditional expression to list filtered " + + "policies") + listPoliciesCmd.Flags().IntP("max-items", "m", 0, + "Maximum number of items to include " + + "in the response") + listPoliciesCmd.Flags().StringArrayP("field", "f", []string{}, + "Policy field to include in the response") + listPoliciesCmd.Flags().StringP("next-token", "n", "", + "Token from which subsequent Policies would " + + "be listed") +} diff --git a/cmd/listPolicyVersions.go b/cmd/listPolicyVersions.go new file mode 100644 index 0000000..302f8c0 --- /dev/null +++ b/cmd/listPolicyVersions.go @@ -0,0 +1,92 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// listPolicyVersionsCmd represents the list-policy command +var listPolicyVersionsCmd = &cobra.Command{ + Use: "list-policy-versions", + Short: "List versions of a given Policy", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + if flags.Changed("policyid") { + policyId, _ := flags.GetString("policyid") + params["policy_id"] = policyId + } + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "ListPolicyVersions") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nPolicies not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(listPolicyVersionsCmd) + listPolicyVersionsCmd.Flags().StringP("policyid", "p", "", + "Id or name of the Policy") + + // mark mandatory fields as required + listPolicyVersionsCmd.MarkFlagRequired("policyid") +} diff --git a/cmd/renew.go b/cmd/renew.go new file mode 100644 index 0000000..7c58b3c --- /dev/null +++ b/cmd/renew.go @@ -0,0 +1,80 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "encoding/json" + // external + "github.com/spf13/cobra" +) + +type renewAccessToken struct { + Token string `json:"access_token"` + Expiration string `json:"expires_at"` +} + +// renewCmd represents the renew command +var renewCmd = &cobra.Command{ + Use: "renew", + Short: "Renew Access Token", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + var respData renewAccessToken + + // now POST + endpoint := GetEndPoint("", "1.0", "Renew") + _, err = DoPost2(endpoint, GetCACertFile(), + AuthTokenKV(), + jsonParams, ContentTypeJSON, &respData, nil) + if err != nil { + fmt.Printf("\nSession Renew failed:\n\n%v\n", err) + os.Exit(1) + } + + // save access token to a file + tokenFile, _ := flags.GetString(loginOptionTokenFile) + tokenFile, err = SaveAccessToken(tokenFile, + respData.Token, + GetServer(), + GetCACertFile()) + if err != nil { + fmt.Printf("\nError saving access token to %s - %v\n", tokenFile, err) + os.Exit(4) + } + + fmt.Printf("\nSession is renewed.\nThe login session expires at %s.\n", + formatLoginExpiration(respData.Expiration)) + fmt.Printf("New Access Token is saved in %s.\n", tokenFile) + fmt.Printf("\n") + }, +} + +func init() { + rootCmd.AddCommand(renewCmd) +} diff --git a/cmd/setPolicyVersion.go b/cmd/setPolicyVersion.go new file mode 100644 index 0000000..6d722b2 --- /dev/null +++ b/cmd/setPolicyVersion.go @@ -0,0 +1,97 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + + +// setPolicyVersionCmd represents the set-policy-version command +var setPolicyVersionCmd = &cobra.Command{ + Use: "set-policy-version", + Short: "Set a specific version of Policy to current", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + policyId, _ := flags.GetString("policyid") + params["policy_id"] = policyId + + + version, _ := flags.GetInt("version") + params["version"] = version + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "SetPolicyVersion") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nPolicy not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(setPolicyVersionCmd) + setPolicyVersionCmd.Flags().StringP("policyid", "p", "", + "Id or name of the Policy") + setPolicyVersionCmd.Flags().IntP("version", "v", 0, + "Version of the Policy to be set as current") + + // mark mandatory fields as required + setPolicyVersionCmd.MarkFlagRequired("policyid") + setPolicyVersionCmd.MarkFlagRequired("version") +} diff --git a/cmd/updateAuditSettings.go b/cmd/updateAuditSettings.go new file mode 100644 index 0000000..0a80c55 --- /dev/null +++ b/cmd/updateAuditSettings.go @@ -0,0 +1,115 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "bytes" + "encoding/json" + "fmt" + "os" + // external + "github.com/spf13/cobra" +) + +// updateAuditSettingsCmd represents the update-audit-settings command +var updateAuditSettingsCmd = &cobra.Command{ + Use: "update-audit-settings", + Short: "Update audit settings", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + if flags.Changed("retention-days") { + retentionDays, _ := flags.GetInt32("retention-days") + if retentionDays < 0 { + fmt.Printf("\nRetention days must be 0 (retain all) or greater\n\n") + os.Exit(1) + } + params["auditlog_retention"] = retentionDays + } + + if flags.Changed("max-logs-size") { + maxLogsSize, _ := flags.GetInt64("max-logs-size") + if maxLogsSize < 0 { + fmt.Printf("\nMaximum log size must be 0 (no limit) or greater\n\n") + os.Exit(1) + } + params["auditlog_totsize"] = maxLogsSize + } + + if len(params) <= 0 { + cmd.Usage() + os.Exit(1) + } + + // JSONify + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "UpdateAuditSetting") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nAudit settings not found\n") + os.Exit(5) + } + + if retStatus == 204 { + fmt.Println("\nUpdate successful\n") + os.Exit(0) + } else { + fmt.Println("\n" + retStr + "\n") + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + fmt.Println("\nUnknown error\n") + os.Exit(0) + } + } + } + }, +} + +func init() { + rootCmd.AddCommand(updateAuditSettingsCmd) + // auditlog_retention + updateAuditSettingsCmd.Flags().Int32P("retention-days", "r", 0, + "Number of days to retain the audit logs. Retention days can be set between " + + "30 - 365 days. Set 0 to retain all.") + updateAuditSettingsCmd.Flags().Int64P("max-logs-size", "m", 0, + "Maximum size for the audit logs in bytes. Set 0 for no limit.") +} diff --git a/cmd/updateLocalUser.go b/cmd/updateLocalUser.go new file mode 100644 index 0000000..e61259f --- /dev/null +++ b/cmd/updateLocalUser.go @@ -0,0 +1,117 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "os" + "fmt" + "bytes" + "encoding/json" + // external + "github.com/spf13/cobra" +) + +// updateLocalUserCmd represents the update-local-user command +var updateLocalUserCmd = &cobra.Command{ + Use: "update-local-user", + Short: "Update a given Local User", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + user, _ := flags.GetString("user") + params["username"] = user + + revision, _ := flags.GetInt("revision") + params["revision"] = revision + + if flags.Changed("name") { + name, _ := flags.GetString("name") + charCheck(len(name)) + params["name"] = name + } + + if flags.Changed("account-status") { + accountStatus, _ := flags.GetString("account-status") + if accountStatus == "enable" { + params["account_state"] = true + } else if accountStatus == "disable" { + params["account_state"] = false + } else { + fmt.Printf("\n Valid values: enable or disable") + os.Exit(1) + } + } + + // JSONify + jsonParams, err := json.Marshal(params) + if (err != nil) { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "UpdateLocalUser") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if (retStr == "" && retStatus == 404) { + fmt.Println("\nUser not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(updateLocalUserCmd) + updateLocalUserCmd.Flags().StringP("user", "u", "", + "username of the user to update") + updateLocalUserCmd.Flags().IntP("revision", "R", 0, + "Revision number of the user") + updateLocalUserCmd.Flags().StringP("name", "n", "", + "Full Name of the User") + updateLocalUserCmd.Flags().StringP("account-status", "s", "", + "Account status of the User") + + // mark mandatory fields as required + updateLocalUserCmd.MarkFlagRequired("user") + updateLocalUserCmd.MarkFlagRequired("revision") +} diff --git a/cmd/updatePersonalAccessToken.go b/cmd/updatePersonalAccessToken.go new file mode 100644 index 0000000..83f361f --- /dev/null +++ b/cmd/updatePersonalAccessToken.go @@ -0,0 +1,112 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/spf13/cobra" + "os" + "time" +) + +var updatePersonalAccessTokenCmd = &cobra.Command{ + Use: "update-personal-access-token", + Short: "Update a Personal Access Token", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + name, _ := flags.GetString("name") + params["name"] = name + + if flags.Changed("description") { + description, _ := flags.GetString("description") + params["description"] = description + } + + if flags.Changed("expiry") { + expiry, _ := flags.GetString("expiry") + expiry = expiry + "T10:00:00Z" + thetime, e := time.Parse(time.RFC3339, expiry) + if e != nil { + fmt.Println("Can't parse time format\n") + } + params["expiry"] = thetime.Unix() + } + + if flags.Changed("revoked") { + revoked, _ := flags.GetBool("revoked") + params["revoked"] = revoked + } + + if len(params) < 2 { + fmt.Println("nothing to update") + os.Exit(1) + } + + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + endpoint := GetEndPoint("", "1.0", "UpdatePersonalAccessToken") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nAction denied\n") + os.Exit(5) + } + + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + fmt.Println("\n" + retStr + "\n") + os.Exit(3) + } else { + fmt.Println("\n" + retStr + "\n") + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(updatePersonalAccessTokenCmd) + updatePersonalAccessTokenCmd.Flags().StringP("description", "d", "", + "Description of personal access token") + updatePersonalAccessTokenCmd.Flags().StringP("name", "n", "", + "Name of personal access token") + updatePersonalAccessTokenCmd.Flags().StringP("expiry", "e", "", + "Date on which personal access token expires in yyyy-mm-dd format") + updatePersonalAccessTokenCmd.Flags().BoolP("revoked", "r", false, + "True if you want to revoke this token") + + updatePersonalAccessTokenCmd.MarkFlagRequired("name") +} diff --git a/cmd/updateTenantAuthMethodToAD.go b/cmd/updateTenantAuthMethodToAD.go new file mode 100644 index 0000000..d72eef2 --- /dev/null +++ b/cmd/updateTenantAuthMethodToAD.go @@ -0,0 +1,265 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "bufio" + "encoding/json" + "fmt" + "os" + "strings" + + // custom + "cli/getpasswd" + + // external + "github.com/spf13/cobra" +) + +const ( + authADDomainName = "ad-domain-name" + adDomainType = "ad-domain-type" + adServiceAccountName = "ad-service_account_name" + adServiceAccountPw = "ad-service-account-pw" + adUID = "ad-uid" + adServers = "ad-servers" + + Name = "name" + + initialADMemberCN = "initial-ad-member-cn" + initialADMemberDistinguishedName = "initial-ad-member-distinguished-name" + initialADMemberMail = "initial-ad-member-mail" + initialADMemberUPN = "initial-ad-member-upn" +) + +type AuthToADServer struct { + ServerURL string `json:"server_url"` + TLS bool `json:"tls,omitempty"` + UserBaseDN string `json:"user_base_dn,omitempty"` + GroupBaseDN string `json:"group_base_dn,omitempty"` + Timeout int `json:"timeout,omitempty"` + CACert string `json:"cacert,omitempty"` +} + +type ADDomain struct { + DomainName string `json:"domain_name,omitempty"` + DomainType string `json:"type,omitempty"` + ServiceAccountName string `json:"service_account_name,omitempty"` + ServiceAccountPw string `json:"service_account_pw,omitempty"` + UID string `json:"uid,omitempty"` + Servers []AuthToADServer `json:"servers,omitempty"` +} + +type InitialADmember struct { + CN string `json:"cn,omitempty"` + DistinguishedName string `json:"distinguishedName,omitempty"` + Mail string `json:"mail,omitempty"` + UPN string `json:"upn,omitempty"` +} + + +type updateTenentAuthModeToADApiResponse struct { + Result string `json:"result"` +} + +func adDomainParseServersJSONFile(JSONFile string, v interface{}) error { + file, err := os.Open(JSONFile) + if err != nil { + fmt.Printf("Error opening file %s - %v\n", JSONFile, err) + return err + } + defer file.Close() + + err = json.NewDecoder(file).Decode(v) + if err != nil { + fmt.Printf("Error decoding Servers JSON - %v\n", err) + return err + } + return nil +} + +func adDomainParseCACertFile(Servers []AuthToADServer) error { + for idx := range Servers { + if Servers[idx].CACert != "" { + encoded, err := LoadAndEncodeCACertFile(Servers[idx].CACert) + if err != nil { + fmt.Printf("%v\n", err) + return err + } + Servers[idx].CACert = encoded + } + } + return nil +} + +func getADServiceCredentials(prefix, user, password string) (string, string) { + + if user == "" { + fmt.Printf("%s User Name: ", prefix) + reader := bufio.NewReader(os.Stdin) + user, _ = reader.ReadString('\n') + // the returned string includes \r\n on Windows, \n on *nix + if strings.HasSuffix(user, "\n") { + user = user[:len(user)-1] + } + if strings.HasSuffix(user, "\r") { + user = user[:len(user)-1] + } + } + + if password == "" { + fmt.Printf("%s Password: ", prefix) + password = getpasswd.ReadPassword() + fmt.Printf("\n") + } + + return user, password +} + +func updateTenantAuthMethodToAD(cmd *cobra.Command, args []string) { + + params := map[string]interface{}{} + var adDomain ADDomain + var initialADmember InitialADmember + + flags := cmd.Flags() + + serviceUsername, _ := flags.GetString(adServiceAccountName) + servicePassword, _ := flags.GetString(adServiceAccountPw) + if servicePassword == "" || serviceUsername == "" { + fmt.Printf("\n") + serviceUsername, servicePassword = getADServiceCredentials("Service", serviceUsername, servicePassword) + } + + adDomain.DomainName, _ = flags.GetString(authADDomainName) + adDomain.DomainType, _ = flags.GetString(adDomainType) + adDomain.ServiceAccountName = serviceUsername + adDomain.ServiceAccountPw = servicePassword + adDomain.UID, _ = flags.GetString(adUID) + + JSONFile, _ := flags.GetString(adServers) + if JSONFile != "" { + err := adDomainParseServersJSONFile(JSONFile, &adDomain.Servers) + if err != nil { + os.Exit(1) + } + err = adDomainParseCACertFile(adDomain.Servers) + if err != nil { + os.Exit(1) + } + } + + initialADmember.CN, _ = flags.GetString(initialADMemberCN) + initialADmember.DistinguishedName, _ = flags.GetString(initialADMemberDistinguishedName) + initialADmember.Mail, _ = flags.GetString(initialADMemberMail) + initialADmember.UPN, _ = flags.GetString(initialADMemberUPN) + + params["ad_domain"] = adDomain + + params["name"], _ = flags.GetString(Name) + + params["initial_admember"] = initialADmember + + + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + var respData updateTenentAuthModeToADApiResponse + endpoint := GetEndPoint("", "1.0", "UpdateTenantAuthMethodToAD") + _, err = DoPost2(endpoint, GetCACertFile(), + AuthTokenKV(), + jsonParams, ContentTypeJSON, &respData, nil) + if err != nil { + fmt.Printf("\nUpdating auth method to Active Directory failed:\n\n%v\n", err) + os.Exit(1) + } + + fmt.Printf("\nAuth method updated to Active Directory successfully.\n") + fmt.Printf("\nResult : %s\n", respData.Result) +} + +func init() { + + var updateTenantAuthMethodToADCommand = &cobra.Command{ + Use: "update-tenant-auth-method-to-ad", + Short: "Update Tenant Auth Method To AD", + Run: updateTenantAuthMethodToAD, + } + updateTenantAuthMethodToADCommand.Flags().StringP(authADDomainName, "a", "", + "Active Directory Name") + updateTenantAuthMethodToADCommand.Flags().StringP(adUID, "u", "", + "Active Directory UID Attribute") + updateTenantAuthMethodToADCommand.Flags().StringP(adDomainType, "t", "", + "Active Directory domain type. Supported values: microsoft_Ad, openLDAP") + updateTenantAuthMethodToADCommand.Flags().StringP(adServiceAccountName, "s", "", + "Active Directory Service Account User Name. "+ + "Users have the option to input values either through the console or by using a flag "+ + "To clear, set it to \"unset\".") + updateTenantAuthMethodToADCommand.Flags().StringP(adServiceAccountPw, "p", "", + "Active Directory Service Account Password. "+ + "Users have the option to input values either through the console or by using a flag") + updateTenantAuthMethodToADCommand.Flags().StringP(adServers, "j", "", + "Path to the Active Directory Domain server List JSON File. The file should "+ + "contain an array of JSON objects, each object representing a Domain Controller. "+ + "Following keys are supported within each domain controller JSON object. \n"+ + "server_url (mandatory) full url of the Domain Controller\n"+ + "cacert (optional) path to CA Certificiate to verify with\n"+ + "user_base_dn (optional) user base DN\n"+ + "group_base_dn (optional) group base DN\n"+ + "timeout (optional) connection timeout in seconds, defaults to 5 seconds\n"+ + "tls (optional) enable StartTLS or not, defaults to false\n"+ + "\n"+ + "Example: \n"+ + "\n"+ + "[\n"+ + " {\n"+ + " \"server_url\": \"ldaps://dc1.mycompany.eng.com\",\n"+ + " \"cacert\": \"/root/cacert.pem\",\n"+ + " \"user_base_dn\": \"DC=mycompany,DC=eng,DC=com\",\n"+ + " \"group_base_dn\": \"DC=mycompany,DC=eng,DC=com\",\n"+ + " \"timeout\": 10,\n"+ + " \"tls\": false,\n"+ + " }\n"+ + "]\n") + + updateTenantAuthMethodToADCommand.Flags().StringP(Name, "n", "", + "Name of the tenant to be updated") + + updateTenantAuthMethodToADCommand.Flags().StringP(initialADMemberCN, "k", "", + "Initial Active Directory member CN") + updateTenantAuthMethodToADCommand.Flags().StringP(initialADMemberDistinguishedName, "d", "", + "Initial Active Directory member distinguished name") + updateTenantAuthMethodToADCommand.Flags().StringP(initialADMemberMail, "m", "", + "Initial Active Directory member mail") + updateTenantAuthMethodToADCommand.Flags().StringP(initialADMemberUPN, "o", "", + "Initial Active Directory member UPN") + + // mark mandatory fields as required + updateTenantAuthMethodToADCommand.MarkFlagRequired(authADDomainName) + updateTenantAuthMethodToADCommand.MarkFlagRequired(adUID) + updateTenantAuthMethodToADCommand.MarkFlagRequired(adDomainType) + updateTenantAuthMethodToADCommand.MarkFlagRequired(adServers) + updateTenantAuthMethodToADCommand.MarkFlagRequired(Name) + updateTenantAuthMethodToADCommand.MarkFlagRequired(initialADMemberMail) + updateTenantAuthMethodToADCommand.MarkFlagRequired(initialADMemberUPN) + + rootCmd.AddCommand(updateTenantAuthMethodToADCommand) +} diff --git a/cmd/utils.go b/cmd/utils.go new file mode 100644 index 0000000..cf097ab --- /dev/null +++ b/cmd/utils.go @@ -0,0 +1,261 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + "bufio" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "math/big" + "bytes" + "time" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "strings" +) + +const RandomStringCharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890" + +type tokenInfo struct { + AccessToken string `json:"access_token"` + Server string `json:"server"` + CACertFile string `json:"cacert_file"` +} + +var gTokenInfo tokenInfo + +func SaveAccessToken(tokenFile, accessToken, server, caCertFile string) (string, error) { + if tokenFile == "" { + tokenDir, err := GetDataDir() + if err != nil { + return "", err + } + tokenFile = filepath.Join(tokenDir, DefaultTokenFilename) + } + + info := tokenInfo{ + AccessToken: accessToken, + Server: server, + CACertFile: caCertFile} + + file, err := os.Create(tokenFile) + if err != nil { + return tokenFile, err + } + defer file.Close() + return tokenFile, json.NewEncoder(file).Encode(&info) +} + +func LoadAccessToken(tokenFile string) (string, error) { + if tokenFile == "" { + tokenDir, err := GetDataDir() + if err != nil { + return "", err + } + tokenFile = filepath.Join(tokenDir, DefaultTokenFilename) + } + + file, err := os.Open(tokenFile) + if err != nil { + return tokenFile, err + } + defer file.Close() + + err = json.NewDecoder(file).Decode(&gTokenInfo) + if err != nil { + return tokenFile, err + } + + if gTokenInfo.AccessToken == "" || gTokenInfo.Server == "" { + return tokenFile, fmt.Errorf("Invalid or corrupt Token File - access_token or server is missing") + } + + return tokenFile, nil +} + +func GetAccessToken() string { + return gTokenInfo.AccessToken +} + +func GetServer() string { + return gTokenInfo.Server +} + +func GetCACertFile() string { + return gTokenInfo.CACertFile +} + +func JsonStrToMap(jsonStr string) map[string]interface{} { + var jsonMap map[string]interface{} + err := json.Unmarshal([]byte(jsonStr), &jsonMap) + if err != nil { + fmt.Println("Error parsing json string: ", err) + os.Exit(1) + } + return jsonMap +} + +func IsJSON(str string) bool { + var js json.RawMessage + return json.Unmarshal([]byte(str), &js) == nil +} + +func LoadAndEncodeCACertFile(CACertFile string) (string, error) { + file, err := os.Open(CACertFile) + if err != nil { + return "", fmt.Errorf("Error opening CA Certificate File %s - %v", + CACertFile, err) + } + defer file.Close() + + // Read entire CA CertFile content into a byte slice + reader := bufio.NewReader(file) + content, _ := io.ReadAll(reader) + + encoded := base64.StdEncoding.EncodeToString(content) + if encoded == "" { + return "", fmt.Errorf("Error encoding certificate data - %s", CACertFile) + } + return encoded, nil +} + +// equivalent of json.MarshalIndent, while escaping "<", ">" and "&" +// which otherwise would be escaped to their unicode equivalents +// see https://golang.org/pkg/encoding/json/#SetEscapeHTML +func JSONMarshalIndent(t interface{}) ([]byte, error) { + buffer := &bytes.Buffer{} + encoder := json.NewEncoder(buffer) + encoder.SetEscapeHTML(false) + encoder.SetIndent("", " ") + err := encoder.Encode(t) + return buffer.Bytes(), err +} + +func B64File(File string) (string, error) { + file, err := os.Open(File) + if err != nil { + return "", fmt.Errorf("Error opening file %s - %v", + File, err) + } + defer file.Close() + + reader := bufio.NewReader(file) + content, _ := io.ReadAll(reader) + + encoded := base64.StdEncoding.EncodeToString(content) + if encoded == "" { + return "", fmt.Errorf("Error base64 encoding file - %s", File) + } + return encoded, nil +} + +func B64Encode(data string) string { + return base64.StdEncoding.EncodeToString([]byte(data)) +} + +func B64Decode(b64Str string) string { + dec, _ := base64.StdEncoding.DecodeString(b64Str) + return string(dec) +} + +func AESGCMDecrypt(b64CipherText string, b64Key string, b64Nonce string, + b64Tag string, authData string) string { + key := []byte(B64Decode(b64Key)) + ciphertext := []byte(B64Decode(b64CipherText)) + nonce := []byte(B64Decode(b64Nonce)) + tag := []byte(B64Decode(b64Tag)) + + block, err := aes.NewCipher(key) + if err != nil { + panic(err.Error()) + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + panic(err.Error()) + } + +// crypto library expects these together & separates it out by itself + ciphertextTag := append(ciphertext, tag...) + plaintext, err := aesgcm.Open(nil, nonce, ciphertextTag, []byte(authData)) + if err != nil { + panic(err.Error()) + } + return string(plaintext) +} + +func KeyExists(kvMap map[string]interface{}, key string) bool { + val, ok := kvMap[key] + return ok && val != nil +} + +func convertUTCtoLocal() *time.Location { + location, err := time.LoadLocation("Local") + if err != nil { + os.Exit(10) // unexpected + } + return location +} + +func convertTimeFrom24HourTo12HourFormat(hour int) (int, string) { + ampm := "AM" + if hour > 11 { + ampm = "PM" + } + if hour == 0 { + hour = 12 + } else if hour > 12 { + hour = hour - 12 + } + return hour, ampm +} + +func formatLoginExpiration(expiresAt string) string { + expiration, err := time.Parse(time.RFC3339, expiresAt) + if err != nil { + fmt.Printf("\nInvalid Expiration %q - %v\n", expiresAt, err) + os.Exit(5) + } + + expiration = expiration.In(convertUTCtoLocal()) + + hour, min, sec := expiration.Clock() + hour, ampm := convertTimeFrom24HourTo12HourFormat(hour) + + year, month, day := expiration.Date() + + return fmt.Sprintf("%s, %02d %s %d %02d:%02d:%02d %s", expiration.Weekday(), + day, month, year, hour, min, sec, ampm) +} + +// Generates random string of provided length. Charset used to generate the random string includes upper & lowercase +// alphabets and numerals from 0 to 9. Crypthographically strong random generator is used while generating string so +// that it can be used as password/passphrase. +func GenerateRandomString(length int) string { + var randomString strings.Builder + maxIndex := big.NewInt(int64(len(RandomStringCharSet))) + for i := 0; i < length; i++ { + randIndex, _ := rand.Int(rand.Reader, maxIndex) + randomString.WriteByte(RandomStringCharSet[int(randIndex.Int64())]) + } + return randomString.String() +} diff --git a/getpasswd/getpasswd_nix.go b/getpasswd/getpasswd_nix.go new file mode 100644 index 0000000..5912f9f --- /dev/null +++ b/getpasswd/getpasswd_nix.go @@ -0,0 +1,34 @@ +// +build !windows + +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 getpasswd + +import ( + "strings" + + "golang.org/x/term" +) + +// ReadPassword reads password from stdin +func ReadPassword() string { + bytePassword, err := term.ReadPassword(0) + if err != nil { + return "" + } + return strings.TrimSpace(string(bytePassword)) +} diff --git a/getpasswd/getpasswd_windows.go b/getpasswd/getpasswd_windows.go new file mode 100644 index 0000000..104ce9d --- /dev/null +++ b/getpasswd/getpasswd_windows.go @@ -0,0 +1,73 @@ +// +build windows + +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 getpasswd + +import ( + "bufio" + "os" + "strings" + "syscall" +) + +// refer SetConsoleMode documentation for the bit flags +// https://docs.microsoft.com/en-us/windows/console/setconsolemode +const ENABLE_ECHO_INPUT = 0x0004 + +// ReadPassword reads password from stdin +func ReadPassword() string { + + hStdIn := syscall.Handle(os.Stdin.Fd()) + var orgConsoleMode uint32 + + err := syscall.GetConsoleMode(hStdIn, &orgConsoleMode) + if err != nil { + return "" + } + + var newConsoleMode uint32 = (orgConsoleMode &^ ENABLE_ECHO_INPUT) + + err = setConsoleMode(hStdIn, newConsoleMode) + defer setConsoleMode(hStdIn, orgConsoleMode) + + if err != nil { + return "" + } + + reader := bufio.NewReader(os.Stdin) + passwd, _ := reader.ReadString('\n') + if strings.HasSuffix(passwd, "\n") { + passwd = passwd[:len(passwd)-1] + } + // check for \r just in case + if strings.HasSuffix(passwd, "\r") { + passwd = passwd[:len(passwd)-1] + } + + return strings.TrimSpace(passwd) +} + +func setConsoleMode(hConsole syscall.Handle, mode uint32) error { + kernel32Dll := syscall.MustLoadDLL("kernel32.dll") + procSetConsoleMode := kernel32Dll.MustFindProc("SetConsoleMode") + ret, _, err := procSetConsoleMode.Call(uintptr(hConsole), uintptr(mode)) + if ret == 0 { + return err + } + return nil +} From 599824401c5e49b74220fb8cc9b12c27c41949c0 Mon Sep 17 00:00:00 2001 From: Dibya Prakash Date: Fri, 27 Jun 2025 18:10:15 +0530 Subject: [PATCH 3/3] Some reorganizing and chngaes as per ticket HTDC-23442 and HTDC-23443 --- cmd/updateTenantAuthMethodToAD.go | 12 +-- Makefile => kmipcli/Makefile | 0 kmipcli/{ => cmd}/KMIPCLIutils.go | 0 kmipcli/cmd/configureHPCSKEK.go | 125 ++++++++++++++++++++++ kmipcli/{ => cmd}/configureHSMKEK.go | 0 kmipcli/{ => cmd}/createClientCert.go | 0 kmipcli/{ => cmd}/createPolicy.go | 0 kmipcli/{ => cmd}/deleteClientCert.go | 0 kmipcli/{ => cmd}/disableKEK.go | 0 kmipcli/{ => cmd}/downloadClientCert.go | 0 kmipcli/{ => cmd}/getClientCert.go | 0 kmipcli/{ => cmd}/getHSMInfo.go | 0 kmipcli/{ => cmd}/getKEKSetting.go | 0 kmipcli/{ => cmd}/getKmipObject.go | 0 kmipcli/{ => cmd}/getKmipObjectCount.go | 0 kmipcli/{ => cmd}/getPlatformInfo.go | 0 kmipcli/cmd/getTenantInfo.go | 80 ++++++++++++++ kmipcli/cmd/getTenantSettings.go | 80 ++++++++++++++ kmipcli/{ => cmd}/listClientCerts.go | 0 kmipcli/{ => cmd}/listKmipObjects.go | 0 kmipcli/{ => cmd}/locateRootKey.go | 0 kmipcli/{ => cmd}/login.go | 0 kmipcli/{ => cmd}/rekeyKEK.go | 0 kmipcli/{ => cmd}/root.go | 0 kmipcli/{ => cmd}/updateKmipObject.go | 0 kmipcli/{ => cmd}/updatePolicy.go | 0 kmipcli/cmd/updateTenantSettings.go | 135 ++++++++++++++++++++++++ kmipcli/{ => cmd}/version.go | 21 ++-- kmipcli/configureHPCSKEK.go | 128 ---------------------- kmipcli/getTenantInfo.go | 80 -------------- kmipcli/getTenantSettings.go | 80 -------------- main.go => kmipcli/main.go | 0 kmipcli/updateTenantSettings.go | 135 ------------------------ 33 files changed, 435 insertions(+), 441 deletions(-) rename Makefile => kmipcli/Makefile (100%) rename kmipcli/{ => cmd}/KMIPCLIutils.go (100%) create mode 100644 kmipcli/cmd/configureHPCSKEK.go rename kmipcli/{ => cmd}/configureHSMKEK.go (100%) rename kmipcli/{ => cmd}/createClientCert.go (100%) rename kmipcli/{ => cmd}/createPolicy.go (100%) rename kmipcli/{ => cmd}/deleteClientCert.go (100%) rename kmipcli/{ => cmd}/disableKEK.go (100%) rename kmipcli/{ => cmd}/downloadClientCert.go (100%) rename kmipcli/{ => cmd}/getClientCert.go (100%) rename kmipcli/{ => cmd}/getHSMInfo.go (100%) rename kmipcli/{ => cmd}/getKEKSetting.go (100%) rename kmipcli/{ => cmd}/getKmipObject.go (100%) rename kmipcli/{ => cmd}/getKmipObjectCount.go (100%) rename kmipcli/{ => cmd}/getPlatformInfo.go (100%) create mode 100644 kmipcli/cmd/getTenantInfo.go create mode 100644 kmipcli/cmd/getTenantSettings.go rename kmipcli/{ => cmd}/listClientCerts.go (100%) rename kmipcli/{ => cmd}/listKmipObjects.go (100%) rename kmipcli/{ => cmd}/locateRootKey.go (100%) rename kmipcli/{ => cmd}/login.go (100%) rename kmipcli/{ => cmd}/rekeyKEK.go (100%) rename kmipcli/{ => cmd}/root.go (100%) rename kmipcli/{ => cmd}/updateKmipObject.go (100%) rename kmipcli/{ => cmd}/updatePolicy.go (100%) create mode 100644 kmipcli/cmd/updateTenantSettings.go rename kmipcli/{ => cmd}/version.go (71%) delete mode 100644 kmipcli/configureHPCSKEK.go delete mode 100644 kmipcli/getTenantInfo.go delete mode 100644 kmipcli/getTenantSettings.go rename main.go => kmipcli/main.go (100%) delete mode 100644 kmipcli/updateTenantSettings.go diff --git a/cmd/updateTenantAuthMethodToAD.go b/cmd/updateTenantAuthMethodToAD.go index d72eef2..33bce7f 100644 --- a/cmd/updateTenantAuthMethodToAD.go +++ b/cmd/updateTenantAuthMethodToAD.go @@ -26,7 +26,7 @@ import ( // custom "cli/getpasswd" - + // external "github.com/spf13/cobra" ) @@ -72,7 +72,6 @@ type InitialADmember struct { UPN string `json:"upn,omitempty"` } - type updateTenentAuthModeToADApiResponse struct { Result string `json:"result"` } @@ -175,7 +174,6 @@ func updateTenantAuthMethodToAD(cmd *cobra.Command, args []string) { params["initial_admember"] = initialADmember - jsonParams, err := json.Marshal(params) if err != nil { fmt.Println("Error building JSON request: ", err) @@ -199,8 +197,8 @@ func updateTenantAuthMethodToAD(cmd *cobra.Command, args []string) { func init() { var updateTenantAuthMethodToADCommand = &cobra.Command{ - Use: "update-tenant-auth-method-to-ad", - Short: "Update Tenant Auth Method To AD", + Use: "update-vault-auth-method-to-ad", + Short: "Update Vault Auth Method To AD", Run: updateTenantAuthMethodToAD, } updateTenantAuthMethodToADCommand.Flags().StringP(authADDomainName, "a", "", @@ -211,11 +209,11 @@ func init() { "Active Directory domain type. Supported values: microsoft_Ad, openLDAP") updateTenantAuthMethodToADCommand.Flags().StringP(adServiceAccountName, "s", "", "Active Directory Service Account User Name. "+ - "Users have the option to input values either through the console or by using a flag "+ + "Users have the option to input values either through the console or by using a flag "+ "To clear, set it to \"unset\".") updateTenantAuthMethodToADCommand.Flags().StringP(adServiceAccountPw, "p", "", "Active Directory Service Account Password. "+ - "Users have the option to input values either through the console or by using a flag") + "Users have the option to input values either through the console or by using a flag") updateTenantAuthMethodToADCommand.Flags().StringP(adServers, "j", "", "Path to the Active Directory Domain server List JSON File. The file should "+ "contain an array of JSON objects, each object representing a Domain Controller. "+ diff --git a/Makefile b/kmipcli/Makefile similarity index 100% rename from Makefile rename to kmipcli/Makefile diff --git a/kmipcli/KMIPCLIutils.go b/kmipcli/cmd/KMIPCLIutils.go similarity index 100% rename from kmipcli/KMIPCLIutils.go rename to kmipcli/cmd/KMIPCLIutils.go diff --git a/kmipcli/cmd/configureHPCSKEK.go b/kmipcli/cmd/configureHPCSKEK.go new file mode 100644 index 0000000..822286d --- /dev/null +++ b/kmipcli/cmd/configureHPCSKEK.go @@ -0,0 +1,125 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "bytes" + "encoding/json" + "fmt" + "os" + + // external + "github.com/spf13/cobra" +) + +// ConfigureHPCSKEK represents the configure-hpcs-kek command +var ConfigureHPCSKEK = &cobra.Command{ + Use: "configure-hpcs-kek", + Short: "Configure Encrypting KMIP objects using KEK stored in IBM Hyper Protect Crypto Services", + Hidden: true, + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // revision + revision, _ := flags.GetInt("revision") + params["revision"] = revision + + params["hsm_type"] = "HPCS" + + hpcs_url, _ := flags.GetString("hpcs_url") + params["hpcs_url"] = hpcs_url + + hpcs_api_key, _ := flags.GetString("hpcs_api_key") + params["hpcs_api_key"] = hpcs_api_key + + hpcs_instance_id, _ := flags.GetString("hpcs_instance_id") + params["hpcs_instance_id"] = hpcs_instance_id + + if flags.Changed("hpcs_root_key_id") { + hpcs_root_key_id, _ := flags.GetString("hpcs_root_key_id") + params["hpcs_root_key_id"] = hpcs_root_key_id + } + + if flags.Changed("kek_cache_timeout") { + //kek_cache_timeout + kek_cache_timeout, _ := flags.GetInt("kek_cache_timeout") + params["kek_cache_timeout"] = kek_cache_timeout + } + + // JSONify + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "UpdateKEKSetting") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nTenant not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(ConfigureHPCSKEK) + ConfigureHPCSKEK.Flags().IntP("kek_cache_timeout", "t", 1800, + "KEK Cache Timeout") + ConfigureHPCSKEK.Flags().IntP("revision", "R", 0, + "KEK Setting revision number") + ConfigureHPCSKEK.Flags().StringP("hpcs_url", "u", "", + "HPCS URL") + ConfigureHPCSKEK.Flags().StringP("hpcs_api_key", "k", "", + "HPCS API Key") + ConfigureHPCSKEK.Flags().StringP("hpcs_instance_id", "i", "", + "HPCS Instance ID") + ConfigureHPCSKEK.Flags().StringP("hpcs_root_key_id", "r", "", + "KEK Rootkey ID") + // mark mandatory fields as required + ConfigureHPCSKEK.MarkFlagRequired("hpcs_url") + ConfigureHPCSKEK.MarkFlagRequired("hpcs_api_key") + ConfigureHPCSKEK.MarkFlagRequired("hpcs_instance_id") + ConfigureHPCSKEK.MarkFlagRequired("revision") +} diff --git a/kmipcli/configureHSMKEK.go b/kmipcli/cmd/configureHSMKEK.go similarity index 100% rename from kmipcli/configureHSMKEK.go rename to kmipcli/cmd/configureHSMKEK.go diff --git a/kmipcli/createClientCert.go b/kmipcli/cmd/createClientCert.go similarity index 100% rename from kmipcli/createClientCert.go rename to kmipcli/cmd/createClientCert.go diff --git a/kmipcli/createPolicy.go b/kmipcli/cmd/createPolicy.go similarity index 100% rename from kmipcli/createPolicy.go rename to kmipcli/cmd/createPolicy.go diff --git a/kmipcli/deleteClientCert.go b/kmipcli/cmd/deleteClientCert.go similarity index 100% rename from kmipcli/deleteClientCert.go rename to kmipcli/cmd/deleteClientCert.go diff --git a/kmipcli/disableKEK.go b/kmipcli/cmd/disableKEK.go similarity index 100% rename from kmipcli/disableKEK.go rename to kmipcli/cmd/disableKEK.go diff --git a/kmipcli/downloadClientCert.go b/kmipcli/cmd/downloadClientCert.go similarity index 100% rename from kmipcli/downloadClientCert.go rename to kmipcli/cmd/downloadClientCert.go diff --git a/kmipcli/getClientCert.go b/kmipcli/cmd/getClientCert.go similarity index 100% rename from kmipcli/getClientCert.go rename to kmipcli/cmd/getClientCert.go diff --git a/kmipcli/getHSMInfo.go b/kmipcli/cmd/getHSMInfo.go similarity index 100% rename from kmipcli/getHSMInfo.go rename to kmipcli/cmd/getHSMInfo.go diff --git a/kmipcli/getKEKSetting.go b/kmipcli/cmd/getKEKSetting.go similarity index 100% rename from kmipcli/getKEKSetting.go rename to kmipcli/cmd/getKEKSetting.go diff --git a/kmipcli/getKmipObject.go b/kmipcli/cmd/getKmipObject.go similarity index 100% rename from kmipcli/getKmipObject.go rename to kmipcli/cmd/getKmipObject.go diff --git a/kmipcli/getKmipObjectCount.go b/kmipcli/cmd/getKmipObjectCount.go similarity index 100% rename from kmipcli/getKmipObjectCount.go rename to kmipcli/cmd/getKmipObjectCount.go diff --git a/kmipcli/getPlatformInfo.go b/kmipcli/cmd/getPlatformInfo.go similarity index 100% rename from kmipcli/getPlatformInfo.go rename to kmipcli/cmd/getPlatformInfo.go diff --git a/kmipcli/cmd/getTenantInfo.go b/kmipcli/cmd/getTenantInfo.go new file mode 100644 index 0000000..21929e8 --- /dev/null +++ b/kmipcli/cmd/getTenantInfo.go @@ -0,0 +1,80 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "bytes" + "encoding/json" + "fmt" + "os" + + // external + "github.com/spf13/cobra" +) + +// getKmipInfoCmd represents the get-tenant-info command +var getKmipInfoCmd = &cobra.Command{ + Use: "get-vault-info", + Short: "Get Kmip Vault Info", + Run: func(cmd *cobra.Command, args []string) { + params := map[string]interface{}{} + + // JSONify + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetTenantInfo") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nKmip not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getKmipInfoCmd) +} diff --git a/kmipcli/cmd/getTenantSettings.go b/kmipcli/cmd/getTenantSettings.go new file mode 100644 index 0000000..5cbe7b2 --- /dev/null +++ b/kmipcli/cmd/getTenantSettings.go @@ -0,0 +1,80 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "bytes" + "encoding/json" + "fmt" + "os" + + // external + "github.com/spf13/cobra" +) + +// getKmipSettingsCmd represents the get-kmip-settings command +var getKmipSettingsCmd = &cobra.Command{ + Use: "get-vault-settings", + Short: "Get Kmip Vault settings", + Run: func(cmd *cobra.Command, args []string) { + params := map[string]interface{}{} + + // JSONify + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "GetTenantSettings") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nKmip settings not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(getKmipSettingsCmd) +} diff --git a/kmipcli/listClientCerts.go b/kmipcli/cmd/listClientCerts.go similarity index 100% rename from kmipcli/listClientCerts.go rename to kmipcli/cmd/listClientCerts.go diff --git a/kmipcli/listKmipObjects.go b/kmipcli/cmd/listKmipObjects.go similarity index 100% rename from kmipcli/listKmipObjects.go rename to kmipcli/cmd/listKmipObjects.go diff --git a/kmipcli/locateRootKey.go b/kmipcli/cmd/locateRootKey.go similarity index 100% rename from kmipcli/locateRootKey.go rename to kmipcli/cmd/locateRootKey.go diff --git a/kmipcli/login.go b/kmipcli/cmd/login.go similarity index 100% rename from kmipcli/login.go rename to kmipcli/cmd/login.go diff --git a/kmipcli/rekeyKEK.go b/kmipcli/cmd/rekeyKEK.go similarity index 100% rename from kmipcli/rekeyKEK.go rename to kmipcli/cmd/rekeyKEK.go diff --git a/kmipcli/root.go b/kmipcli/cmd/root.go similarity index 100% rename from kmipcli/root.go rename to kmipcli/cmd/root.go diff --git a/kmipcli/updateKmipObject.go b/kmipcli/cmd/updateKmipObject.go similarity index 100% rename from kmipcli/updateKmipObject.go rename to kmipcli/cmd/updateKmipObject.go diff --git a/kmipcli/updatePolicy.go b/kmipcli/cmd/updatePolicy.go similarity index 100% rename from kmipcli/updatePolicy.go rename to kmipcli/cmd/updatePolicy.go diff --git a/kmipcli/cmd/updateTenantSettings.go b/kmipcli/cmd/updateTenantSettings.go new file mode 100644 index 0000000..307819b --- /dev/null +++ b/kmipcli/cmd/updateTenantSettings.go @@ -0,0 +1,135 @@ +/* + Copyright 2020-2025 Entrust Corporation + +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 + +https://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 cmd + +import ( + // standard + "bytes" + "encoding/json" + "fmt" + "os" + + // external + "github.com/spf13/cobra" +) + +// updateKmipSettingsCmd represents the update-kmip-settings command +var updateKmipSettingsCmd = &cobra.Command{ + Use: "update-vault-settings", + Short: "Update Kmip Vault settings", + Run: func(cmd *cobra.Command, args []string) { + flags := cmd.Flags() + params := map[string]interface{}{} + + // create request payload + degradedModeAvailProvided := flags.Changed("degraded-mode-availability") + oidcProvided := flags.Changed("oidc-enabled") + if !degradedModeAvailProvided && !oidcProvided { + fmt.Println("Specify any one of Vault settings to update") + os.Exit(1) + } + + if flags.Changed("degraded-mode-availability") { + degradedModeAvailability, _ := flags.GetString("degraded-mode-availability") + if degradedModeAvailability == "enable" || + degradedModeAvailability == "disable" { + if degradedModeAvailability == "enable" { + params["degraded_mode_availability"] = true + } + if degradedModeAvailability == "disable" { + params["degraded_mode_availability"] = false + } + } else { + fmt.Printf("\nInvalid -d, --degraded-mode-availability option %s. "+ + "Supported: enable (or) disable\n", degradedModeAvailability) + os.Exit(1) + } + } + + if flags.Changed("oidc-enabled") { + oidcEnabled, _ := flags.GetString("oidc-enabled") + if oidcEnabled == "enable" || + oidcEnabled == "disable" { + if oidcEnabled == "enable" { + params["oidc_enabled"] = true + } + if oidcEnabled == "disable" { + params["oidc_enabled"] = false + } + } else { + fmt.Printf("\nInvalid -o, --oidc-enabled option %s. "+ + "Supported: enable (or) disable\n", oidcEnabled) + os.Exit(1) + } + } + + revision, _ := flags.GetInt("revision") + params["revision"] = revision + + // JSONify + jsonParams, err := json.Marshal(params) + if err != nil { + fmt.Println("Error building JSON request: ", err) + os.Exit(1) + } + + // now POST + endpoint := GetEndPoint("", "1.0", "UpdateTenantSettings") + ret, err := DoPost(endpoint, + GetCACertFile(), + AuthTokenKV(), + jsonParams, + "application/json") + if err != nil { + fmt.Printf("\nHTTP request failed: %s\n", err) + os.Exit(4) + } else { + // type assertion + retBytes := ret["data"].(*bytes.Buffer) + retStatus := ret["status"].(int) + retStr := retBytes.String() + + if retStr == "" && retStatus == 404 { + fmt.Println("\nKmip Settings not found\n") + os.Exit(5) + } + + fmt.Println("\n" + retStr + "\n") + + // make a decision on what to exit with + retMap := JsonStrToMap(retStr) + if _, present := retMap["error"]; present { + os.Exit(3) + } else { + os.Exit(0) + } + } + }, +} + +func init() { + rootCmd.AddCommand(updateKmipSettingsCmd) + updateKmipSettingsCmd.Flags().StringP("degraded-mode-availability", "d", "", + "Degraded mode availability. ") + updateKmipSettingsCmd.Flags().StringP("oidc-enabled", "o", "", + "OIDC enabled flag. ") + updateKmipSettingsCmd.Flags().IntP("revision", "R", 0, + "Revision number of the box") + + // mark mandatory fields as required + updateKmipSettingsCmd.MarkFlagRequired("revision") +} diff --git a/kmipcli/version.go b/kmipcli/cmd/version.go similarity index 71% rename from kmipcli/version.go rename to kmipcli/cmd/version.go index 1dfc95a..6ee53f9 100644 --- a/kmipcli/version.go +++ b/kmipcli/cmd/version.go @@ -17,22 +17,21 @@ limitations under the License. package cmd import ( - // standard - "fmt" - // external - "github.com/spf13/cobra" + // standard + "fmt" + // external + "github.com/spf13/cobra" ) - // versionCmd represents the version command var versionCmd = &cobra.Command{ - Use: "version", - Short: "Version of Entrust KMIP tenant portal cli", - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("1.0") - }, + Use: "version", + Short: "Version of Entrust KMIP Vault portal cli", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("1.0") + }, } func init() { - rootCmd.AddCommand(versionCmd) + rootCmd.AddCommand(versionCmd) } diff --git a/kmipcli/configureHPCSKEK.go b/kmipcli/configureHPCSKEK.go deleted file mode 100644 index 54c5ed9..0000000 --- a/kmipcli/configureHPCSKEK.go +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright 2020-2025 Entrust Corporation - -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 - -https://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 cmd - -import ( - // standard - "os" - "fmt" - "bytes" - "encoding/json" - - - // external - "github.com/spf13/cobra" -) - - -// ConfigureHPCSKEK represents the configure-hpcs-kek command -var ConfigureHPCSKEK = &cobra.Command{ - Use: "configure-hpcs-kek", - Short: "Configure Encrypting KMIP objects using KEK stored in IBM Hyper Protect Crypto Services", - Run: func(cmd *cobra.Command, args []string) { - flags := cmd.Flags() - params := map[string]interface{}{} - - - - // revision - revision, _ := flags.GetInt("revision") - params["revision"] = revision - - params["hsm_type"] = "HPCS" - - hpcs_url, _ := flags.GetString("hpcs_url") - params["hpcs_url"] = hpcs_url - - hpcs_api_key, _ := flags.GetString("hpcs_api_key") - params["hpcs_api_key"] = hpcs_api_key - - hpcs_instance_id, _ := flags.GetString("hpcs_instance_id") - params["hpcs_instance_id"] = hpcs_instance_id - - if flags.Changed("hpcs_root_key_id") { - hpcs_root_key_id, _ := flags.GetString("hpcs_root_key_id") - params["hpcs_root_key_id"] = hpcs_root_key_id - } - - if flags.Changed("kek_cache_timeout") { - //kek_cache_timeout - kek_cache_timeout, _ := flags.GetInt("kek_cache_timeout") - params["kek_cache_timeout"] = kek_cache_timeout - } - - // JSONify - jsonParams, err := json.Marshal(params) - if (err != nil) { - fmt.Println("Error building JSON request: ", err) - os.Exit(1) - } - - // now POST - endpoint := GetEndPoint("", "1.0", "UpdateKEKSetting") - ret, err := DoPost(endpoint, - GetCACertFile(), - AuthTokenKV(), - jsonParams, - "application/json") - if err != nil { - fmt.Printf("\nHTTP request failed: %s\n", err) - os.Exit(4) - } else { - // type assertion - retBytes := ret["data"].(*bytes.Buffer) - retStatus := ret["status"].(int) - retStr := retBytes.String() - - if (retStr == "" && retStatus == 404) { - fmt.Println("\nTenant not found\n") - os.Exit(5) - } - - fmt.Println("\n" + retStr + "\n") - - // make a decision on what to exit with - retMap := JsonStrToMap(retStr) - if _, present := retMap["error"]; present { - os.Exit(3) - } else { - os.Exit(0) - } - } - }, -} - -func init() { - rootCmd.AddCommand(ConfigureHPCSKEK) - ConfigureHPCSKEK.Flags().IntP("kek_cache_timeout", "t", 1800, - "KEK Cache Timeout") - ConfigureHPCSKEK.Flags().IntP("revision", "R", 0, - "KEK Setting revision number") - ConfigureHPCSKEK.Flags().StringP("hpcs_url", "u", "", - "HPCS URL") - ConfigureHPCSKEK.Flags().StringP("hpcs_api_key", "k", "", - "HPCS API Key") - ConfigureHPCSKEK.Flags().StringP("hpcs_instance_id", "i", "", - "HPCS Instance ID") - ConfigureHPCSKEK.Flags().StringP("hpcs_root_key_id", "r", "", - "KEK Rootkey ID") - // mark mandatory fields as required - ConfigureHPCSKEK.MarkFlagRequired("hpcs_url") - ConfigureHPCSKEK.MarkFlagRequired("hpcs_api_key") - ConfigureHPCSKEK.MarkFlagRequired("hpcs_instance_id") - ConfigureHPCSKEK.MarkFlagRequired("revision") -} diff --git a/kmipcli/getTenantInfo.go b/kmipcli/getTenantInfo.go deleted file mode 100644 index 7ac62a9..0000000 --- a/kmipcli/getTenantInfo.go +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright 2020-2025 Entrust Corporation - -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 - -https://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 cmd - -import ( - // standard - "os" - "fmt" - "bytes" - "encoding/json" - // external - "github.com/spf13/cobra" -) - - -// getKmipInfoCmd represents the get-tenant-info command -var getKmipInfoCmd = &cobra.Command{ - Use: "get-tenant-info", - Short: "Get Kmip Tenant Info", - Run: func(cmd *cobra.Command, args []string) { - params := map[string]interface{}{} - - // JSONify - jsonParams, err := json.Marshal(params) - if (err != nil) { - fmt.Println("Error building JSON request: ", err) - os.Exit(1) - } - - // now POST - endpoint := GetEndPoint("", "1.0", "GetTenantInfo") - ret, err := DoPost(endpoint, - GetCACertFile(), - AuthTokenKV(), - jsonParams, - "application/json") - if err != nil { - fmt.Printf("\nHTTP request failed: %s\n", err) - os.Exit(4) - } else { - // type assertion - retBytes := ret["data"].(*bytes.Buffer) - retStatus := ret["status"].(int) - retStr := retBytes.String() - - if (retStr == "" && retStatus == 404) { - fmt.Println("\nKmip not found\n") - os.Exit(5) - } - - fmt.Println("\n" + retStr + "\n") - - // make a decision on what to exit with - retMap := JsonStrToMap(retStr) - if _, present := retMap["error"]; present { - os.Exit(3) - } else { - os.Exit(0) - } - } - }, -} - -func init() { - rootCmd.AddCommand(getKmipInfoCmd) -} diff --git a/kmipcli/getTenantSettings.go b/kmipcli/getTenantSettings.go deleted file mode 100644 index c0acbaf..0000000 --- a/kmipcli/getTenantSettings.go +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright 2020-2025 Entrust Corporation - -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 - -https://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 cmd - -import ( - // standard - "os" - "fmt" - "bytes" - "encoding/json" - // external - "github.com/spf13/cobra" -) - - -// getKmipSettingsCmd represents the get-kmip-settings command -var getKmipSettingsCmd = &cobra.Command{ - Use: "get-tenant-settings", - Short: "Get Kmip Tenant settings", - Run: func(cmd *cobra.Command, args []string) { - params := map[string]interface{}{} - - // JSONify - jsonParams, err := json.Marshal(params) - if (err != nil) { - fmt.Println("Error building JSON request: ", err) - os.Exit(1) - } - - // now POST - endpoint := GetEndPoint("", "1.0", "GetTenantSettings") - ret, err := DoPost(endpoint, - GetCACertFile(), - AuthTokenKV(), - jsonParams, - "application/json") - if err != nil { - fmt.Printf("\nHTTP request failed: %s\n", err) - os.Exit(4) - } else { - // type assertion - retBytes := ret["data"].(*bytes.Buffer) - retStatus := ret["status"].(int) - retStr := retBytes.String() - - if (retStr == "" && retStatus == 404) { - fmt.Println("\nKmip settings not found\n") - os.Exit(5) - } - - fmt.Println("\n" + retStr + "\n") - - // make a decision on what to exit with - retMap := JsonStrToMap(retStr) - if _, present := retMap["error"]; present { - os.Exit(3) - } else { - os.Exit(0) - } - } - }, -} - -func init() { - rootCmd.AddCommand(getKmipSettingsCmd) -} diff --git a/main.go b/kmipcli/main.go similarity index 100% rename from main.go rename to kmipcli/main.go diff --git a/kmipcli/updateTenantSettings.go b/kmipcli/updateTenantSettings.go deleted file mode 100644 index 0aa32f2..0000000 --- a/kmipcli/updateTenantSettings.go +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright 2020-2025 Entrust Corporation - -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 - -https://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 cmd - -import ( - // standard - "os" - "fmt" - "bytes" - "encoding/json" - // external - "github.com/spf13/cobra" -) - - -// updateKmipSettingsCmd represents the update-kmip-settings command -var updateKmipSettingsCmd = &cobra.Command{ - Use: "update-tenant-settings", - Short: "Update Kmip Tenant settings", - Run: func(cmd *cobra.Command, args []string) { - flags := cmd.Flags() - params := map[string]interface{}{} - - // create request payload - degradedModeAvailProvided := flags.Changed("degraded-mode-availability") - oidcProvided := flags.Changed("oidc-enabled") - if (!degradedModeAvailProvided && !oidcProvided) { - fmt.Println("Specify any one of Vault settings to update") - os.Exit(1) - } - - if flags.Changed("degraded-mode-availability") { - degradedModeAvailability, _ := flags.GetString("degraded-mode-availability") - if (degradedModeAvailability == "enable" || - degradedModeAvailability == "disable") { - if (degradedModeAvailability == "enable") { - params["degraded_mode_availability"] = true - } - if (degradedModeAvailability == "disable") { - params["degraded_mode_availability"] = false - } - } else { - fmt.Printf("\nInvalid -d, --degraded-mode-availability option %s. " + - "Supported: enable (or) disable\n", degradedModeAvailability) - os.Exit(1) - } - } - - if flags.Changed("oidc-enabled") { - oidcEnabled, _ := flags.GetString("oidc-enabled") - if (oidcEnabled == "enable" || - oidcEnabled == "disable") { - if (oidcEnabled == "enable") { - params["oidc_enabled"] = true - } - if (oidcEnabled == "disable") { - params["oidc_enabled"] = false - } - } else { - fmt.Printf("\nInvalid -o, --oidc-enabled option %s. " + - "Supported: enable (or) disable\n", oidcEnabled) - os.Exit(1) - } - } - - revision, _ := flags.GetInt("revision") - params["revision"] = revision - - // JSONify - jsonParams, err := json.Marshal(params) - if (err != nil) { - fmt.Println("Error building JSON request: ", err) - os.Exit(1) - } - - // now POST - endpoint := GetEndPoint("", "1.0", "UpdateTenantSettings") - ret, err := DoPost(endpoint, - GetCACertFile(), - AuthTokenKV(), - jsonParams, - "application/json") - if err != nil { - fmt.Printf("\nHTTP request failed: %s\n", err) - os.Exit(4) - } else { - // type assertion - retBytes := ret["data"].(*bytes.Buffer) - retStatus := ret["status"].(int) - retStr := retBytes.String() - - if (retStr == "" && retStatus == 404) { - fmt.Println("\nKmip Settings not found\n") - os.Exit(5) - } - - fmt.Println("\n" + retStr + "\n") - - // make a decision on what to exit with - retMap := JsonStrToMap(retStr) - if _, present := retMap["error"]; present { - os.Exit(3) - } else { - os.Exit(0) - } - } - }, -} - -func init() { - rootCmd.AddCommand(updateKmipSettingsCmd) - updateKmipSettingsCmd.Flags().StringP("degraded-mode-availability", "d", "", - "Degraded mode availability. ") - updateKmipSettingsCmd.Flags().StringP("oidc-enabled", "o", "", - "OIDC enabled flag. ") - updateKmipSettingsCmd.Flags().IntP("revision", "R", 0, - "Revision number of the box") - - // mark mandatory fields as required - updateKmipSettingsCmd.MarkFlagRequired("revision") -}