use of io.kubernetes.client.ApiException in project weblogic-kubernetes-operator by oracle.
the class Main method begin.
private static void begin() {
// read the operator configuration
String namespace = System.getenv("OPERATOR_NAMESPACE");
if (namespace == null) {
namespace = "default";
}
Collection<String> targetNamespaces = getTargetNamespaces(namespace);
String serviceAccountName = tuningAndConfig.get("serviceaccount");
if (serviceAccountName == null) {
serviceAccountName = "default";
}
principal = "system:serviceaccount:" + namespace + ":" + serviceAccountName;
LOGGER.info(MessageKeys.OP_CONFIG_NAMESPACE, namespace);
StringBuilder tns = new StringBuilder();
Iterator<String> it = targetNamespaces.iterator();
while (it.hasNext()) {
tns.append(it.next());
if (it.hasNext()) {
tns.append(", ");
}
}
LOGGER.info(MessageKeys.OP_CONFIG_TARGET_NAMESPACES, tns.toString());
LOGGER.info(MessageKeys.OP_CONFIG_SERVICE_ACCOUNT, serviceAccountName);
try {
// Initialize logging factory with JSON serializer for later logging
// that includes k8s objects
LoggingFactory.setJSON(new JSON());
// start the REST server
startRestServer(principal, targetNamespaces);
// create the Custom Resource Definitions if they are not already there
CRDHelper.checkAndCreateCustomResourceDefinition();
try {
HealthCheckHelper healthCheck = new HealthCheckHelper(namespace, targetNamespaces);
version = healthCheck.performK8sVersionCheck();
healthCheck.performNonSecurityChecks();
healthCheck.performSecurityChecks(serviceAccountName);
} catch (ApiException e) {
LOGGER.warning(MessageKeys.EXCEPTION, e);
}
// check for any existing resources and add the watches on them
// this would happen when the Domain was running BEFORE the Operator starts up
LOGGER.info(MessageKeys.LISTING_DOMAINS);
for (String ns : targetNamespaces) {
initialized.put(ns, Boolean.TRUE);
Step domainList = callBuilderFactory.create().listDomainAsync(ns, new ResponseStep<DomainList>(null) {
@Override
public NextAction onFailure(Packet packet, ApiException e, int statusCode, Map<String, List<String>> responseHeaders) {
if (statusCode == CallBuilder.NOT_FOUND) {
return onSuccess(packet, null, statusCode, responseHeaders);
}
return super.onFailure(packet, e, statusCode, responseHeaders);
}
@Override
public NextAction onSuccess(Packet packet, DomainList result, int statusCode, Map<String, List<String>> responseHeaders) {
if (result != null) {
for (Domain dom : result.getItems()) {
doCheckAndCreateDomainPresence(dom);
}
}
// main logic now happens in the watch handlers
domainWatchers.put(ns, createDomainWatcher(ns, result != null ? result.getMetadata().getResourceVersion() : ""));
return doNext(packet);
}
});
Step initialize = ConfigMapHelper.createScriptConfigMapStep(ns, new ConfigMapAfterStep(ns, callBuilderFactory.create().with($ -> {
$.labelSelector = LabelConstants.DOMAINUID_LABEL + "," + LabelConstants.CREATEDBYOPERATOR_LABEL;
}).listPodAsync(ns, new ResponseStep<V1PodList>(callBuilderFactory.create().with($ -> {
$.labelSelector = LabelConstants.DOMAINUID_LABEL + "," + LabelConstants.CREATEDBYOPERATOR_LABEL;
}).listServiceAsync(ns, new ResponseStep<V1ServiceList>(callBuilderFactory.create().with($ -> {
$.labelSelector = LabelConstants.DOMAINUID_LABEL + "," + LabelConstants.CREATEDBYOPERATOR_LABEL;
}).listIngressAsync(ns, new ResponseStep<V1beta1IngressList>(domainList) {
@Override
public NextAction onFailure(Packet packet, ApiException e, int statusCode, Map<String, List<String>> responseHeaders) {
if (statusCode == CallBuilder.NOT_FOUND) {
return onSuccess(packet, null, statusCode, responseHeaders);
}
return super.onFailure(packet, e, statusCode, responseHeaders);
}
@Override
public NextAction onSuccess(Packet packet, V1beta1IngressList result, int statusCode, Map<String, List<String>> responseHeaders) {
if (result != null) {
for (V1beta1Ingress ingress : result.getItems()) {
String domainUID = IngressWatcher.getIngressDomainUID(ingress);
String clusterName = IngressWatcher.getIngressClusterName(ingress);
if (domainUID != null && clusterName != null) {
DomainPresenceInfo created = new DomainPresenceInfo(ns);
DomainPresenceInfo info = domains.putIfAbsent(domainUID, created);
if (info == null) {
info = created;
}
info.getIngresses().put(clusterName, ingress);
}
}
}
ingressWatchers.put(ns, createIngressWatcher(ns, result != null ? result.getMetadata().getResourceVersion() : ""));
return doNext(packet);
}
})) {
@Override
public NextAction onFailure(Packet packet, ApiException e, int statusCode, Map<String, List<String>> responseHeaders) {
if (statusCode == CallBuilder.NOT_FOUND) {
return onSuccess(packet, null, statusCode, responseHeaders);
}
return super.onFailure(packet, e, statusCode, responseHeaders);
}
@Override
public NextAction onSuccess(Packet packet, V1ServiceList result, int statusCode, Map<String, List<String>> responseHeaders) {
if (result != null) {
for (V1Service service : result.getItems()) {
String domainUID = ServiceWatcher.getServiceDomainUID(service);
String serverName = ServiceWatcher.getServiceServerName(service);
String channelName = ServiceWatcher.getServiceChannelName(service);
if (domainUID != null && serverName != null) {
DomainPresenceInfo created = new DomainPresenceInfo(ns);
DomainPresenceInfo info = domains.putIfAbsent(domainUID, created);
if (info == null) {
info = created;
}
ServerKubernetesObjects csko = new ServerKubernetesObjects();
ServerKubernetesObjects current = info.getServers().putIfAbsent(serverName, csko);
ServerKubernetesObjects sko = current != null ? current : csko;
if (channelName != null) {
sko.getChannels().put(channelName, service);
} else {
sko.getService().set(service);
}
}
}
}
serviceWatchers.put(ns, createServiceWatcher(ns, result != null ? result.getMetadata().getResourceVersion() : ""));
return doNext(packet);
}
})) {
@Override
public NextAction onFailure(Packet packet, ApiException e, int statusCode, Map<String, List<String>> responseHeaders) {
if (statusCode == CallBuilder.NOT_FOUND) {
return onSuccess(packet, null, statusCode, responseHeaders);
}
return super.onFailure(packet, e, statusCode, responseHeaders);
}
@Override
public NextAction onSuccess(Packet packet, V1PodList result, int statusCode, Map<String, List<String>> responseHeaders) {
if (result != null) {
for (V1Pod pod : result.getItems()) {
String domainUID = PodWatcher.getPodDomainUID(pod);
String serverName = PodWatcher.getPodServerName(pod);
if (domainUID != null && serverName != null) {
DomainPresenceInfo created = new DomainPresenceInfo(ns);
DomainPresenceInfo info = domains.putIfAbsent(domainUID, created);
if (info == null) {
info = created;
}
ServerKubernetesObjects csko = new ServerKubernetesObjects();
ServerKubernetesObjects current = info.getServers().putIfAbsent(serverName, csko);
ServerKubernetesObjects sko = current != null ? current : csko;
sko.getPod().set(pod);
}
}
}
podWatchers.put(ns, createPodWatcher(ns, result != null ? result.getMetadata().getResourceVersion() : ""));
return doNext(packet);
}
})));
engine.createFiber().start(initialize, new Packet(), new CompletionCallback() {
@Override
public void onCompletion(Packet packet) {
// no-op
}
@Override
public void onThrowable(Packet packet, Throwable throwable) {
LOGGER.severe(MessageKeys.EXCEPTION, throwable);
}
});
}
// delete stranded resources
for (Map.Entry<String, DomainPresenceInfo> entry : domains.entrySet()) {
String domainUID = entry.getKey();
DomainPresenceInfo info = entry.getValue();
if (info != null) {
if (info.getDomain() == null) {
// no domain resource
deleteDomainPresence(info.getNamespace(), domainUID);
}
}
}
} catch (Throwable e) {
LOGGER.warning(MessageKeys.EXCEPTION, e);
} finally {
LOGGER.info(MessageKeys.OPERATOR_SHUTTING_DOWN);
}
}
use of io.kubernetes.client.ApiException in project weblogic-kubernetes-operator by oracle.
the class HealthCheckHelper method performK8sVersionCheck.
/**
* Verify the k8s version.
*
* @return Major and minor version information
* @throws ApiException exception for k8s API
*/
public KubernetesVersion performK8sVersionCheck() throws ApiException {
// k8s version must be 1.7.5 or greater
LOGGER.info(MessageKeys.VERIFY_K8S_MIN_VERSION);
boolean k8sMinVersion = true;
VersionInfo info = null;
int major = 0;
int minor = 0;
try {
CallBuilderFactory factory = ContainerResolver.getInstance().getContainer().getSPI(CallBuilderFactory.class);
info = factory.create().readVersionCode();
String gitVersion = info.getGitVersion();
major = Integer.parseInt(info.getMajor());
if (major < 1) {
k8sMinVersion = false;
} else if (major == 1) {
// The Minor version can be also 8+
String minor_string = info.getMinor();
// If not it will remove the last part of the string in order to have just a number
while (!minor_string.chars().allMatch(Character::isDigit)) {
minor_string = minor_string.substring(0, minor_string.length() - 1);
}
minor = Integer.parseInt(minor_string);
if (minor < 7) {
k8sMinVersion = false;
} else if (minor == 7) {
// git version is of the form v1.7.5
// Check the 3rd part of the version.
String[] splitVersion = gitVersion.split("\\.");
// issue-36: gitVersion can be not just "v1.7.9" but also values like "v1.7.9+coreos.0"
splitVersion = splitVersion[2].split("\\+");
if (Integer.parseInt(splitVersion[0]) < 5) {
k8sMinVersion = false;
}
}
}
// Minimum k8s version not satisfied.
if (!k8sMinVersion) {
logHealthCheckEvent(MessageKeys.K8S_MIN_VERSION_CHECK_FAILED, MINIMUM_K8S_VERSION, gitVersion);
} else {
LOGGER.info(MessageKeys.K8S_VERSION_CHECK, gitVersion);
}
} catch (ApiException ae) {
LOGGER.warning(MessageKeys.K8S_VERSION_CHECK_FAILURE, ae);
}
return new KubernetesVersion(major, minor);
}
use of io.kubernetes.client.ApiException in project weblogic-kubernetes-operator by oracle.
the class AuthenticationProxy method check.
/**
* Check if the specified access token can be authenticated
*
* @param principal The user, group or service account.
* @param token The access token that identifies the user.
* @return V1TokenReviewStatus containing either info about the authenticated user or
* an error explaining why the user couldn't be authenticated
*/
public V1TokenReviewStatus check(String principal, String token) {
// Don't expose the token since it's a credential
LOGGER.entering(principal);
V1TokenReview result = null;
try {
boolean allowed = authorizationProxy.check(principal, AuthorizationProxy.Operation.create, AuthorizationProxy.Resource.tokenreviews, null, AuthorizationProxy.Scope.cluster, null);
if (allowed) {
CallBuilderFactory factory = ContainerResolver.getInstance().getContainer().getSPI(CallBuilderFactory.class);
result = factory.create().createTokenReview(prepareTokenReview(token));
} else {
LOGGER.info(MessageKeys.CANNOT_CREATE_TOKEN_REVIEW);
}
} catch (ApiException e) {
LOGGER.severe(MessageKeys.APIEXCEPTION_FROM_TOKEN_REVIEW, e);
LOGGER.exiting(null);
return null;
}
LOGGER.info("Returned TokenReview", result);
V1TokenReviewStatus status = result != null ? result.getStatus() : null;
LOGGER.exiting(status);
return status;
}
use of io.kubernetes.client.ApiException in project weblogic-kubernetes-operator by oracle.
the class LoggingFormatter method format.
@Override
public String format(LogRecord record) {
String sourceClassName = "";
String sourceMethodName = "";
if (record.getSourceClassName() != null) {
sourceClassName = record.getSourceClassName();
if (record.getSourceMethodName() != null) {
sourceMethodName = record.getSourceMethodName();
}
} else {
sourceClassName = record.getLoggerName();
}
// the toString() format for the model classes is inappropriate for our logs
// so, replace with the JSON serialization
JSON j = LoggingFactory.getJSON();
if (j != null) {
Object[] parameters = record.getParameters();
if (parameters != null) {
for (int i = 0; i < parameters.length; i++) {
Object pi = parameters[i];
if (pi != null) {
if (pi.getClass().getAnnotation(ApiModel.class) != null || pi.getClass().getName().startsWith("oracle.kubernetes.weblogic.domain.")) {
// this is a model object
parameters[i] = j.serialize(pi);
}
}
}
}
}
String message = formatMessage(record);
String code = "";
Map<String, List<String>> headers = PLACEHOLDER;
String body = "";
String throwable = "";
if (record.getThrown() != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println();
record.getThrown().printStackTrace(pw);
pw.close();
throwable = sw.toString();
if (record.getThrown() instanceof ApiException) {
ApiException ae = (ApiException) record.getThrown();
code = String.valueOf(ae.getCode());
if (ae.getResponseHeaders() != null) {
headers = ae.getResponseHeaders();
}
String rb = ae.getResponseBody();
if (rb != null)
body = rb;
}
}
String level = record.getLevel().getLocalizedName();
Map<String, Object> map = new LinkedHashMap<>();
long rawTime = record.getMillis();
final String dateString = dateFormat.format(new Date(rawTime));
long thread = Thread.currentThread().getId();
map.put(TIMESTAMP, dateString);
map.put(THREAD, thread);
map.put(LOG_LEVEL, level);
map.put(SOURCE_CLASS, sourceClassName);
map.put(SOURCE_METHOD, sourceMethodName);
map.put(TIME_IN_MILLIS, rawTime);
// if message or throwable have new lines in them, we need to replace with JSON newline control character \n
map.put(MESSAGE, message != null ? message.replaceAll("\n", "\\\n") : "");
map.put(EXCEPTION, throwable.replaceAll("\n", "\\\n"));
map.put(RESPONSE_CODE, code);
map.put(RESPONSE_HEADERS, headers);
map.put(RESPONSE_BODY, body.replaceAll("\n", "\\\n"));
String json = "";
try {
ObjectMapper mapper = new ObjectMapper();
json = mapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
String tmp = "{\"@timestamp\":%1$s,\"level\":%2$s, \"class\":%3$s, \"method\":\"format\", \"timeInMillis\":%4$d, \"@message\":\"Exception while preparing json object\",\"exception\":%5$s}\n";
return String.format(tmp, dateString, level, LoggingFormatter.class.getName(), rawTime, e.getLocalizedMessage());
}
return json + "\n";
}
use of io.kubernetes.client.ApiException in project weblogic-kubernetes-operator by oracle.
the class RestBackendImpl method updateReplicasForDomain.
private void updateReplicasForDomain(String namespace, Domain domain, String cluster, int managedServerCount) {
// Capacity of configured cluster is valid for scaling
// Set replicas value on corresponding ClusterStartup (if defined)
// or on the Domain level replicas value for cluster not defined in a ClusterStartup
String domainUID = domain.getSpec().getDomainUID();
boolean domainModified = false;
ClusterStartup clusterStartup = getClusterStartup(domain, cluster);
int currentReplicasCount = clusterStartup != null ? clusterStartup.getReplicas() : domain.getSpec().getReplicas();
if (managedServerCount != currentReplicasCount) {
if (clusterStartup != null) {
// set replica value on corresponding ClusterStartup
clusterStartup.setReplicas(managedServerCount);
domainModified = true;
} else if (StartupControlConstants.AUTO_STARTUPCONTROL.equals(domain.getSpec().getStartupControl())) {
// set replica on Domain for cluster not defined in ClusterStartup
domain.getSpec().setReplicas(managedServerCount);
domainModified = true;
} else {
// so scaling will not occur since Domain.spec.Replicas property will be ignored.
throw createWebApplicationException(Status.BAD_REQUEST, MessageKeys.SCALING_AUTO_CONTROL_AUTO, cluster);
}
}
if (domainModified) {
try {
CallBuilderFactory factory = ContainerResolver.getInstance().getContainer().getSPI(CallBuilderFactory.class);
// Write out the Domain with updated replica values
// TODO: Can we patch instead of replace?
factory.create().replaceDomain(domainUID, namespace, domain);
} catch (ApiException e) {
LOGGER.finer("Unexpected exception when updating Domain " + domainUID + " in namespace " + namespace, e);
throw new WebApplicationException(e.getMessage());
}
}
}
Aggregations