Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add read only mode of operation to ZTS #439

Merged
merged 2 commits into from
Apr 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public final class ZTSConsts {
public static final String ZTS_PROP_CHANGE_LOG_STORE_DIR = "athenz.zts.change_log_store_dir";
public static final String ZTS_PROP_NOAUTH_URI_LIST = "athenz.zts.no_auth_uri_list";
public static final String ZTS_PROP_ROLE_COMPLETE_FLAG = "athenz.zts.role_complete_flag";

public static final String ZTS_PROP_READ_ONLY_MODE = "athenz.zts.read_only_mode";

public static final String ZTS_PROP_CERT_REFRESH_IP_FNAME = "athenz.zts.cert_refresh_ip_fname";
public static final String ZTS_PROP_INSTANCE_CERT_IP_FNAME = "athenz.zts.instance_cert_ip_fname";

Expand Down
48 changes: 43 additions & 5 deletions servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ public class ZTSImpl implements KeyStore, ZTSHandler {
protected boolean statusCertSigner = false;
protected Status successServerStatus = null;
protected boolean includeRoleCompleteFlag = true;

protected boolean readOnlyMode = false;

private static final String TYPE_DOMAIN_NAME = "DomainName";
private static final String TYPE_SIMPLE_NAME = "SimpleName";
private static final String TYPE_ENTITY_NAME = "EntityName";
Expand Down Expand Up @@ -384,6 +385,11 @@ void loadConfigurationSettings() {

includeRoleCompleteFlag = Boolean.parseBoolean(
System.getProperty(ZTSConsts.ZTS_PROP_ROLE_COMPLETE_FLAG, "true"));

// check if we need to run in maintenance read only mode

readOnlyMode = Boolean.parseBoolean(
System.getProperty(ZTSConsts.ZTS_PROP_READ_ONLY_MODE, "false"));
}

static String getServerHostName() {
Expand Down Expand Up @@ -1399,6 +1405,11 @@ public RoleToken postRoleCertificateRequest(ResourceContext ctx, String domainNa
metric.increment(HTTP_POST);
logPrincipal(ctx);

if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
validate(domainName, TYPE_DOMAIN_NAME, caller);
validate(roleName, TYPE_ENTITY_NAME, caller);
Expand Down Expand Up @@ -1670,6 +1681,11 @@ public void postInstanceRegisterInformation(ResourceContext ctx, InstanceRegiste
final String callerTiming = "postinstanceregisterinformation_timing";
metric.increment(HTTP_POST);

if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
validate(info, TYPE_INSTANCE_REGISTER_INFO, caller);

Expand Down Expand Up @@ -1888,6 +1904,11 @@ public InstanceIdentity postInstanceRefreshInformation(ResourceContext ctx, Stri
metric.increment(HTTP_POST);
logPrincipal(ctx);

if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
validate(provider, TYPE_SERVICE_NAME, caller);
validate(domain, TYPE_DOMAIN_NAME, caller);
Expand Down Expand Up @@ -2229,6 +2250,11 @@ public InstanceIdentity deleteInstanceIdentity(ResourceContext ctx, String provi
metric.increment(HTTP_POST);
logPrincipal(ctx);

if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
validate(provider, TYPE_SERVICE_NAME, caller);
validate(domain, TYPE_DOMAIN_NAME, caller);
Expand Down Expand Up @@ -2277,6 +2303,11 @@ public Identity postInstanceRefreshRequest(ResourceContext ctx, String domain,
metric.increment(HTTP_POST);
logPrincipal(ctx);

if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
validate(domain, TYPE_DOMAIN_NAME, caller);
validate(service, TYPE_SIMPLE_NAME, caller);
Expand Down Expand Up @@ -2449,8 +2480,9 @@ public Identity postOSTKInstanceInformation(ResourceContext ctx, OSTKInstanceInf
metric.increment(HTTP_POST);
logPrincipal(ctx);

if (LOGGER.isDebugEnabled()) {
LOGGER.debug("postOSTKInstanceInformation: " + info);
if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
Expand Down Expand Up @@ -2565,8 +2597,9 @@ public Identity postOSTKInstanceRefreshRequest(ResourceContext ctx, String domai
metric.increment(HTTP_POST);
logPrincipal(ctx);

if (LOGGER.isDebugEnabled()) {
LOGGER.debug("postOSTKInstanceRefreshRequest: " + req);
if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
Expand Down Expand Up @@ -2854,6 +2887,11 @@ public DomainMetrics postDomainMetrics(ResourceContext ctx, String domainName,
metric.increment(HTTP_POST);
logPrincipal(ctx);

if (readOnlyMode) {
throw requestError("Server in Maintenance Read-Only mode. Please try your request later",
caller, ZTSConsts.ZTS_UNKNOWN_DOMAIN);
}

validateRequest(ctx.request(), caller);
validate(domainName, TYPE_DOMAIN_NAME, caller);
validate(domainMetrics, TYPE_DOMAIN_METRICS, caller);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ public InstanceCertManager(final PrivateKeyStore keyStore, final CertSigner cert
}
}

public void shutdown() {
if (scheduledExecutor != null) {
scheduledExecutor.shutdownNow();
}
}

boolean loadAllowedIPAddresses(List<IPBlock> ipBlocks, final String propName) {

// get the configured path for the list of ip addresses
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public HttpCertSigner() {
httpClient = new HttpClient(ZTSUtils.createSSLContextObject(new String[] {"TLSv1.2"}, privateKeyStore));
httpClient.setFollowRedirects(false);
httpClient.setConnectTimeout(connectTimeout);
httpClient.setStopTimeout(TimeUnit.MILLISECONDS.convert(requestTimeout, TimeUnit.SECONDS));
try {
httpClient.start();
} catch (Exception ex) {
Expand All @@ -95,7 +96,18 @@ public HttpCertSigner() {
x509CertUri = serverBaseUri + "/x509";
sshCertUri = serverBaseUri + "/ssh";
}


@Override
public void close() {
try {
if (httpClient != null) {
httpClient.stop();
}
} catch (Exception ex) {
LOGGER.error("close: unable to stop httpClient", ex);
}
}

@Override
public int getMaxCertExpiryTimeMins() {
return maxCertExpiryTimeMins;
Expand All @@ -114,17 +126,6 @@ private PrivateKeyStore loadServicePrivateKey() {
}
return pkeyFactory.create();
}

@Override
public void close() {
try {
if (httpClient != null) {
httpClient.stop();
}
} catch (Exception ex) {
LOGGER.error("close: unable to stop httpClient", ex);
}
}

ContentResponse processX509CertRequest(final String csr, final List<Integer> extKeyUsage,
int expiryTime, int retryCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public CloudStore(CertSigner certSigner) {

httpClient = new HttpClient();
httpClient.setFollowRedirects(false);
httpClient.setStopTimeout(1000);
try {
httpClient.start();
} catch (Exception ex) {
Expand Down Expand Up @@ -125,25 +126,28 @@ public CloudStore(CertSigner certSigner) {
initializeAwsSupport();
}

void close() {
if (httpClient != null) {
try {
httpClient.stop();
} catch (Exception e) {
}
public void close() {
if (scheduledThreadPool != null) {
scheduledThreadPool.shutdownNow();
}
stopHttpClient();
}

public void setHttpClient(HttpClient client) {
if (httpClient != null) {
try {
httpClient.stop();
} catch (Exception e) {
}
}
stopHttpClient();
httpClient = client;
}

void stopHttpClient() {
if (httpClient == null) {
return;
}
try {
httpClient.stop();
} catch (Exception e) {
}
}

public boolean isAwsEnabled() {
return awsEnabled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,9 @@ public CloudStore getCloudStore() {
}

public void setCloudStore(CloudStore cloudStore) {
if (this.cloudStore != null) {
this.cloudStore.close();
}
this.cloudStore = cloudStore;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import com.yahoo.athenz.auth.util.Crypto;
import com.yahoo.athenz.common.utils.SignUtils;
import com.yahoo.athenz.instance.provider.InstanceProvider;
import com.yahoo.athenz.instance.provider.InstanceProviderClient;
import com.yahoo.athenz.zms.DomainData;
import com.yahoo.athenz.zms.Role;
import com.yahoo.athenz.zms.RoleMember;
Expand Down
20 changes: 11 additions & 9 deletions servers/zts/src/test/java/com/yahoo/athenz/zts/ZTSImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public class ZTSImplTest {
PrivateKey privateKey = null;
PublicKey publicKey = null;
AuditLogger auditLogger = null;
CloudStore cloudStore = null;
@Mock CloudStore mockCloudStore;

static final String ZTS_DATA_STORE_PATH = "/tmp/zts_server_unit_tests/zts_root";
Expand Down Expand Up @@ -167,7 +168,7 @@ public class ZTSImplTest {
@Mock HttpServletResponse mockServletResponse;

@BeforeClass
public void setUpClass() throws Exception {
public void setupClass() throws Exception {
MockitoAnnotations.initMocks(this);
Mockito.when(mockServletRequest.getRemoteAddr()).thenReturn(MOCKCLIENTADDR);

Expand Down Expand Up @@ -216,7 +217,7 @@ public void setup() {
ChangeLogStore structStore = new MockZMSFileChangeLogStore("/tmp/zts_server_unit_tests/zts_root",
privateKey, "0");

CloudStore cloudStore = new CloudStore(null);
cloudStore = new CloudStore(null);
cloudStore.setHttpClient(null);

System.setProperty(ZTSConsts.ZTS_PROP_SELF_SIGNER_PRIVATE_KEY_FNAME,
Expand All @@ -233,6 +234,14 @@ public void setup() {
authorizer = new ZTSAuthorizer(store);
}

@AfterMethod
public void shutdown() {
cloudStore.close();
ZMSFileChangeLogStore.deleteDirectory(new File(ZTS_DATA_STORE_PATH));
System.clearProperty(ZTSConsts.ZTS_PROP_ROLE_TOKEN_MAX_TIMEOUT);
System.clearProperty(ZTSConsts.ZTS_PROP_ROLE_TOKEN_DEFAULT_TIMEOUT);
}

static class ZtsMetricTester extends com.yahoo.athenz.common.metrics.impl.NoOpMetric {
Map<String, Integer> metrixMap = new HashMap<>();

Expand Down Expand Up @@ -359,13 +368,6 @@ private Metric getMetric(){
return metric;
}

@AfterMethod
public void shutdown() {
ZMSFileChangeLogStore.deleteDirectory(new File(ZTS_DATA_STORE_PATH));
System.clearProperty(ZTSConsts.ZTS_PROP_ROLE_TOKEN_MAX_TIMEOUT);
System.clearProperty(ZTSConsts.ZTS_PROP_ROLE_TOKEN_DEFAULT_TIMEOUT);
}

private String generateRoleName(String domain, String role) {
StringBuilder str = new StringBuilder(256);
str.append(domain);
Expand Down
Loading