Change agent.sh to work with K8s

Issue-ID: AAF-667
Change-Id: Iad69da5637a545555e3de7fff8ca8f45aa06a13c
Signed-off-by: Instrumental <jonathan.gathman@att.com>
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java
index 3d74216..7920e48 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java
@@ -33,6 +33,7 @@
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.GregorianCalendar;
 import java.util.HashSet;
 import java.util.List;
@@ -51,8 +52,8 @@
 import org.onap.aaf.auth.org.Organization.Identity;
 import org.onap.aaf.auth.org.OrganizationException;
 import org.onap.aaf.auth.org.OrganizationFactory;
-import org.onap.aaf.cadi.PropAccess;
 import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.PropAccess;
 import org.onap.aaf.cadi.config.Config;
 import org.onap.aaf.misc.env.APIException;
 import org.onap.aaf.misc.env.Env;
@@ -77,6 +78,7 @@
     protected static AuthzEnv env;
     protected static Session session;
     protected static Set<String> specialNames;
+    protected static List<String> specialDomains;
     protected static boolean dryRun; 
     protected static String batchEnv;
 
@@ -131,14 +133,18 @@
 
         // Special names to allow behaviors beyond normal rules
         specialNames = new HashSet<>();
+        specialDomains = new ArrayList<>();
         String names = env.getProperty( "SPECIAL_NAMES" );
         if ( names != null )
         {
             env.info().log("Loading SPECIAL_NAMES");
-            for (String s :names.split(",") )
-            {
+            for (String s :names.split(",") ) {
                 env.info().log("\tspecial: " + s );
-                specialNames.add( s.trim() );
+                if(s.indexOf('@')>0) {
+                	specialNames.add( s.trim() );
+                } else {
+                	specialDomains.add(s.trim());
+                }
             }
         }
     }
@@ -156,13 +162,23 @@
     }
     
     public boolean isSpecial(String user) {
+    	if(user==null) {
+    		return false;
+    	}
         if (specialNames != null && specialNames.contains(user)) {
             env.info().log("specialName: " + user);
-
             return (true);
         } else {
-            return (false);
+        	if(specialDomains!=null) {
+	        	for(String sd : specialDomains) {
+	        		if(user.endsWith(sd)) {
+	        			env.info().log("specialDomain: " + user + " matches " + sd);
+	        			return (true);
+	        		}
+	        	}
+        	}
         }
+        return (false);
     }
 
 
@@ -459,16 +475,16 @@
                     Class<?> cls;
                     String classifier = "";
                     try {
-                        cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.update." + toolName);
+                        cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.batch.update." + toolName);
                         classifier = "Update:";
                     } catch (ClassNotFoundException e) {
                         try {
-                            cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.reports." + toolName);
+                            cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.batch.reports." + toolName);
                             classifier = "Report:";
                         } catch (ClassNotFoundException e2) {
                             try {
                                 cls = ClassLoader.getSystemClassLoader()
-                                        .loadClass("org.onap.aaf.auth.temp." + toolName);
+                                        .loadClass("org.onap.aaf.auth.batch.temp." + toolName);
                                 classifier = "Temp Utility:";
                             } catch (ClassNotFoundException e3) {
                                 cls = null;
@@ -476,7 +492,7 @@
                         }
                     }
                     if (cls != null) {
-                        Constructor<?> cnst = cls.getConstructor(new Class[] { AuthzTrans.class });
+                        Constructor<?> cnst = cls.getConstructor(AuthzTrans.class);
                         batch = (Batch) cnst.newInstance(trans);
                         env.info().log("Begin", classifier, toolName);
                     }
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/CacheTouch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/CacheTouch.java
index a4f4dcf..94df581 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/CacheTouch.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/CacheTouch.java
@@ -45,6 +45,7 @@
             trans.info().printf("Would mark %s cache in DB for clearing: %s",table, text);
             return Result.ok();
         } else {
+        	
             Result<Void> rv = q.clearCache(trans, table);
             trans.info().printf("Set DB Cache %s for clearing: %s",table, text);
             return rv;
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/CQLBatch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/CQLBatch.java
index 5df5dcd..c65026a 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/CQLBatch.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/CQLBatch.java
@@ -66,6 +66,17 @@
 		} else {
 			return execute();
 		}
