Building Morpheus Plugins: A Practical Workflow for Engineers
These articles are AI-generated summaries. Please check the original sources for full details.
Building a Morpheus Plugin A Practical Walkthrough
The Morpheus hybrid cloud management platform provides an SDK with over fifty provider types for extending cloud integrations and UI components. This guide demonstrates building an MFA enforcement utility to close a security gap where appliance-wide 2FA is not natively supported.
Why This Matters
While the SDK is documented in pieces, the practical transition from idea to a running shadow JAR on an appliance is often undocumented. Technical reality requires managing Gradle 7.x/JDK 11 compatibility while targeting Java 8, and failing to account for Content-Security-Policy (CSP) through nonce helpers results in silent UI failures that are difficult to debug.
Key Insights
- The SDK exposes 50+ provider types like CloudProvider and GlobalUIComponentProvider to hook into specific lifecycle moments.
- Local clones of morpheus-plugin-core and morpheus-openapi are essential for high-speed grepping of 600+ endpoint files and 650+ schemas.
- The shadow plugin must be updated to com.github.johnrengelman.shadow version 7.1.2 for compatibility with Gradle 7.x and JDK 11.
- Using compileOnly for the plugin API and Groovy is mandatory to prevent NoSuchMethodError at runtime caused by classpath conflicts.
- GlobalUIComponentProvider allows HTML injection via Handlebars but requires the {{nonce}} helper to bypass Morpheus strict security headers.
Working Examples
Setting up reference material for local grepping.
git clone --depth 1 --branch v1.2.x https://github.com/HewlettPackard/morpheus-plugin-core.git
git clone --depth 1 https://github.com/HewlettPackard/morpheus-docs.git
git clone --depth 1 https://github.com/HewlettPackard/morpheus-openapi.git
Minimal build.gradle configuration for a Morpheus shadow JAR.
plugins {
id 'java'
id 'groovy'
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
group = 'com.morpheusdata'
version = '1.0.0'
sourceCompatibility = '11'
targetCompatibility = '11'
repositories { mavenCentral() }
dependencies {
compileOnly 'com.morpheusdata:morpheus-plugin-api:0.15.4'
compileOnly 'org.codehaus.groovy:groovy-all:3.0.11'
compileOnly 'io.reactivex.rxjava3:rxjava:3.1.5'
compileOnly 'org.slf4j:slf4j-api:1.7.26'
}
shadowJar {
manifest {
attributes(
'Plugin-Class' : 'com.example.myplugin.MyPlugin',
'Plugin-Version': archiveVersion.get()
)
}
}
The Plugin class serves as the entry point for registration.
class MfaEnforcerPlugin extends Plugin {
@Override String getCode() { 'morpheus-mfa-enforcer-plugin' }
@Override void initialize() {
setName("MFA Enforcer")
def provider = new MfaEnforcerProvider(this, morpheus)
pluginProviders.put(provider.code, provider)
}
}
Handlebars template using the nonce helper to satisfy CSP requirements.
<div id="mfa-shield" role="dialog" aria-modal="true">
<style nonce="{{nonce}}">
#mfa-shield {
position: fixed; inset: 0; z-index: 2147483647;
background: rgba(15, 23, 42, 0.75);
display: flex; align-items: center; justify-content: center;
}
</style>
<div class="card">
<h1>Two-Factor Authentication Required</h1>
<a class="cta" href="{{userSettingsUrl}}" target="_top">
Go to User Settings -> Enable 2FA
</a>
</div>
</div>
Practical Applications
- Use Case: Implementing appliance-wide MFA enforcement using GlobalUIComponentProvider to intercept users post-login. Pitfall: Performing uncached database lookups on every page render, which creates latency and InnoDB lock contention.
- Use Case: Adding custom detail tabs via InstanceTabProvider or AppTabProvider. Pitfall: Implementing bare interfaces instead of extending AbstractProvider, which leads to missing Handlebars helpers and classpath prefix errors.
- Use Case: Hardening security via password complexity rules or IP-based access restrictions. Pitfall: Relying on browser session cookies for internal API calls, which require OAuth2 bearer tokens for /api/* endpoints.
References:
Continue reading
Next article
Automating Accessibility with the CSS contrast-color() Function
Related Content
Automating Engineering Standups: Building a Daily Digest with Swrly
Automate engineering standups using Swrly to aggregate 24 hours of GitHub and Linear activity into Slack via a 5-node cron-triggered workflow.
Building SwiftDeploy: A Declarative Infrastructure CLI with Observability and Policy Enforcement
SwiftDeploy automates web application deployments using a single manifest file, integrating OPA for policy enforcement and Prometheus metrics.
Building ClauseGuard: A 5-Agent AI Pipeline for Legal Contract Risk Analysis
ClauseGuard automates legal contract analysis using a 5-agent pipeline and Qwen 2.5 on AMD hardware to detect critical risks across twelve clause types.