### Implement Plugin Settings Getter Source: https://developer.morpheusdata.com/docs/index Defines the 'getSettings' method to return a list of OptionType settings for a plugin. This allows users to configure plugin options globally after installation. The settings are managed via the OptionType and OptionProvider entities. ```java class MyPlugin extends Plugin { /** * Returns a list of {@link OptionType} settings for this plugin. * @return this list of settings */ public List getSettings() { return this.settings; } } ``` -------------------------------- ### Test Infoblox Provider with Spock (Groovy) Source: https://developer.morpheusdata.com/docs/index Provides an example of unit testing an `InfobloxProvider` using Spock. It demonstrates mocking Morpheus contexts and API clients, setting up test data, and asserting the response of the `listNetworks` method. ```Groovy class InfobloxProviderSpec extends Specification { @Shared MorpheusContext context @Shared InfobloxPlugin plugin @Shared InfobloxAPI infobloxAPI @Shared MorpheusNetworkContext networkContext @Subject @Shared InfobloxProvider provider void setup() { // Create a Mocks of the Morepohus contexts you will use context = Mock(MorpheusContextImpl) networkContext = Mock(MorpheusNetworkContext) context.getNetwork() >> networkContext plugin = Mock(InfobloxPlugin) infobloxAPI = Mock(InfobloxAPI) // Create the actual provider to unit test provider = new InfobloxProvider(plugin, context, infobloxAPI) } void "listNetworks"() { given: "A pool server" def poolServer = new NetworkPoolServer(apiPort: 8080, serviceUrl: "http://localhost") // Here we are stubbing the actual API call to infoblox, but we could create a integration test by actually providing the real infoblox API class instead of a mock. infobloxAPI.callApi(_, _, _, _, _, _) >> new ServiceResponse(success: true, errors: null , content:'{"foo": 1}') when: "We list the networks" def response = provider.listNetworks(poolServer, [doPaging: false]) then: "We get a response" response.size() == 1 } } ``` -------------------------------- ### Example Morpheus Data Query with Filters Source: https://developer.morpheusdata.com/docs/index Demonstrates how to use DataQuery with complex filters in Morpheus. This example uses DataOrFilter to find clouds based on multiple external or linked account IDs. The query is executed asynchronously. ```groovy def usageClouds = morpheusContext.async.cloud.list( new DataQuery().withFilters( new DataOrFilter( new DataFilter("externalId","in",usageAccountIds), new DataFilter("linkedAccountId","in",usageAccountIds) ) ) ).toList().blockingGet() ``` -------------------------------- ### HCL Resource: Instance Type Layout referencing Ubuntu Source: https://developer.morpheusdata.com/docs/index Defines an 'instance-type-layout' in HCL, referencing the built-in Morpheus 'ubuntu' instance type. This example showcases how to define layouts for provisioning, including server count, port count, and provisioning types like 'demo-provision-provider'. ```hcl resource "instance-type-layout" "demo-ubuntu-22" { code = "demo-ubuntu-22" name = "Demo VM" sortOrder = 22 instanceVersion = "22" description = "This will provision a single vm" instanceType { code = "ubuntu" } serverCount = 1 hasAutoScale = true portCount = 1 serverType = "vm" enabled = true creatable = true supportsConvertToManaged = true provisionType = "demo-provision-provider" } ``` -------------------------------- ### Define Plugin Routes and HTML/JSON Responses Source: https://developer.morpheusdata.com/docs/index This example demonstrates how to define routes for a plugin controller using the Route builder. It specifies URLs, response types (HTML or JSON), and associated permissions. The controller methods handle generating either an HTMLResponse or a JsonResponse based on the requested route. ```Groovy class MyPluginController implements PluginController { List getRoutes() { [ Route.build("/myPrefix/example", "html", Permission.build("admin", "full")), Route.build("/reverseTask/json", "json", Permission.build("admin", "full")) ] } def html(ViewModel model) { return HTMLResponse.success("Some Text") } def json(ViewModel model) { Map simpleMap = [serverid: "abc-123", other: model.object.someData] return JsonResponse.of(simpleMap) } } ``` -------------------------------- ### Call External APIs with HttpApiClient Source: https://developer.morpheusdata.com/docs/index This example demonstrates using the HttpApiClient utility to make calls to external APIs. It shows how to instantiate the client, configure request options (like headers and query parameters), make the call (e.g., callJsonApi), handle potential errors, and ensure the client is shut down properly in a finally block. ```Groovy import com.morpheusdata.core.util.HttpApiClient HttpApiClient infobloxClient = new HttpApiClient() try { def results = infobloxClient.callJsonApi(serviceUrl, apiPath, poolServer.serviceUsername, poolServer.servicePassword, new HttpApiClient.RequestOptions(headers:['Content-Type':'application/json'], queryParams:pageQuery, ignoreSSL: poolServer.ignoreSsl), 'GET') } catch(e) { log.error("verifyPoolServer error: ${e}", e) } finally { infobloxClient.shutdownClient() } return rtn ``` -------------------------------- ### Implement GoogleOptionSourceProvider for Morpheus Source: https://developer.morpheusdata.com/docs/index Example implementation of OptionSourceProvider for Google Cloud Plugin. It defines methods to fetch Google Cloud projects, regions, etc. Methods accept a single Object argument (Map) and return a List> with 'name' and 'value' keys. Dependencies include GoogleApiService. ```Groovy class GoogleOptionSourceProvider implements OptionSourceProvider { @Override List getMethodNames() { return new ArrayList(['googlePluginProjects', 'googlePluginRegions', 'googlePluginZonePools', 'googlePluginMtu']) } def googlePluginProjects(args) { Map authConfig = getAuthConfig(args) def projectResults = [] if(authConfig.clientEmail && authConfig.privateKey) { def listResults = GoogleApiService.listProjects(authConfig) if(listResults.success) { projectResults = listResults.projects?.collect { [name: it.name, value: it.projectId] } projectResults = projectResults.sort { a, b -> a.name?.toLowerCase() <=> b.name?.toLowerCase() } } } projectResults } } ``` -------------------------------- ### Defining OptionTypes for Cloud Configuration Source: https://developer.morpheusdata.com/docs/index Define `OptionType` objects to provide configuration inputs for the Cloud setup wizard and `ComputeServerType` objects. These options specify the type of input fields (e.g., text, password, dropdown) and their behavior. Multiple `ComputeServerType` objects can be defined based on platform and management state. ```java import com.morpheusdata.core.CloudProvider; import com.morpheusdata.model.OptionType; import java.util.Arrays; import java.util.List; public class MyCloudProvider implements CloudProvider { @Override public List getOptionTypes() { OptionType usernameOption = new OptionType(); usernameOption.setFieldName("serviceUsername"); usernameOption.setLabel("Service Username"); usernameOption.setInputType("text"); OptionType passwordOption = new OptionType(); passwordOption.setFieldName("servicePassword"); passwordOption.setLabel("Service Password"); passwordOption.setInputType("password"); return Arrays.asList(usernameOption, passwordOption); } // Other CloudProvider methods... } ``` -------------------------------- ### Define Backup Provider with Scoped Providers - Groovy Source: https://developer.morpheusdata.com/docs/index This example illustrates the creation of a primary backup provider that manages multiple scoped backup type providers. It extends `AbstractBackupProvider` and registers specific providers for 'vmware' and 'hyperv' provision types. The `getIcon` method is also shown for defining custom plugin icons. ```groovy class MyPluginBackupProvider extends AbstractBackupProvider { MyPluginBackupProvider(Plugin plugin, MorpheusContext morpheusContext) { super(plugin, morpheusContext) MyVmwareBackupProvider vmwareBackupProvider = new MyVmwareBackupProvider(plugin, morpheus) plugin.registerProvider(vmwareBackupProvider) addScopedProvider(vmwareBackupProvider, "vmware", null) MyHypervBackupProvider hypervBackupProvider = new MyHypervBackupProvider(plugin, morpheus) plugin.registerProvider(hypervBackupProvider) addScopedProvider(hypervBackupProvider, "hyperv", null) } @Override String getCode() { return 'my-backup-provider' } @Override String getName() { return 'My Backup Provider' } @Override Icon getIcon() { return new Icon(path:"icon.svg", darkPath: "icon-dark.svg") } ... } ``` -------------------------------- ### Render Server Tab Template Source: https://developer.morpheusdata.com/docs/index This snippet illustrates rendering a custom tab for a Server's UI. By extending `AbstractServerTabProvider`, you can bind the `ComputeServer` object to a `ViewModel` and use `getRenderer().renderTemplate` to display content, typically using Handlebars templating. The example uses `hbs/serverTab` as the template path. ```Groovy @Override HTMLResponse renderTemplate(ComputeServer server) { ViewModel model = new ViewModel<>() model.object = server getRenderer().renderTemplate("hbs/serverTab", model) } ``` -------------------------------- ### Include Static Assets in Handlebars Templates Source: https://developer.morpheusdata.com/docs/index This example shows how to reference static assets (like JavaScript and images) within Handlebars templates using the `{{ asset }}` helper. Assets should be placed under `src/assets/{plugin-code}`. ```HTML ``` -------------------------------- ### Define Morpheus OptionType using Custom Option Source Source: https://developer.morpheusdata.com/docs/index Configuration of an OptionType in Morpheus, linking it to a custom option source. This example sets up a 'Region' option type that sources its data from the 'googlePluginRegions' method defined in an OptionSourceProvider. ```Groovy OptionType ot4 = new OptionType( name: 'Region', code: 'google-plugin-region', fieldName: 'googleRegionId', optionSource: 'googlePluginRegions', //Note the Option Source Defined here. displayOrder: 3, fieldLabel: 'Region', required: true, inputType: OptionType.InputType.SELECT, dependsOn: 'google-plugin-project-id', fieldContext: 'config' ) ``` -------------------------------- ### Groovy Custom Report Filter Options Source: https://developer.morpheusdata.com/docs/index Implements the `getOptionTypes` method to provide custom filter options for a report. This example creates a text input field for searching by phrase, which is configured with a specific code, name, field name, context, and display order. ```Groovy @Override List getOptionTypes() { [new OptionType(code: 'status-report-search', name: 'Search', fieldName: 'phrase', fieldContext: 'config', fieldLabel: 'Search Phrase', displayOrder: 0)] } ``` -------------------------------- ### Implement DatastoreTypeProvider and StorageProvider in Java Source: https://developer.morpheusdata.com/docs/index This code demonstrates how to implement the DatastoreTypeProvider and StorageProvider interfaces in Java. It includes facets for MvmProvisioning and Snapshots, and shows how to define the storage provider code. IDEs can often auto-generate the required methods. ```java class MyCustomDatastoreTypeProvider implements DatastoreTypeProvider, DatastoreTypeProvider.MvmProvisionFacet, DatastoreTypeProvider.SnapshotFacet.SnapshotServerFacet { @Override String getStorageProviderCode() { return 'my-storage-provider-code' } // Implement required methods here for all 3 interfaces } class MyCustomStorageProvider implements StorageProvider { @Override String getCode() { return 'my-storage-provider-code' } } ``` -------------------------------- ### Render Instance Tab Template Source: https://developer.morpheusdata.com/docs/index This code demonstrates how to render a custom tab for an Instance's UI. It extends `AbstractInstanceTabProvider`, binds the `Instance` object to a `ViewModel`, and uses `getRenderer().renderTemplate` to display the content using Handlebars. The `hbs/instanceTab` path specifies the template to use. ```Groovy @Override HTMLResponse renderTemplate(Instance instance) { ViewModel model = new ViewModel<>() model.object = instance getRenderer().renderTemplate("hbs/instanceTab", model) } ``` -------------------------------- ### Standard Catalog Layout Provider Implementation in Groovy Source: https://developer.morpheusdata.com/docs/index This Groovy class extends AbstractCatalogItemLayoutProvider to define a standard layout for catalog items. It initializes with a Plugin and MorpheusContext, and its renderTemplate method prepares a ViewModel with the CatalogItemType and uses a Handlebars template for rendering the HTML response. Dependencies include MorpheusContext and Plugin classes. ```groovy /** * Example TabProvider */ class StandardCatalogLayoutProvider extends AbstractCatalogItemLayoutProvider { Plugin plugin MorpheusContext morpheus String code = 'catalog-item-standard' String name = 'Standard Catalog Layout' StandardCatalogLayoutProvider(Plugin plugin, MorpheusContext context) { this.plugin = plugin this.morpheus = context } /** * Demonstrates building a TaskConfig to get details about the Server and renders the html from the specified template. * @param server details of a ComputeServer * @return */ @Override HTMLResponse renderTemplate(CatalogItemType catalogItemType, User user) { ViewModel model = new ViewModel<>() model.object = catalogItemType getRenderer().renderTemplate("hbs/standardCatalogItem", model) } } ``` -------------------------------- ### HCL Resource: Instance Type Definition with Option Type Reference Source: https://developer.morpheusdata.com/docs/index Defines an 'instance-type' resource in HCL, demonstrating how to reference a previously defined 'option-type'. This allows for creating complex instance configurations that utilize custom option selections. Ensure dependent plugins are loaded first. ```hcl resource "instance-type" "demo-instance" { name = "Demo Instance" code = "demo-instance" description = "Spin up any VM on our Demo infrastructure." environmentPrefix = "DEMO" category = "cloud" active = true enabled = true versions = ["1.0"] optionTypes = [ option-type.demo-option ] provisionTypeDefault = true pluginIconPath = "demo.svg" pluginIconHidpiPath= "demo.svg" pluginIconDarkPath = "demo-dark.svg" pluginIconDarkHidpiPath = "demo-dark.svg" } ``` -------------------------------- ### Sync Data with SyncTask in Groovy Source: https://developer.morpheusdata.com/docs/index Synchronizes data from a remote endpoint into Morpheus using the SyncTask utility. It handles matching, adding, updating, and deleting records by comparing identity objects with API results. Dependencies include Morpheus context and specific model classes like CloudRegion and Region. Input is an Observable of identity projections and a collection of region data. Output is a started SyncTask. ```Groovy Observable domainRecords = morpheusContext.async.cloud.region.listIdentityProjections(cloud.id) SyncTask syncTask = new SyncTask<>(domainRecords, regionResults.regionList as Collection) syncTask.addMatchFunction { CloudRegionIdentity domainObject, Region data -> domainObject.externalId == data.getRegionName() }.onDelete { removeItems -> removeMissingRegions(removeItems) }.onUpdate { List> updateItems -> updateRegions(updateItems) }.onAdd { itemsToAdd -> addMissingRegions(itemsToAdd, this.@cloud.account) }.withLoadObjectDetailsFromFinder { List> updateItems -> morpheusContext.async.cloud.region.listById(updateItems.collect { it.existingItem.id } as List) }.start() ``` -------------------------------- ### Implement Morpheus Backup Provider in Java Source: https://developer.morpheusdata.com/docs/index This Java code defines a custom backup provider that extends the MorpheusBackupProvider class. It initializes and registers a specific snapshot backup provider and scopes it for 'vmware' operations. This allows Morpheus to manage backup jobs while delegating execution and restore to the plugin. ```java class MyBackupProvider extends MorpheusBackupProvider { MyBackupProvider(Plugin plugin, MorpheusContext context) { super(plugin, context) MySnapshotBackupProvider mySnapshotBackupProvider = new MySnapshotBackupProvider(plugin, morpheus) plugin.registerProvider(mySnapshotBackupProvider) addScopedProvider(mySnapshotBackupProvider, "vmware", null) } } ``` -------------------------------- ### Gradle Build Configuration for Morpheus Plugin Source: https://developer.morpheusdata.com/docs/index Sets up a Gradle project for Morpheus plugin development. It applies the shadowjar plugin for fat JAR creation and the Morpheus plugin Gradle plugin. It also defines repositories, dependencies, and Java/Groovy compatibility. ```gradle plugins { id "com.bertramlabs.asset-pipeline" version "4.3.0" id "com.github.johnrengelman.shadow" version "6.0.0" } buildscript { repositories { mavenCentral() } dependencies { classpath "com.morpheusdata:morpheus-plugin-gradle:0.14.3" } } apply plugin: 'com.morpheusdata.morpheus-plugin-gradle' apply plugin: 'java' apply plugin: 'groovy' apply plugin: 'maven-publish' group = 'com.example' version = '1.0.0' sourceCompatibility = '1.11' targetCompatibility = '1.11' ext.isReleaseVersion = !version.endsWith("SNAPSHOT") repositories { mavenCentral() } configurations { provided } dependencies { provided 'com.morpheusdata:morpheus-plugin-api:0.12.5' //use 0.13.4 for 5.5.x provided 'org.codehaus.groovy:groovy-all:3.0.9' /* When using custom libraries, use the gradle `implementation` directive instead of `provided`. This will allow shadowJar to package the library into the resulting plugin and keep it isolated within the same classloader. */ } tasks.assemble.dependsOn tasks.shadowJar ``` -------------------------------- ### Implement VMware Backup Type Provider in Java Source: https://developer.morpheusdata.com/docs/index This Java code defines a custom backup type provider for VMware environments, extending AbstractBackupTypeProvider. It specifies unique codes and names, provides an empty collection of option types, and returns SnapshotExecutionProvider and SnapshotRestoreProvider instances for backup and restore operations. ```java class MyVmwareBackupProvider extends AbstractBackupTypeProvider { MyVmwareBackupProvider(Plugin plugin, MorpheusContext context) { super(plugin, context) } @Override String getCode() { return "my-vmware-backup-provider" } @Override String getName() { return "MY VMware backup provider" } @Override Collection getOptionTypes() { return new ArrayList() } @Override BackupExecutionProvider getExecutionProvider() { return new SnapshotExecutionProvider() } @Override BackupRestoreProvider getRestoreProvider() { return new SnapshotRestoreProvider() } ... } ``` -------------------------------- ### CloudProvider Interface Implementation Source: https://developer.morpheusdata.com/docs/index Implement the `com.morpheusdata.core.CloudProvider` interface to define cloud integration. This includes methods for syncing existing workloads, state changes, and larger data syncs like pricing information. The `refresh()` method typically handles periodic state syncs, while `refreshDaily()` manages less frequent updates. ```java import com.morpheusdata.core.CloudProvider; public class MyCloudProvider implements CloudProvider { @Override public void refresh() { // Code for periodic state syncs (e.g., every 5 minutes) } @Override public void refreshDaily() { // Code for daily larger syncs (e.g., price data at Midnight UTC) } // Other CloudProvider methods must be implemented... } ``` -------------------------------- ### Fetch and Deserialize Plugin Settings Source: https://developer.morpheusdata.com/docs/index Retrieves plugin settings as a JSON string from the morpheusContext and deserializes it. The 'morpheusContext.getSettings(Plugin plugin)' method returns an rxJava Single which needs to be blocked and parsed. ```groovy String pluginSettings = morpheus.getSettings(this.plugin).blockingGet() def pluginDeserialized = new JsonSlurper().parseText(pluginSettings) ``` -------------------------------- ### Java AbstractDataSetProvider Implementation Source: https://developer.morpheusdata.com/docs/index Illustrates the creation of a Java `OptionType` that leverages a `DataSetProvider` for dynamic data. It specifies the `optionSourceType` (namespace) and `optionSource` (key) to link the form input to the dataset. ```java OptionType ot4 = new OptionType( name: 'Region', code: 'google-plugin-region', fieldName: 'googleRegionId', optionSourceType: 'google', // Note: this references the dataset namespace. optionSource: 'googlePluginRegions', // Note: this references the dataset key. displayOrder: 3, fieldLabel: 'Region', required: true, inputType: OptionType.InputType.SELECT, dependsOn: 'google-plugin-project-id', fieldContext: 'config' ) ``` -------------------------------- ### Define Infoblox Provider OptionTypes (Groovy) Source: https://developer.morpheusdata.com/docs/index Defines the available OptionTypes for the Infoblox provider, including service URL, credentials, username, and password. It demonstrates how to use `OptionType.InputType.CREDENTIAL` and set `localCredential:true` for fields that should be exposed when using local credentials. ```Groovy class InfobloxProvider implements IPAMProvider, DNSProvider { @Override List getIntegrationOptionTypes() { return [ new OptionType(code: 'infoblox.serviceUrl', name: 'Service URL', inputType: OptionType.InputType.TEXT, fieldName: 'serviceUrl', fieldLabel: 'API Url', fieldContext: 'domain', placeHolder: 'https://x.x.x.x/wapi/v2.2.1', helpBlock: 'Warning! Using HTTP URLS are insecure and not recommended.', displayOrder: 0, required:true), new OptionType(code: 'infoblox.credentials', name: 'Credentials', inputType: OptionType.InputType.CREDENTIAL, fieldName: 'type', fieldLabel: 'Credentials', fieldContext: 'credential', required: true, displayOrder: 1, defaultValue: 'local',optionSource: 'credentials',config: '{"credentialTypes":["username-password"]}'), new OptionType(code: 'infoblox.serviceUsername', name: 'Service Username', inputType: OptionType.InputType.TEXT, fieldName: 'serviceUsername', fieldLabel: 'Username', fieldContext: 'domain', displayOrder: 2,localCredential: true), new OptionType(code: 'infoblox.servicePassword', name: 'Service Password', inputType: OptionType.InputType.PASSWORD, fieldName: 'servicePassword', fieldLabel: 'Password', fieldContext: 'domain', displayOrder: 3,localCredential: true), ... } } ``` -------------------------------- ### Define Task Options Source: https://developer.morpheusdata.com/docs/index This snippet shows how to define configuration options for a Morpheus task. It involves creating an `OptionType` object with various properties like name, code, field name, and input type, then returning it as a list. Dependencies include `com.morpheusdata.model.OptionType`. ```Groovy @Override List getOptionTypes() { OptionType optionType = new OptionType( name: 'myTask', code: 'myTaskText', fieldName: 'myTask', optionSource: true, displayOrder: 0, fieldLabel: 'Text to Reverse', required: true, inputType: OptionType.InputType.TEXT ) return [optionType] } ``` -------------------------------- ### Call Infoblox API with Credentials (Groovy) Source: https://developer.morpheusdata.com/docs/index Shows how to make a remote API call to the Infoblox integration, correctly referencing credential data. It prioritizes checking the `credentialData` map on `poolServer` for username and password before falling back to `poolServer.serviceUsername` and `poolServer.servicePassword`. ```Groovy results = client.callApi(serviceUrl, apiPath, poolServer.credentialData?.username ?: poolServer.serviceUsername, poolServer.credentialData?.password ?: poolServer.servicePassword, new HttpApiClient.RequestOptions(headers:['Content-Type':'application/json'], ignoreSSL: poolServer.ignoreSsl,body:body), 'POST') ``` -------------------------------- ### JAR Manifest Configuration for Morpheus Plugin Source: https://developer.morpheusdata.com/docs/index Configures the JAR manifest file to include essential metadata for Morpheus plugin identification and loading. This includes the main plugin class, version, name, organization, and other details required by the Morpheus platform. ```gradle jar { manifest { attributes( 'Plugin-Class': 'com.example.MyPlugin', //Reference to Plugin class 'Plugin-Version': archiveVersion.get() // Get version defined in gradle 'Morpheus-Name': 'Plugin Name', 'Morpheus-Organization': 'My Organization', 'Morpheus-Code': 'plugin-code', 'Morpheus-Description': 'My Plugin Description', 'Morpheus-Logo': 'assets/myplugin.svg', 'Morpheus-Logo-Dark': 'assets/myplugin-dark.svg', 'Morpheus-Labels': 'Plugin, Stuff', 'Morpheus-Repo': 'https://github.com/myorg/myrepo', 'Morpheus-Min-Appliance-Version': "5.5.2" ) } } ``` -------------------------------- ### Override Backup Provider Detail View in Java Source: https://developer.morpheusdata.com/docs/index This Java code demonstrates how to override the entire backup integration detail view by extending AbstractBackupProvider and implementing the renderTemplate method. It sets up a ViewModel with the backup provider object and uses a HandlebarsRenderer to render a custom view ('hbs/myBackupProviderView'). The getRenderer method ensures the HandlebarsRenderer is initialized with necessary helpers. ```java class MyBackupProvider extends AbstractBackupProvider { private HandlebarsRenderer renderer /... @Override HTMLResponse renderTemplate(com.morpheusdata.model.BackupProvider backupProvider) { ViewModel model = new ViewModel<>() model.object = backupProvider return getRenderer().renderTemplate("hbs/myBackupProviderView", model) } // we need to implement a renderer to use handlebars Renderer getRenderer() { if(renderer == null) { renderer = new HandlebarsRenderer("renderer", getPlugin().getClassLoader()) renderer.registerAssetHelper(getPlugin().getName()) renderer.registerNonceHelper(getMorpheus().getWebRequest()) renderer.registerI18nHelper(getPlugin(),getMorpheus()) } return renderer } } ``` -------------------------------- ### Handlebars i18n Helper for Server-Side Rendering Source: https://developer.morpheusdata.com/docs/index Demonstrates how to use the `{{i18n}}` helper within Handlebars templates to render localized strings. It takes a localization key as an argument and displays the appropriate translated text. ```html {{i18n 'com.morpheusdata.label.hello'}} ``` -------------------------------- ### Implement Backup Provider Refresh Method in Java Source: https://developer.morpheusdata.com/docs/index This Java code snippet demonstrates how to implement the refresh method for a backup provider, ensuring data synchronization. It utilizes a BackupSyncTask within a try-catch block to handle potential exceptions during the synchronization process, logging any errors encountered. ```java @Slf4j class MyPluginBackupProvider extends AbstractBackupProvider { /... @Override ServiceResponse refresh(BackupProvider backupProvider) { ServiceResponse rtn = ServiceResponse.prepare() try { new BackupSyncTask().execute() } catch(Exception e) { log.error("error refreshing backup provider {}::{}: {}", plugin.name, this.name, e) } return rtn } /... } ``` -------------------------------- ### Register Backup Provider in Plugin - Groovy Source: https://developer.morpheusdata.com/docs/index This code snippet demonstrates how to register a custom backup provider within a Morpheus plugin. It overrides the getCode, getName, and initialize methods to set up and register the backup provider instance. This is a fundamental step for enabling backup functionalities in your plugin. ```groovy class MyPlugin extends Plugin { @Override String getCode() { return 'my-plugin' } @Override String getName() { return 'My Plugin' } @Override void initialize() { MyPluginBackupProvider backupProvider = new MyPluginBackupProvider(this, morpheus) registerProvider(backupProvider) } } ``` -------------------------------- ### Basic Morpheus Plugin Class Structure Source: https://developer.morpheusdata.com/docs/index Defines the main plugin class for a Morpheus Data plugin. It extends the `com.morpheus.core.Plugin` class and overrides the `initialize` method to set plugin metadata and register necessary providers, such as custom tab providers. ```java import com.morpheus.core.Plugin; class MyPlugin extends Plugin { @Override void initialize() { this.setName("My Custom Tabs Plugin"); CustomTabProvider tabProvider = new CustomTabProvider(this, morpheus); this.registerProvider(tabProvider); } } ``` -------------------------------- ### Check User Permissions for Instance Tab Visibility Source: https://developer.morpheusdata.com/docs/index This Groovy code implements the `show` method of `InstanceTabProvider` to conditionally display an Instance tab. It iterates through defined permissions and checks if the current user has the required access level, returning `false` if any permission check fails. ```Groovy @Override Boolean show(Instance instance, User user, Account account) { def show = true plugin.permissions.each { Permission permission -> if(user.permissions[permission.code] != permission.availableAccessTypes.last().toString()){ show = false } } return show } ``` -------------------------------- ### Render Handlebars Template View Source: https://developer.morpheusdata.com/docs/index This snippet illustrates how to render an HTML view using the provided Handlebars template engine. It assumes views are located in `src/main/resources/renderer//` and shows how to call the renderer with a template name and a model. ```Groovy getRenderer().renderTemplate("prefix/someview", model); ``` -------------------------------- ### Register Plugin Controller Source: https://developer.morpheusdata.com/docs/index This Java code snippet shows how to register a custom plugin controller within the plugin's initialization process. It involves creating an instance of the controller and adding it to the plugin's controller list. ```Java @Override void initialize() { this.setName("My Custom Task Plugin"); CustomTaskProvider taskProvider = new CustomTaskProvider(this, morpheusContext); this.pluginProviders.put(taskProvider.providerCode, taskProvider); this.controllers.add(new MyPluginController()); } ``` -------------------------------- ### JavaScript Localization Function Source: https://developer.morpheusdata.com/docs/index Shows how to use the `$L` function in JavaScript for client-side localization. It accepts an object with a 'code' for the localization key and an optional 'default' value to fall back on. ```javascript var helloString = $L({code: 'com.morpheusdata.label.hello', default: 'Hello'}); ``` -------------------------------- ### Localization Properties Files Source: https://developer.morpheusdata.com/docs/index Defines key-value pairs for text localization. `messages.properties` is the default, while `messages_es.properties` provides Spanish translations. These are used to dynamically display localized strings based on the user's locale. ```properties com.morpheusdata.label.hello=Hello ``` ```properties com.morpheusdata.label.hello=Hola ``` -------------------------------- ### Configure Content Security Policy for UI Source: https://developer.morpheusdata.com/docs/index This snippet defines Content Security Policy directives for a Morpheus UI tab. It customizes `scriptSrc`, `frameSrc`, `imgSrc`, and `styleSrc` to allow loading resources from specified domains, enhancing security by restricting where content can be loaded from. ```Groovy @Override TabContentSecurityPolicy getContentSecurityPolicy() { def csp = new TabContentSecurityPolicy() csp.scriptSrc = '*.jsdelivr.net' csp.frameSrc = '*.digitalocean.com' csp.imgSrc = '*.wikimedia.org' csp.styleSrc = 'https: *.bootstrapcdn.com' csp } ``` -------------------------------- ### HCL Resource: Option Type Definition Source: https://developer.morpheusdata.com/docs/index Defines an 'option-type' resource in HCL format for Morpheus plugins. This resource typically represents a selectable option within a configuration, referencing a DatasetProvider via 'optionSource'. ```hcl resource "option-type" "demo-option" { name = "Demo Option" code = "demo-option" fieldName = "demoOption" fieldContext = "config" fieldLabel = "Demo Option" type = "select" displayOrder = 10 required = true optionSource = "demoOptionSource" } ``` -------------------------------- ### Groovy Report Rendering with Handlebars Source: https://developer.morpheusdata.com/docs/index Renders a report using a Handlebars template. It prepares a ViewModel containing the report results organized by section and then uses the `getRenderer()` to render the specified template (`hbs/instanceReport`). ```Groovy @Override HTMLResponse renderTemplate(ReportResult reportResult, Map> reportRowsBySection) { ViewModel model = new ViewModel() model.object = reportRowsBySection getRenderer().renderTemplate("hbs/instanceReport", model) } ``` -------------------------------- ### Handlebars Template for Catalog Item Layout Source: https://developer.morpheusdata.com/docs/index This Handlebars template defines the structure for rendering a catalog item's details page. It includes external JavaScript and CSS files using the 'asset' helper and dynamically displays item information like name, description, and wiki content. It also includes conditional rendering for elements like the order form and wiki content. ```html