-		
+	}
+	
+	public void touch(String table, int begin, int end, boolean dryRun) {
+		StringBuilder sb = begin();
+		for(int i=begin;i<end;++i) {
+			sb.append("UPDATE cache SET touched=dateof(now()) WHERE name='");
+			sb.append(table);
+			sb.append("' AND seg=");
+			sb.append(i);
+			sb.append(";\n");
+		}
+		execute(dryRun);
 	}
 }
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java
index 979cdf0..b58506e 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java
@@ -322,4 +322,14 @@
         return id.equals(obj);
     }
 
+
+	public static String histSubject(List<String> row) {
+		return row.get(1);
+	}
+
+
+	public static String histMemo(String fmt, String orgName, List<String> row) {
+		return String.format(fmt, row.get(1),orgName,row.get(4));
+	}
+
 }
\ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/UserRole.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/UserRole.java
index 30069d6..ecf66fe 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/UserRole.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/UserRole.java
@@ -321,6 +321,12 @@
     	sb.append(row.get(3));
     	sb.append("';\n");
     }
-    
 
+	public static String histMemo(String fmt, List<String> row) {
+		return String.format(fmt, row.get(1),row.get(2)+'.'+row.get(3), row.get(4));
+	}
+
+	public static String histSubject(List<String> row) {
+		return row.get(1) + '|' + row.get(2)+'.'+row.get(3);	
+	}
 }
\ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Visitor.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Visitor.java
index a59064e..17f289a 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Visitor.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Visitor.java
@@ -22,4 +22,19 @@
 
 public interface Visitor<T> {
 	void visit(T t);
+	
+	public static class Multi<T> implements Visitor<T> {
+		private final Visitor<T>[] visitors;
+		@SafeVarargs
+		public Multi(Visitor<T> ... vs) {
+			visitors  = vs;
+		}
+		
+		@Override
+		public void visit(T t) {
+			for(Visitor<T> v : visitors) {
+				v.visit(t);
+			}
+		}
+	};
 }
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/X509.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/X509.java
index 8bdcd10..0ffaa8f 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/X509.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/X509.java
@@ -33,6 +33,7 @@
 import org.onap.aaf.misc.env.TimeTaken;
 import org.onap.aaf.misc.env.Trans;
 import org.onap.aaf.misc.env.util.Chrono;
+import org.onap.aaf.misc.env.util.Split;
 
 import com.datastax.driver.core.ResultSet;
 import com.datastax.driver.core.Row;
@@ -59,7 +60,7 @@
 
     private static void load(Trans trans, Session session, String query, Visitor<X509> visitor) {
         trans.info().log( "query: " + query );
-        TimeTaken tt = trans.start("Read Roles", Env.REMOTE);
+        TimeTaken tt = trans.start("Read X509", Env.REMOTE);
        
         ResultSet results;
         try {
@@ -116,4 +117,25 @@
     	sb.append(";\n");
 	}
 
+
+	public static String histSubject(List<String> row) {
+		return row.get(4);
+	}
+
+
+	public static String histMemo(String fmt, List<String> row) {
+		String id="n/a";
+		for(String s : Split.splitTrim(',', row.get(4))) {
+			if(s.startsWith("OU=") && s.indexOf('@')>=0) {
+				int colon = s.indexOf(':');
+				if(colon<0) {
+					colon=s.length();
+				}
+				id=s.substring(3,colon);
+				break;
+			}
+		}
+		return String.format(fmt, "Cert for " + id,"CA " + row.get(1),row.get(3));
+	}
+
 }
\ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Expiring.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Expiring.java
index 1a7db05..e9fd818 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Expiring.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Expiring.java
@@ -80,7 +80,6 @@
             
             // Load Cred.  We don't follow Visitor, because we have to gather up everything into Identity Anyway
             Cred.load(trans, session);
