You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: enroll.go
    path of file: ./repos/ziti/common/enrollment
    
    the code of the file until where you have to start completion: /*
	Copyright NetFoundry Inc.

	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 enrollment

import (
	"encoding/json"
	"fmt"
	"github.com/openziti/identity/engines"
	"github.com/openziti/sdk-golang/ziti"
	"github.com/openziti/ziti/ziti/cmd/common"
	"os"
	"strings"

	"github.com/michaelquigley/pfxlog"
	"github.com/openziti/foundation/v2/term"
	"github.com/openziti/sdk-golang/ziti/enroll"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

// global state used by all subcommands are located here for easy discovery

const outpathDesc = "Output configuration file."
const jwtpathDesc = "Enrollment token (JWT file). Required"
const certDesc = "The certificate to present when establishing a connection."
const idnameDesc = "Names the identity. Ignored if not 3rd party auto enrollment"

const outFlag = "out"

// EnrollOptions contains the command line options
type EnrollOptions struct {
	common.CommonOptions
	RemoveJwt  bool
	KeyAlg     ziti.KeyAlgVar
	JwtPath    string
	OutputPath string
	KeyPath    string
	CertPath   string
	IdName     string
	CaOverride string
	Username   string
	Password   string
}

type EnrollAction struct {
	EnrollOptions
}

func NewEnrollCommand(p common.OptionsProvider) *cobra.Command {
	action := &EnrollAction{
		Enrol
    
func (e *EnrollAction) Run() error {
	if strings.TrimSpace(e.OutputPath) == "" {
		out, outErr := outPathFromJwt(e.JwtPath)
		if outErr != nil {
			return fmt.Errorf("could not set the output path: %s", outErr)
		}
		e.OutputPath = out
	}

	if e.JwtPath != "" {
		if _, err := os.Stat(e.JwtPath); os.IsNotExist(err) {
			return fmt.Errorf("the provided jwt file does not exist: %s", e.JwtPath)
		}
	}

	if e.CaOverride != "" {
		if _, err := os.Stat(e.CaOverride); os.IsNotExist(err) {
			return fmt.Errorf("the provided ca file does not exist: %s", e.CaOverride)
		}
	}

	if strings.TrimSpace(e.OutputPath) == strings.TrimSpace(e.JwtPath) {
		return fmt.Errorf("the output path must not be the same as the jwt path")
	}

	tokenStr, _ := os.ReadFile(e.JwtPath)

	pfxlog.Logger().Debugf("jwt to parse: %s", tokenStr)
	tkn, _, err := enroll.ParseToken(string(tokenStr))

	if err != nil {
		return fmt.Errorf("failed to parse JWT: %s", err.Error())
	}

	flags := enroll.EnrollmentFlags{
		CertFile:      e.CertPath,
		KeyFile:       e.KeyPath,
		KeyAlg:        e.KeyAlg,
		Token:         tkn,
		IDName:        e.IdName,
		AdditionalCAs: e.CaOverride,
		Username:      e.Username,
		Password:      e.Password,
		Verbose:       e.Verbose,
	}

	if tkn.EnrollmentMethod == "updb" {
		if e.Password == "" {
			e.Password, err = term.PromptPassword("updb enrollment requires a password, please enter one: ", false)
			e.Password = strings.TrimSpace(e.Password)

			if err != nil {
				return fmt.Errorf("failed to complete enrollment, updb requires a non-empty password: %v", err)
			}

			confirm, err := term.PromptPassword("please confirm what you entered: ", false)

			if err != nil {
				return fmt.Errorf("failed to complete enrollment, updb password confirmation failed: %v", err)
			}

			confirm = strings.TrimSpace(confirm)

			if e.Password != confirm {
				return fmt.Errorf("failed to complete enrollment, passwords did not match")
			}

			flags.Password = e.Password
		}

		err = enroll.EnrollUpdb(flags)
		if err == nil {
			if rmErr := os.Remove(e.JwtPath); rmErr != nil {
				pfxlog.Logger().WithError(rmErr).Warnf("unable to remove JWT file as requested: %v", e.JwtPath)
			}
		}
		return err
	}

	conf, err := enroll.Enroll(flags)
	if err != nil {
		return fmt.Errorf("failed to enroll: %v", err)
	}

	output, err := os.Create(e.OutputPath)
	if err != nil {
		return fmt.Errorf("failed to open file '%s': %s", e.OutputPath, err.Error())
	}
	defer func() { _ = output.Close() }()

	enc := json.NewEncoder(output)
	enc.SetEscapeHTML(false)
	encErr := enc.Encode(&conf)

	if err = os.Remove(e.JwtPath); err != nil {
		pfxlog.Logger().WithError(err).Warnf("unable to remove JWT file as requested: %v", e.JwtPath)
	}

	if encErr == nil {
		pfxlog.Logger().Infof("enrolled successfully. identity file written to: %s", e.OutputPath)
		return nil
	} else {
		return fmt.Errorf("enrollment successful but the identity file was not able to be written to: %s [%s]", e.OutputPath, encErr)
	}
}