{{name}}

{{description}}
{{#hasWiki}}
{{wiki}}
{{/hasWiki}}
{{#orderForm}}
{{/orderForm}}
``` -------------------------------- ### Using Morpheus Credentials - Credential Type OptionType Source: https://developer.morpheusdata.com/docs/index Configure an `OptionType` to allow users to select a credential type from a predefined list. This involves setting `inputType` to `CREDENTIAL`, `fieldContext` to `credential`, `fieldName` to `type`, and `optionSource` to `credentials`. The `config` property specifies the allowed credential types. ```json { "fieldName": "credentialType", "label": "Credential Type", "inputType": "CREDENTIAL", "fieldContext": "credential", "optionSource": "credentials", "config": "{\"credentialTypes\":[\"username-password\", \"access-key-secret\"]}" } ``` -------------------------------- ### Add Custom Tab to Backup Provider View in Java Source: https://developer.morpheusdata.com/docs/index This Java code extends AbstractBackupIntegrationTabProvider to add a custom tab to the backup provider detail view. The renderTemplate method is overridden to render a specific Handlebars template ('hbs/myTabView'), and the show method determines the visibility of this tab based on the backup provider's type code. ```java class MyBackupTabProvider extends AbstractBackupIntegrationTabProvider { /... @Override HTMLResponse renderTemplate(BackupProvider backupProvider) { ViewModel model = new ViewModel<>() model.object = backupProvider return getRenderer().renderTemplate("hbs/myTabView", model) } @Override Boolean show(BackupProvider backupProvider, User user, Account account) { // only show this tab for providers that match this plugin's backup provider return backupProvider.type.code == MyBackupProvider.PROVIDER_CODE } } ```