-            UserRole.load(trans, session, UserRole.v2_0_11, new UserRole.DataLoadVisitor());
 
             minOwners=1;
 
@@ -100,7 +99,7 @@
                     	cw.row(INFO,r.name(),Chrono.dateOnlyStamp(expireRange.now),r.reportingLevel());
                     	writerList.put(r.name(),cw);
                     	if("Delete".equals(r.name())) {
-                    		deleteDate = r.getStart();
+                    		deleteDate = r.getEnd();
                     	}
             		}
             	}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java
index a884006..3e1a8df 100644
--- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java
@@ -23,15 +23,23 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 import org.onap.aaf.auth.batch.Batch;
 import org.onap.aaf.auth.batch.BatchPrincipal;
-import org.onap.aaf.auth.batch.actions.CacheTouch;
 import org.onap.aaf.auth.batch.helpers.CQLBatch;
 import org.onap.aaf.auth.batch.helpers.Cred;
 import org.onap.aaf.auth.batch.helpers.UserRole;
 import org.onap.aaf.auth.batch.helpers.X509;
+import org.onap.aaf.auth.dao.CassAccess;
+import org.onap.aaf.auth.dao.cass.CertDAO;
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.dao.cass.HistoryDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.org.OrganizationException;
 import org.onap.aaf.cadi.CadiException;
