Documentation
¶
Index ¶
- func CloneImage(sourceImageID int, targetImageName string, targetDatastoreID int, ...) (int, error)
- func CommHost(host string, ui packersdk.Ui) func(multistep.StateBag) (string, error)
- func GetVMState(ID int, state multistep.StateBag) (string, string, error)
- func NewOpenNebulaConnect(OpenNebulaURL, Username, Password string, Insecure bool) (*goca.Client, *goca.Controller, error)
- func WaitForResourceState(ID int, desiredState string, resourceType string, state multistep.StateBag, ...) error
- type Artifact
- type Builder
- type Config
- type FlatConfig
- type FlatImageConfig
- type FlatNICConfig
- type FlatSnapshotConfig
- type Global
- type ImageConfig
- type NICConfig
- type OpenNebulaConnect
- type SnapshotConfig
- type StepCloneDisk
- type StepCreateVM
- type StepDetachISO
- type StepPowerOffVM
- type StepProcessImages
- type StepStartVM
- type StepVNCBootCommand
- type VMTemplateConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloneImage ¶
func CloneImage(sourceImageID int, targetImageName string, targetDatastoreID int, state multistep.StateBag) (int, error)
CloneImage клонирует указанный образ в OpenNebula и возвращает ID нового.
func GetVMState ¶
GetVMState возвращает текущее состояние виртуальной машины.
func NewOpenNebulaConnect ¶
Types ¶
type Artifact ¶
type Artifact struct { ImageID string StateData map[string]interface{} Client *goca.Client Controller *goca.Controller // contains filtered or unexported fields }
type Builder ¶
type Builder struct { BuilderID string PreSteps []multistep.Step // contains filtered or unexported fields }
func NewSharedBuilder ¶
NewSharedBuilder creates a new shared builder for OpenNebula.
type Config ¶
type Config struct { common.PackerConfig `mapstructure:",squash"` commonsteps.HTTPConfig `mapstructure:",squash"` Global `mapstructure:",squash"` OpenNebulaConnect `mapstructure:",squash"` VMTemplateConfig VMTemplateConfig `mapstructure:",squash"` StepVNCBootCommand `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` Ctx interpolate.Context `mapstructure-to-hcl2:",skip"` }
func (*Config) FlatMapstructure ¶
FlatMapstructure returns a new FlatConfig. FlatConfig is an auto-generated flat version of Config. Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig ¶
type FlatConfig struct { PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"` PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"` PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"` PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"` PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"` PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` HTTPDir *string `mapstructure:"http_directory" cty:"http_directory" hcl:"http_directory"` HTTPContent map[string]string `mapstructure:"http_content" cty:"http_content" hcl:"http_content"` HTTPPortMin *int `mapstructure:"http_port_min" cty:"http_port_min" hcl:"http_port_min"` HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max" hcl:"http_port_max"` HTTPAddress *string `mapstructure:"http_bind_address" cty:"http_bind_address" hcl:"http_bind_address"` HTTPInterface *string `mapstructure:"http_interface" undocumented:"true" cty:"http_interface" hcl:"http_interface"` Datastore *string `mapstructure:"datastore" cty:"datastore" hcl:"datastore"` Debug *bool `mapstructure:"debug" cty:"debug" hcl:"debug"` EjectISO *bool `mapstructure:"eject_iso" cty:"eject_iso" hcl:"eject_iso"` EjectISODelay *string `mapstructure:"eject_iso_delay" cty:"eject_iso_delay" hcl:"eject_iso_delay"` SnapshotConfig *FlatSnapshotConfig `mapstructure:"snapshot" cty:"snapshot" hcl:"snapshot"` ImageConfigs []FlatImageConfig `mapstructure:"image" cty:"image" hcl:"image"` OpenNebulaURL *string `mapstructure:"opennebula_url" cty:"opennebula_url" hcl:"opennebula_url"` Username *string `mapstructure:"username" cty:"username" hcl:"username"` Password *string `mapstructure:"password" cty:"password" hcl:"password"` Insecure *bool `mapstructure:"insecure" cty:"insecure" hcl:"insecure"` Name *string `mapstructure:"vm_name" cty:"vm_name" hcl:"vm_name"` CPU *float64 `mapstructure:"vm_cpu" cty:"vm_cpu" hcl:"vm_cpu"` CPUModel *string `mapstructure:"vm_cpu_model" cty:"vm_cpu_model" hcl:"vm_cpu_model"` Description *string `mapstructure:"vm_description" cty:"vm_description" hcl:"vm_description"` EnableVNC *bool `mapstructure:"enable_vnc" cty:"enable_vnc" hcl:"enable_vnc"` GraphicsKeymap *string `mapstructure:"vm_graphics_keymap" cty:"vm_graphics_keymap" hcl:"vm_graphics_keymap"` GraphicsListen *string `mapstructure:"vm_graphics_listen" cty:"vm_graphics_listen" hcl:"vm_graphics_listen"` GraphicsType *string `mapstructure:"vm_graphics_type" cty:"vm_graphics_type" hcl:"vm_graphics_type"` Hypervisor *string `mapstructure:"vm_hypervisor" cty:"vm_hypervisor" hcl:"vm_hypervisor"` Logo *string `mapstructure:"vm_logo" cty:"vm_logo" hcl:"vm_logo"` Memory *int `mapstructure:"vm_memory" cty:"vm_memory" hcl:"vm_memory"` NICs []FlatNICConfig `mapstructure:"vm_nics" cty:"vm_nics" hcl:"vm_nics"` OSArch *string `mapstructure:"vm_os_arch" cty:"vm_os_arch" hcl:"vm_os_arch"` OSBoot *string `mapstructure:"vm_os_boot" cty:"vm_os_boot" hcl:"vm_os_boot"` VCPU *int `mapstructure:"vm_vcpu" cty:"vm_vcpu" hcl:"vm_vcpu"` UserData *string `mapstructure:"vm_user_data" cty:"vm_user_data" hcl:"vm_user_data"` BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"` BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` DisableVNC *bool `mapstructure:"disable_vnc" cty:"disable_vnc" hcl:"disable_vnc"` BootKeyInterval *string `mapstructure:"boot_key_interval" cty:"boot_key_interval" hcl:"boot_key_interval"` VNCPassword *string `mapstructure:"vm_vnc_password,omitempty" cty:"vm_vnc_password" hcl:"vm_vnc_password"` VNCIP *string `mapstructure:"vnc_ip" required:"false" cty:"vnc_ip" hcl:"vnc_ip"` VNCPort *int `mapstructure:"vnc_port" required:"false" cty:"vnc_port" hcl:"vnc_port"` BootSteps [][]string `mapstructure:"boot_steps" required:"false" cty:"boot_steps" hcl:"boot_steps"` Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"` PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"` SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"` SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port" hcl:"ssh_port"` SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"` SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"` SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"` SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"` SSHTemporaryKeyPairType *string `mapstructure:"temporary_key_pair_type" cty:"temporary_key_pair_type" hcl:"temporary_key_pair_type"` SSHTemporaryKeyPairBits *int `mapstructure:"temporary_key_pair_bits" cty:"temporary_key_pair_bits" hcl:"temporary_key_pair_bits"` SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"` SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"` SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"` SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" undocumented:"true" cty:"ssh_private_key_file" hcl:"ssh_private_key_file"` SSHCertificateFile *string `mapstructure:"ssh_certificate_file" cty:"ssh_certificate_file" hcl:"ssh_certificate_file"` SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty" hcl:"ssh_pty"` SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout" hcl:"ssh_timeout"` SSHWaitTimeout *string `mapstructure:"ssh_wait_timeout" undocumented:"true" cty:"ssh_wait_timeout" hcl:"ssh_wait_timeout"` SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" undocumented:"true" cty:"ssh_agent_auth" hcl:"ssh_agent_auth"` SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding" hcl:"ssh_disable_agent_forwarding"` SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts" hcl:"ssh_handshake_attempts"` SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host" hcl:"ssh_bastion_host"` SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port" hcl:"ssh_bastion_port"` SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth" hcl:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username" hcl:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password" hcl:"ssh_bastion_password"` SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive" hcl:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file" hcl:"ssh_bastion_private_key_file"` SSHBastionCertificateFile *string `mapstructure:"ssh_bastion_certificate_file" cty:"ssh_bastion_certificate_file" hcl:"ssh_bastion_certificate_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method" hcl:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host" hcl:"ssh_proxy_host"` SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port" hcl:"ssh_proxy_port"` SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username" hcl:"ssh_proxy_username"` SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password" hcl:"ssh_proxy_password"` SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval" hcl:"ssh_keep_alive_interval"` SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout" hcl:"ssh_read_write_timeout"` SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels" hcl:"ssh_remote_tunnels"` SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels" hcl:"ssh_local_tunnels"` SSHPublicKey []byte `mapstructure:"ssh_public_key" undocumented:"true" cty:"ssh_public_key" hcl:"ssh_public_key"` SSHPrivateKey []byte `mapstructure:"ssh_private_key" undocumented:"true" cty:"ssh_private_key" hcl:"ssh_private_key"` WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username" hcl:"winrm_username"` WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"` WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host" hcl:"winrm_host"` WinRMNoProxy *bool `mapstructure:"winrm_no_proxy" cty:"winrm_no_proxy" hcl:"winrm_no_proxy"` WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port" hcl:"winrm_port"` WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout" hcl:"winrm_timeout"` WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl" hcl:"winrm_use_ssl"` WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"` WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"` }
FlatConfig is an auto-generated flat version of Config. Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatImageConfig ¶
type FlatImageConfig struct { Image_ID *int `mapstructure:"id" cty:"id" hcl:"id"` Image_Name *string `mapstructure:"name" cty:"name" hcl:"name"` Image_Type *string `mapstructure:"type" cty:"type" hcl:"type"` Image_DatastoreID *int `mapstructure:"datastore_id" cty:"datastore_id" hcl:"datastore_id"` Image_Persistent *bool `mapstructure:"persistent" cty:"persistent" hcl:"persistent"` Image_Lock *string `mapstructure:"lock" cty:"lock" hcl:"lock"` Image_Permissions *int `mapstructure:"permissions" cty:"permissions" hcl:"permissions"` Image_Group *string `mapstructure:"group" cty:"group" hcl:"group"` Image_Path *string `mapstructure:"path" cty:"path" hcl:"path"` Image_DevPrefix *string `mapstructure:"dev_prefix" cty:"dev_prefix" hcl:"dev_prefix"` Image_Target *string `mapstructure:"target" cty:"target" hcl:"target"` Image_Driver *string `mapstructure:"driver" cty:"driver" hcl:"driver"` Image_Format *string `mapstructure:"format" cty:"format" hcl:"format"` Image_Size *int `mapstructure:"size" cty:"size" hcl:"size"` Image_CloneFromImage *string `mapstructure:"clone_from_image" cty:"clone_from_image" hcl:"clone_from_image"` Image_Tags []string `mapstructure:"tags" cty:"tags" hcl:"tags"` }
FlatImageConfig is an auto-generated flat version of ImageConfig. Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatNICConfig ¶
type FlatNICConfig struct {
Network *string `mapstructure:"network" cty:"network" hcl:"network"`
}
FlatNICConfig is an auto-generated flat version of NICConfig. Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatSnapshotConfig ¶
type FlatSnapshotConfig struct { Snapshot_Name *string `mapstructure:"name" cty:"name" hcl:"name"` Snapshot_DatastoreID *int `mapstructure:"datastore_id" cty:"datastore_id" hcl:"datastore_id"` }
FlatSnapshotConfig is an auto-generated flat version of SnapshotConfig. Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type Global ¶
type Global struct { Datastore string `mapstructure:"datastore"` // required:"true"` Debug bool `mapstructure:"debug"` EjectISO bool `mapstructure:"eject_iso"` EjectISODelay time.Duration `mapstructure:"eject_iso_delay"` SnapshotConfig SnapshotConfig `mapstructure:"snapshot"` ImageConfigs []ImageConfig `mapstructure:"image"` }
type ImageConfig ¶
type ImageConfig struct { Image_ID int `mapstructure:"id"` Image_Name string `mapstructure:"name"` Image_Type string `mapstructure:"type"` Image_DatastoreID int `mapstructure:"datastore_id"` Image_Persistent bool `mapstructure:"persistent"` Image_Lock string `mapstructure:"lock"` Image_Permissions int `mapstructure:"permissions"` Image_Group string `mapstructure:"group"` Image_Path string `mapstructure:"path"` Image_DevPrefix string `mapstructure:"dev_prefix"` Image_Target string `mapstructure:"target"` Image_Driver string `mapstructure:"driver"` Image_Format string `mapstructure:"format"` Image_Size int `mapstructure:"size"` Image_CloneFromImage string `mapstructure:"clone_from_image"` Image_Tags []string `mapstructure:"tags"` }
ImageConfig holds the configuration settings for the image
func (*ImageConfig) FlatMapstructure ¶
func (*ImageConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec }
FlatMapstructure returns a new FlatImageConfig. FlatImageConfig is an auto-generated flat version of ImageConfig. Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
type NICConfig ¶
type NICConfig struct {
Network string `mapstructure:"network"`
}
func (*NICConfig) FlatMapstructure ¶
FlatMapstructure returns a new FlatNICConfig. FlatNICConfig is an auto-generated flat version of NICConfig. Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
type OpenNebulaConnect ¶
type OpenNebulaConnect struct { OpenNebulaURL string `mapstructure:"opennebula_url"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` Insecure bool `mapstructure:"insecure"` Client *goca.Client `mapstructure-to-hcl2:",skip"` Controller *goca.Controller `mapstructure-to-hcl2:",skip"` }
type SnapshotConfig ¶
type SnapshotConfig struct { Snapshot_Name string `mapstructure:"name"` Snapshot_DatastoreID int `mapstructure:"datastore_id"` }
func (*SnapshotConfig) FlatMapstructure ¶
func (*SnapshotConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec }
FlatMapstructure returns a new FlatSnapshotConfig. FlatSnapshotConfig is an auto-generated flat version of SnapshotConfig. Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
type StepCloneDisk ¶
type StepCloneDisk struct { }
StepCloneDisk creates clones of disks that are not CDROM.
func (*StepCloneDisk) Cleanup ¶
func (s *StepCloneDisk) Cleanup(state multistep.StateBag)
Cleanup performs cleanup tasks if necessary.
func (*StepCloneDisk) Run ¶
func (s *StepCloneDisk) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction
Run executes the step to create clones of disks.
type StepCreateVM ¶
type StepCreateVM struct { //config Config VMTemplateConfig VMTemplateConfig OpenNebulaConnect OpenNebulaConnect }
func (*StepCreateVM) Cleanup ¶
func (s *StepCreateVM) Cleanup(state multistep.StateBag)
func (*StepCreateVM) Run ¶
func (s *StepCreateVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction
type StepDetachISO ¶
type StepDetachISO struct { }
StepDetachISO detaches the currently attached ISO file from a virtual machine if any.
func (*StepDetachISO) Cleanup ¶
func (s *StepDetachISO) Cleanup(state multistep.StateBag)
Cleanup performs cleanup tasks if necessary.
func (*StepDetachISO) Run ¶
func (s *StepDetachISO) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction
Run executes the step to detach the ISO file.
type StepPowerOffVM ¶
type StepPowerOffVM struct {
ShutdownMethod string
}
func (*StepPowerOffVM) Cleanup ¶
func (s *StepPowerOffVM) Cleanup(state multistep.StateBag)
func (*StepPowerOffVM) Run ¶
func (s *StepPowerOffVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction
Shuts down the virtual machine using the specified method.
type StepProcessImages ¶
type StepProcessImages struct {
Images []ImageConfig
}
StepProcessImages processes multiple image configurations.
func (*StepProcessImages) Cleanup ¶
func (s *StepProcessImages) Cleanup(state multistep.StateBag)
func (*StepProcessImages) Run ¶
func (s *StepProcessImages) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction
type StepStartVM ¶
type StepStartVM struct{}
func (*StepStartVM) Cleanup ¶
func (s *StepStartVM) Cleanup(state multistep.StateBag)
func (*StepStartVM) Run ¶
func (s *StepStartVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction
Starts the virtual machine.
type StepVNCBootCommand ¶
type StepVNCBootCommand struct { VNCConfig bootcommand.VNCConfig `mapstructure:",squash"` VNCPassword string `mapstructure:"vm_vnc_password,omitempty"` VNCIP string `mapstructure:"vnc_ip" required:"false"` VNCPort int `mapstructure:"vnc_port" required:"false"` BootSteps [][]string `mapstructure:"boot_steps" required:"false"` }
func (*StepVNCBootCommand) Cleanup ¶
func (s *StepVNCBootCommand) Cleanup(state multistep.StateBag)
func (*StepVNCBootCommand) Run ¶
func (s *StepVNCBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction
type VMTemplateConfig ¶
type VMTemplateConfig struct { Name string `mapstructure:"vm_name"` CPU float64 `mapstructure:"vm_cpu"` CPUModel string `mapstructure:"vm_cpu_model"` Description string `mapstructure:"vm_description"` EnableVNC bool `mapstructure:"enable_vnc"` GraphicsKeymap string `mapstructure:"vm_graphics_keymap"` GraphicsListen string `mapstructure:"vm_graphics_listen"` GraphicsType string `mapstructure:"vm_graphics_type"` Hypervisor string `mapstructure:"vm_hypervisor"` Logo string `mapstructure:"vm_logo"` Memory int `mapstructure:"vm_memory"` NICs []NICConfig `mapstructure:"vm_nics"` // Используется массив для сетевых интерфейсов OSArch string `mapstructure:"vm_os_arch"` OSBoot string `mapstructure:"vm_os_boot"` VCPU int `mapstructure:"vm_vcpu"` UserData string `mapstructure:"vm_user_data"` }