@@ -44,7 +52,7 @@
 
 public class Remove extends Batch {
     private final AuthzTrans noAvg;
-	private CacheTouch cacheTouch;
+    private HistoryDAO historyDAO;
 	private CQLBatch cqlBatch;
 
     public Remove(AuthzTrans trans) throws APIException, IOException, OrganizationException {
@@ -52,14 +60,14 @@
         trans.info().log("Starting Connection Process");
         
         noAvg = env.newTransNoAvg();
-        noAvg.setUser(new BatchPrincipal("batch:RemoveExpired"));
+        noAvg.setUser(new BatchPrincipal("Remove"));
 
         TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
         try {
-        	cacheTouch = new CacheTouch(trans, cluster, dryRun);
+        	historyDAO = new HistoryDAO(trans, cluster, CassAccess.KEYSPACE);
             TimeTaken tt2 = trans.start("Connect to Cluster", Env.REMOTE);
             try {
-                session = cacheTouch.getSession(trans);
+                session = historyDAO.getSession(trans);
             } finally {
                 tt2.done();
             }
@@ -73,52 +81,123 @@
 
     @Override
     protected void run(AuthzTrans trans) {
-        final int maxBatch = 50;
+        final int maxBatch = 25;
 
         // Create Intermediate Output 
         File logDir = new File(logDir());
         
-        File expired = new File(logDir,"Delete"+Chrono.dateOnlyStamp()+".csv");
-        CSV expiredCSV = new CSV(expired);
-        try {
-        	final StringBuilder sb = cqlBatch.begin();
-            final Holder<Integer> hi = new Holder<Integer>(0);
-			expiredCSV.visit(new CSV.Visitor() {
-				@Override
-				public void visit(List<String> row) throws IOException, CadiException {
-					int i = hi.get();
-					if(i>=maxBatch) {
+        List<File> remove = new ArrayList<>();
+        if(args().length>0) {
+        	for(int i=0;i<args().length;++i) {
+        		remove.add(new File(logDir, args()[i]));
+        	}
+        } else {
+        	remove.add(new File(logDir,"Delete"+Chrono.dateOnlyStamp()+".csv"));
+        }
+        
+        final Holder<Boolean> ur = new Holder<>(false);
+        final Holder<Boolean> cred = new Holder<>(false);
+        final Holder<Boolean> x509 = new Holder<>(false);
+        final Holder<String> memoFmt = new Holder<String>("");
+        final HistoryDAO.Data hdd = new HistoryDAO.Data();
+        final String orgName = trans.org().getName();
+        
+        hdd.action="delete";
+        hdd.reconstruct = ByteBuffer.allocate(0);
+        hdd.user = noAvg.user();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
+        hdd.yr_mon = Integer.parseInt(sdf.format(new Date()));
+        
+        try { 
+	        for(File f : remove) {
+	        	trans.info().log("Processing ",f.getAbsolutePath(),"for Deletions");
+	        	if(f.exists()) {
+			        CSV removeCSV = new CSV(f);
+		        		
+			        try {
+			        	final StringBuilder sb = cqlBatch.begin();
+			            final Holder<Integer> hi = new Holder<Integer>(0);
+						removeCSV.visit(new CSV.Visitor() {
+							@Override
+							public void visit(List<String> row) throws IOException, CadiException {
+								int i = hi.get();
+								if(i>=maxBatch) {
+									cqlBatch.execute(dryRun);
+									hi.set(0);
+									cqlBatch.begin();
+									i=0;
+								}
+								switch(row.get(0)) {
+									case "info":
+										switch(row.get(1)) {
+											case "Delete":
+												memoFmt.set("%s expired from %s on %s");
+												break;
+											case "NotInOrgDelete":
+												memoFmt.set("Identity %s was removed from %s on %s");
+												break;
+										}
+										break;
+									case "ur":
+										if(!ur.get()) {
+											ur.set(true);
+										}
+										hi.set(++i);
+										UserRole.row(sb,row);
+										hdd.target=UserRoleDAO.TABLE; 
+										hdd.subject=UserRole.histSubject(row);
+										hdd.memo=UserRole.histMemo(memoFmt.get(), row);
+										historyDAO.createBatch(sb, hdd);
+										break;
+									case "cred":
+										if(!cred.get()) {
+											cred.set(true);
+										}
+										hi.set(++i);
+										Cred.row(sb,row);
+										hdd.target=CredDAO.TABLE; 
+										hdd.subject=Cred.histSubject(row);
+										hdd.memo=Cred.histMemo(memoFmt.get(), orgName,row);
+										historyDAO.createBatch(sb, hdd);
+								    	break;
+									case "x509":
+										if(!x509.get()) {
+											x509.set(true);
+										}
+										hi.set(++i);
+										X509.row(sb,row);
+										hdd.target=CertDAO.TABLE; 
+										hdd.subject=X509.histSubject(row);
+										hdd.memo=X509.histMemo(memoFmt.get(),row);
+										historyDAO.createBatch(sb, hdd);
+										break;
+								}
+							}
+						});
 						cqlBatch.execute(dryRun);
-						hi.set(0);
-						cqlBatch.begin();
-						i=0;
+					} catch (IOException | CadiException e) {
+						e.printStackTrace();
 					}
-					switch(row.get(0)) {
-						case "ur":
-							hi.set(++i);
-							UserRole.row(sb,row);
-							break;
-						case "cred":
-							hi.set(++i);
-							Cred.row(sb,row);
-					    	break;
-						case "x509":
-							hi.set(++i);
-							X509.row(sb,row);
-							break;
-					}
-				}
-			});
-			cqlBatch.execute(dryRun);
-		} catch (IOException | CadiException e) {
-			e.printStackTrace();
-		}
+	        	} else {
+	        		trans.error().log("File",f.getAbsolutePath(),"does not exist.");
+	        	}
+	        }
+        } finally {
+        	if(ur.get()) {
+        		cqlBatch.touch(UserRoleDAO.TABLE, 0, UserRoleDAO.CACHE_SEG, dryRun);
+        	}
+        	if(cred.get()) {
+        		cqlBatch.touch(CredDAO.TABLE, 0, CredDAO.CACHE_SEG, dryRun);
+        	}
+        	if(x509.get()) {
+        		cqlBatch.touch(CertDAO.TABLE, 0, CertDAO.CACHE_SEG, dryRun);
+        	}
+        }
     }
     
     @Override
     protected void _close(AuthzTrans trans) {
         session.close();
-        cacheTouch.close(trans);
     }
 
 }
diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java
index a40b28f..69d1d26 100644
--- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java
+++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java
@@ -171,6 +171,24 @@
         // data.day_time = Integer.parseInt(dayTimeFormat.format(now));
         return data;        
     }
+    
+    public void createBatch(StringBuilder sb, Data data) {
+    	sb.append("INSERT INTO history (");
+    	sb.append(helpers[FIELD_COMMAS]);
+    	sb.append(") VALUES(now(),");
+    	sb.append(data.yr_mon);
+    	sb.append(",'");
+    	sb.append(data.user);
+    	sb.append("','");
+    	sb.append(data.action);
+    	sb.append("','");
+    	sb.append(data.target);
+    	sb.append("','");
+    	sb.append(data.subject);
+    	sb.append("','");
+    	sb.append(data.memo);
+    	sb.append("',null);\n");
+    }
 
     public Result<List<Data>> readByYYYYMM(AuthzTrans trans, int yyyymm) {
         Result<ResultSet> rs = readByYRMN.exec(trans, "yr_mon", yyyymm);
diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java
index f55e1c1..4a30769 100644
--- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java
+++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java
@@ -953,27 +953,27 @@
             rv = cacheInfoDAO.touch(trans, NsDAO.TABLE, seg);
         }
         if (all || PermDAO.TABLE.equals(cname)) {
-            int seg[] = series(NsDAO.CACHE_SEG);
+            int seg[] = series(PermDAO.CACHE_SEG);
             for (int i: seg) {cacheClear(trans, PermDAO.TABLE,i);}
             rv = cacheInfoDAO.touch(trans, PermDAO.TABLE,seg);
         }
         if (all || RoleDAO.TABLE.equals(cname)) {
-            int seg[] = series(NsDAO.CACHE_SEG);
+            int seg[] = series(RoleDAO.CACHE_SEG);
             for (int i: seg) {cacheClear(trans, RoleDAO.TABLE,i);}
             rv = cacheInfoDAO.touch(trans, RoleDAO.TABLE,seg);
         }
         if (all || UserRoleDAO.TABLE.equals(cname)) {
-            int seg[] = series(NsDAO.CACHE_SEG);
+            int seg[] = series(UserRoleDAO.CACHE_SEG);
             for (int i: seg) {cacheClear(trans, UserRoleDAO.TABLE,i);}
             rv = cacheInfoDAO.touch(trans, UserRoleDAO.TABLE,seg);
         }
         if (all || CredDAO.TABLE.equals(cname)) {
-            int seg[] = series(NsDAO.CACHE_SEG);
+            int seg[] = series(CredDAO.CACHE_SEG);
             for (int i: seg) {cacheClear(trans, CredDAO.TABLE,i);}
             rv = cacheInfoDAO.touch(trans, CredDAO.TABLE,seg);
         }
         if (all || CertDAO.TABLE.equals(cname)) {
-            int seg[] = series(NsDAO.CACHE_SEG);
+            int seg[] = series(CertDAO.CACHE_SEG);
             for (int i: seg) {cacheClear(trans, CertDAO.TABLE,i);}
             rv = cacheInfoDAO.touch(trans, CertDAO.TABLE,seg);
         }
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
index fd252fe..69cfc7d 100644
--- a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
@@ -64,6 +64,18 @@
         public boolean isPerson();                // Whether a Person or a Machine (App)
         public Organization org();                 // Organization of Identity
 
+
+    	public static String mixedCase(String in) {
+    		StringBuilder sb = new StringBuilder();
+    		for(int i=0;i<in.length();++i) {
+    			if(i==0) {
+    				sb.append(Character.toUpperCase(in.charAt(i)));
+    			} else {
+    				sb.append(Character.toLowerCase(in.charAt(i)));
+    			}
+    		}
+    		return sb.toString();
+    	}
     }
 
 
@@ -83,9 +95,7 @@
 
     public void addSupportedRealm(String r);
 
-
-
-    String getDomain();
+    public String getDomain();
 
     /**
      * Get Identity information based on userID
@@ -95,6 +105,20 @@
      */
     public Identity getIdentity(AuthzTrans trans, String id) throws OrganizationException;
     
+    /**
+     * May AutoDelete
+     * 
+     * Deletion of an Identity that has been removed from an Organization can be dangerous.  Mistakes may have been made 
+     * in the Organization side, a Feed might be corrupted, an API might not be quite right.  
+     * 
+     * The implementation of this method can use a double check of some sort, such as comparsion of missing ID in Organization
+     * feed with a "Deleted ID" feed.  
+     * 
+     * The failure to be in Organization will still be reported, if returned "false", but if true, it is taken as an 
+     * ok to proceed with deletion. 
+     */
+	public boolean mayAutoDelete(AuthzTrans trans, String id);
+
 
     /**
      * Does the ID pass Organization Standards
@@ -516,15 +540,22 @@
                 }
 
             };
+            
+
         }
 
         @Override
         public String[] getPasswordRules() {
             return nullStringArray; 
         }
+        
+    	@Override
+    	public boolean mayAutoDelete(AuthzTrans trans, String id) {
+    		// provide a corresponding feed that indicates that an ID has been intentionally removed from identities.dat table.
+    		return false;
+    	}
 
     };
-
 }
 
 
diff --git a/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java b/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java
index 3c6176e..c7dd3d3 100644
--- a/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java
+++ b/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java
@@ -597,4 +597,10 @@
             return 0;
         }
     }
+
+	@Override
+	public boolean mayAutoDelete(AuthzTrans trans, String user) {
+		// provide a corresponding feed that indicates that an ID has been intentionally removed from identities.dat table.
+		return false;
+	}
 }
diff --git a/auth/docker/.gitignore b/auth/docker/.gitignore
index d3c3ab6..9e4bcf5 100644
--- a/auth/docker/.gitignore
+++ b/auth/docker/.gitignore
@@ -4,3 +4,5 @@
 /aaf.props
 /cass.props
 /policy*
+/*.yaml
+/*.orig
diff --git a/auth/docker/agent.sh b/auth/docker/agent.sh
index 88b8497..33db109 100644
--- a/auth/docker/agent.sh
+++ b/auth/docker/agent.sh
@@ -18,8 +18,6 @@
 #  limitations under the License.
 #  ============LICENSE_END====================================================
 #
-
-
 # Fill out "aaf.props" if not filled out already
 if [ ! -e aaf.props ]; then
   > ./aaf.props
@@ -27,29 +25,53 @@
  
 . ./aaf.props
 
-DOCKER=${DOCKER:=docker}
-CADI_VERSION=${CADI_VERSION:=2.1.9-SNAPSHOT}
+if [ -z "$ADMIN" ]; then
+  echo -n "Is the target [K]ubernetes or [D]ocker (K):"
+  read R
+  case $R in 
+    d|D) ADMIN=docker 
+         echo "ADMIN=docker" >> aaf.props
+         ;;
+    *) ADMIN=kubectl
+         echo "ADMIN=kubectl" >> aaf.props
+	;;
+  esac
+fi
+   
+if [ "$ADMIN" = "docker" ]; then
+   PROPS="VERSION DOCKER_REPOSITORY AAF_FQDN AAF_FQDN_IP DEPLOY_FQI APP_FQDN APP_FQI VOLUME DRIVER LATITUDE LONGITUDE"
+   DEF_AAF_FQDN=aaf-onap-test.osaaf.org
+else
+   PROPS="VERSION DOCKER_REPOSITORY NAMESPACE DEPLOY_FQI DEPLOY_PASSWORD AAF_FQDN APP_FQDN APP_FQI VOLUME PVC DRIVER LATITUDE LONGITUDE"
+   DEF_AAF_FQDN=aaf-locate
+fi
 
-for V in VERSION DOCKER_REPOSITORY AAF_FQDN AAF_FQDN_IP DEPLOY_FQI APP_FQDN APP_FQI VOLUME DRIVER LATITUDE LONGITUDE; do
+for V in $PROPS; do
    if [ "$(grep $V ./aaf.props)" = "" ]; then
       unset DEF
       case $V in
 	 DOCKER_REPOSITORY) 
-	        PROMPT="Docker Repo"
-	        DEF=""
-	        ;;
-         AAF_FQDN)   PROMPT="AAF's FQDN";;
-         DEPLOY_FQI) PROMPT="Deployer's FQI";;
+	             PROMPT="Docker Repo"; DEF="nexus3.onap.org:10003" ;;
+         AAF_FQDN)   PROMPT="AAF's FQDN" 
+                     if [ -z "$NAMESPACE" ]; then
+		       DEF=$DEF_AAF_FQDN
+		     else
+                       DEF=$DEF_AAF_FQDN.$NAMESPACE
+  		     fi
+                     ;;			
+         DEPLOY_FQI) PROMPT="Deployer's FQI"; DEF="deployer@people.osaaf.org" ;;
          AAF_FQDN_IP)
-		# Need AAF_FQDN's IP, because not might not be available in mini-container
-		PROMPT="AAF FQDN IP"
-  		DEF=$(host $AAF_FQDN | grep "has address" | tail -1 | cut -f 4 -d ' ')
-                ;;
+		     # Need AAF_FQDN's IP, because not might not be available in mini-container
+		     PROMPT="AAF FQDN IP"
+  		     DEF=$(host $AAF_FQDN | grep "has address" | tail -1 | cut -f 4 -d ' ')
+                     ;;
          APP_FQI)    PROMPT="App's FQI";; 
          APP_FQDN)   PROMPT="App's Root FQDN";; 
-         VOLUME)     PROMPT="APP's AAF Configuration Volume";;
+         VOLUME)     PROMPT="App's AAF Configuration Volume";DEF=${APP_FQDN/.*/}-config;;
          DRIVER)     PROMPT=$V;DEF=local;;
-	 VERSION)    PROMPT="CADI Version";DEF=$CADI_VERSION;;
+	 VERSION)    PROMPT="CADI Version";DEF=2.1.9-SNAPSHOT;;
+	 NAMESPACE)  PROMPT="Kubernetes Namespace";DEF=onap;;
+	 PVC)        PROMPT="Persistent Volume Claim";DEF=$VOLUME-pvc;;
          LATITUDE|LONGITUDE) PROMPT="$V of Node";;
          *)          PROMPT=$V;;
       esac
@@ -65,6 +87,7 @@
             exit
          else
             VAR=$DEF
+            declare $V="$VAR"
          fi
       fi
       echo "$V=$VAR" >> ./aaf.props
@@ -72,19 +95,20 @@
 done
 . ./aaf.props
 
-# Make sure Container Volume exists
-if [ "$($DOCKER volume ls | grep ${VOLUME})" = "" ]; then
-  echo -n "Creating Volume: " 
-  $DOCKER volume create -d ${DRIVER} ${VOLUME}
-fi
-
 if [ -n "$DOCKER_REPOSITORY" ]; then
   PREFIX="$DOCKER_REPOSITORY/"
 else
   PREFIX=""
 fi 
 
-$DOCKER run \
+if [[ "$ADMIN" =~ docker ]]; then
+  # Make sure Container Volume exists
+  if [ "$($ADMIN volume ls | grep ${VOLUME})" = "" ]; then
+    echo -n "Creating Volume: $VOLUME" 
+    $ADMIN volume create -d ${DRIVER} ${VOLUME}
+  fi
+
+  $ADMIN run \
     -it \
     --rm \
     -v "${VOLUME}:/opt/app/osaaf" \
@@ -99,3 +123,117 @@
     --name aaf_agent_$USER \
     "$PREFIX"onap/aaf/aaf_agent:$VERSION \
     /bin/bash "$@"
+else
+  NAMESPACE=${NAMESPACE:=onap}
+  YAML=${VOLUME}.yaml
+  # Make sure Container Volume exists
+  if [ -z "$($ADMIN -n $NAMESPACE get pv | grep ${VOLUME})" ]; then
+    if [ ! -r $YAML ]; then
+      SIZE=30M
+      echo "---" >> $YAML
+      echo "kind: PersistentVolume" >> $YAML
+      echo "apiVersion: v1" >> $YAML
+      echo "metadata:" >> $YAML
+      echo "  name: $VOLUME-pv" >> $YAML
+      echo "  namespace: $NAMESPACE" >> $YAML
+      echo "  labels:" >> $YAML
+      echo "    app: $VOLUME" >> $YAML
+      echo "    type: local" >> $YAML
+      echo "spec:" >> $YAML
+      echo "  capacity:" >> $YAML
+      echo "    storage: $SIZE" >> $YAML
+      echo "  accessModes:" >> $YAML
+      echo "    - ReadWriteOnce" >> $YAML
+      echo "  hostPath:" >> $YAML
+      echo "    path: \"/data/$VOLUME\"" >> $YAML
+      echo "  storageClassName: \"manual\"" >> $YAML
+      echo "---" >> $YAML
+      echo "kind: PersistentVolumeClaim" >> $YAML
+      echo "apiVersion: v1" >> $YAML
+      echo "metadata:" >> $YAML
+      echo "  name: $VOLUME-pvc" >> $YAML
+      echo "  namespace: $NAMESPACE" >> $YAML
+      echo "  labels:" >> $YAML
+      echo "    app: $VOLUME" >> $YAML
+      echo "    type: local" >> $YAML
+      echo "spec:" >> $YAML
+      echo "  selector:" >> $YAML
+      echo "    matchLabels:" >> $YAML
+      echo "      app: $VOLUME" >> $YAML
+      echo "  accessModes:" >> $YAML
+      echo "    - ReadWriteOnce" >> $YAML
+      echo "  resources:" >> $YAML
+      echo "    requests:" >> $YAML
+      echo "      storage: $SIZE" >> $YAML
+      echo "  storageClassName: "manual"" >> $YAML
+    fi
+    $ADMIN -n $NAMESPACE create -f $YAML
+  fi
+  POD=aaf-agent-$USER
+  $ADMIN run -n $NAMESPACE $POD \
+    -i --rm  \
+    --restart=Never \
+    --image="$PREFIX"onap/aaf/aaf_agent:$VERSION \
+    --overrides='
+{
+  "apiVersion": "v1",
+  "kind": "Pod",
+  "metadata": {
+    "name": "'$POD'"
+  },
+  "spec": {
+    "volumes": [{
+      "name": "'$VOLUME'",
+      "persistentVolumeClaim": {
+         "claimName": "'$VOLUME'-pvc"
+      }
+    }],
+    "containers": [
+      {
+        "name": "aaf-agent-'$USER'",
+        "imagePullPolicy": "IfNotPresent",
+        "image": "'$PREFIX'onap/aaf/aaf_agent:'$VERSION'",
+        "args": [
+	   "/bin/bash",
+           "'$@'"
+        ],
+        "stdin": true,
+        "stdinOnce": true,
+        "tty": true,
+        "volumeMounts": [
+          {
+            "mountPath": "/opt/app/osaaf",
+            "name": "'$VOLUME'"
+          }
+        ],
+       "env": [
+          {
+            "name": "AAF_FQDN",
+            "value": "'$AAF_FQDN'"
+          },{
+            "name": "DEPLOY_FQI",
+            "value": "'$DEPLOY_FQI'"
+          },{
+            "name": "DEPLOY_PASSWORD",
+            "value": "'$DEPLOY_PASSWORD'"
+          },{
+            "name": "APP_FQI",
+            "value": "'$APP_FQI'"
+          },{
+            "name": "APP_FQDN",
+            "value": "'$APP_FQDN'"
+          },{
+            "name": "LATITUDE",
+            "value": "'$LATITUDE'"
+          },{
+            "name": "LONGITUDE",
+            "value": "'$LONGITUDE'"
+          }
+        ]
+      }
+    ]
+  }
+}'
+     
+
+fi
diff --git a/auth/sample/.gitignore b/auth/sample/.gitignore
index 62fd177..80014ba 100644
--- a/auth/sample/.gitignore
+++ b/auth/sample/.gitignore
@@ -1 +1,2 @@
 theme
+.DS_Store